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