12068SN/A// -*- mode:c++ -*-
22068SN/A
32068SN/A// Copyright (c) 2003-2005 The Regents of The University of Michigan
42068SN/A// All rights reserved.
52068SN/A//
62068SN/A// Redistribution and use in source and binary forms, with or without
72068SN/A// modification, are permitted provided that the following conditions are
82068SN/A// met: redistributions of source code must retain the above copyright
92068SN/A// notice, this list of conditions and the following disclaimer;
102068SN/A// redistributions in binary form must reproduce the above copyright
112068SN/A// notice, this list of conditions and the following disclaimer in the
122068SN/A// documentation and/or other materials provided with the distribution;
132068SN/A// neither the name of the copyright holders nor the names of its
142068SN/A// contributors may be used to endorse or promote products derived from
152068SN/A// this software without specific prior written permission.
162068SN/A//
172068SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182068SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192068SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202068SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212068SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222068SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232068SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242068SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252068SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262068SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272068SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665Ssaidi@eecs.umich.edu//
292665Ssaidi@eecs.umich.edu// Authors: Steve Reinhardt
302068SN/A
312649Ssaidi@eecs.umich.edu////////////////////////////////////////////////////////////////////
322649Ssaidi@eecs.umich.edu//
332649Ssaidi@eecs.umich.edu// Utility functions for execute methods
342649Ssaidi@eecs.umich.edu//
352649Ssaidi@eecs.umich.edu
362068SN/Aoutput exec {{
372068SN/A
382068SN/A    /// Return opa + opb, summing carry into third arg.
392068SN/A    inline uint64_t
402068SN/A    addc(uint64_t opa, uint64_t opb, int &carry)
412068SN/A    {
422068SN/A        uint64_t res = opa + opb;
432068SN/A        if (res < opa || res < opb)
442068SN/A            ++carry;
452068SN/A        return res;
462068SN/A    }
472068SN/A
482068SN/A    /// Multiply two 64-bit values (opa * opb), returning the 128-bit
492068SN/A    /// product in res_hi and res_lo.
502068SN/A    inline void
512068SN/A    mul128(uint64_t opa, uint64_t opb, uint64_t &res_hi, uint64_t &res_lo)
522068SN/A    {
532068SN/A        // do a 64x64 --> 128 multiply using four 32x32 --> 64 multiplies
542068SN/A        uint64_t opa_hi = opa<63:32>;
552068SN/A        uint64_t opa_lo = opa<31:0>;
562068SN/A        uint64_t opb_hi = opb<63:32>;
572068SN/A        uint64_t opb_lo = opb<31:0>;
582068SN/A
592068SN/A        res_lo = opa_lo * opb_lo;
602068SN/A
612068SN/A        // The middle partial products logically belong in bit
622068SN/A        // positions 95 to 32.  Thus the lower 32 bits of each product
632068SN/A        // sum into the upper 32 bits of the low result, while the
642068SN/A        // upper 32 sum into the low 32 bits of the upper result.
652068SN/A        uint64_t partial1 = opa_hi * opb_lo;
662068SN/A        uint64_t partial2 = opa_lo * opb_hi;
672068SN/A
682068SN/A        uint64_t partial1_lo = partial1<31:0> << 32;
692068SN/A        uint64_t partial1_hi = partial1<63:32>;
702068SN/A        uint64_t partial2_lo = partial2<31:0> << 32;
712068SN/A        uint64_t partial2_hi = partial2<63:32>;
722068SN/A
732068SN/A        // Add partial1_lo and partial2_lo to res_lo, keeping track
742068SN/A        // of any carries out
752068SN/A        int carry_out = 0;
762068SN/A        res_lo = addc(partial1_lo, res_lo, carry_out);
772068SN/A        res_lo = addc(partial2_lo, res_lo, carry_out);
782068SN/A
792068SN/A        // Now calculate the high 64 bits...
802068SN/A        res_hi = (opa_hi * opb_hi) + partial1_hi + partial2_hi + carry_out;
812068SN/A    }
822068SN/A
832068SN/A    /// Map 8-bit S-floating exponent to 11-bit T-floating exponent.
842068SN/A    /// See Table 2-2 of Alpha AHB.
852068SN/A    inline int
862068SN/A    map_s(int old_exp)
872068SN/A    {
882068SN/A        int hibit = old_exp<7:>;
892068SN/A        int lobits = old_exp<6:0>;
902068SN/A
912068SN/A        if (hibit == 1) {
922068SN/A            return (lobits == 0x7f) ? 0x7ff : (0x400 | lobits);
932068SN/A        }
942068SN/A        else {
952068SN/A            return (lobits == 0) ? 0 : (0x380 | lobits);
962068SN/A        }
972068SN/A    }
982068SN/A
992068SN/A    /// Convert a 32-bit S-floating value to the equivalent 64-bit
1002068SN/A    /// representation to be stored in an FP reg.
1012068SN/A    inline uint64_t
1022068SN/A    s_to_t(uint32_t s_val)
1032068SN/A    {
1042068SN/A        uint64_t tmp = s_val;
1052068SN/A        return (tmp<31:> << 63 // sign bit
1062068SN/A                | (uint64_t)map_s(tmp<30:23>) << 52 // exponent
1072068SN/A                | tmp<22:0> << 29); // fraction
1082068SN/A    }
1092068SN/A
1102068SN/A    /// Convert a 64-bit T-floating value to the equivalent 32-bit
1112068SN/A    /// S-floating representation to be stored in memory.
1122068SN/A    inline int32_t
1132068SN/A    t_to_s(uint64_t t_val)
1142068SN/A    {
1152068SN/A        return (t_val<63:62> << 30   // sign bit & hi exp bit
1162068SN/A                | t_val<58:29>);     // rest of exp & fraction
1172068SN/A    }
1182068SN/A}};
1192068SN/A
120