X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fopenpower%2Fdecoder%2Fhelpers.py;h=87b71d99780046a7643d9cd828779eb53e737bf4;hb=950976b93f5000beb38f9118ca691459f2a774cf;hp=faef2d9a3481dc23bad4ebf732469ac45a4bcfaa;hpb=5b30b31ad4a0268e391dd62a94b72a4dcf6216dc;p=openpower-isa.git diff --git a/src/openpower/decoder/helpers.py b/src/openpower/decoder/helpers.py index faef2d9a..87b71d99 100644 --- a/src/openpower/decoder/helpers.py +++ b/src/openpower/decoder/helpers.py @@ -9,6 +9,7 @@ from openpower.decoder.selectable_int import selectgtu as gtu from openpower.decoder.selectable_int import check_extsign from openpower.util import log +import math trunc_div = floordiv trunc_rem = mod @@ -77,6 +78,14 @@ def rotl(value, bits, wordlen): return ((value << bits) | (value >> (wordlen-bits))) & mask +def SHL64(value, bits, wordlen=64): + if isinstance(bits, SelectableInt): + bits = bits.value + mask = (1 << wordlen) - 1 + bits = bits & (wordlen - 1) + return SelectableInt((value << bits) & mask, 64) + + def ROTL64(value, bits): return rotl(value, bits, 64) @@ -152,56 +161,6 @@ def undefined(v): """ return v -def DOUBLE(WORD): - """convert incoming WORD to double. v3.0B p140 section 4.6.2 - """ - # result, FRT, start off all zeros - log ("WORD", WORD) - FRT = SelectableInt(0, 64) - z1 = SelectableInt(0, 1) - z29 = SelectableInt(0, 29) - e = WORD[1:9] - m = WORD[9:32] - s = WORD[0] - log ("word s e m", s, e, m) - - # Normalized Operand - if e.value > 0 and e.value < 255: - log ("normalised") - FRT[0:2] = WORD[0:2] - FRT[2] = ~WORD[1] - FRT[3] = ~WORD[1] - FRT[4] = ~WORD[1] - FRT[5:64] = selectconcat(WORD[2:32], z29) - - # Denormalized Operand - if e.value == 0 and m.value != 0: - log ("denormalised") - sign = WORD[0] - exp = -126 - frac = selectconcat(z1, WORD[9:32], z29) - # normalize the operand - while frac[0].value == 0: - frac[0:53] = selectconcat(frac[1:53], z1) - exp = exp - 1 - FRT[0] = sign - FRT[1:12] = exp + 1023 - FRT[12:64] = frac[1:53] - - # Zero / Infinity / NaN - if e.value == 255 or WORD[1:32].value == 0: - log ("z/inf/nan") - FRT[0:2] = WORD[0:2] - FRT[2] = WORD[1] - FRT[3] = WORD[1] - FRT[4] = WORD[1] - FRT[5:64] = selectconcat(WORD[2:32], z29) - - log ("Double s e m", FRT[0].value, FRT[1:12].value-1023, - FRT[12:64].value) - - return FRT - def SINGLE(FRS): """convert incoming FRS into 32-bit word. v3.0B p144 section 4.6.3 @@ -252,6 +211,26 @@ def fp64toselectable(frt): return SelectableInt(val, 64) +def FPSIN32(FRB): + from openpower.decoder.isafunctions.double2single import DOUBLE2SINGLE + #FRB = DOUBLE(SINGLE(FRB)) + result = math.sin(float(FRB)) + cvt = fp64toselectable(result) + cvt = DOUBLE2SINGLE(cvt) + log ("FPSIN32", FRB, float(FRB), "=", result, cvt) + return cvt + + +def FPCOS32(FRB): + from openpower.decoder.isafunctions.double2single import DOUBLE2SINGLE + #FRB = DOUBLE(SINGLE(FRB)) + result = math.cos(float(FRB)) + cvt = fp64toselectable(result) + cvt = DOUBLE2SINGLE(cvt) + log ("FPCOS32", FRB, float(FRB), "=", result, cvt) + return cvt + + def FPADD32(FRA, FRB): from openpower.decoder.isafunctions.double2single import DOUBLE2SINGLE #return FPADD64(FRA, FRB) @@ -260,7 +239,7 @@ def FPADD32(FRA, FRB): result = float(FRA) + float(FRB) cvt = fp64toselectable(result) cvt = DOUBLE2SINGLE(cvt) - log ("FPADD32", FRA, FRB, result, cvt) + log ("FPADD32", FRA, FRB, float(FRA), "+", float(FRB), "=", result, cvt) return cvt @@ -272,49 +251,67 @@ def FPSUB32(FRA, FRB): result = float(FRA) - float(FRB) cvt = fp64toselectable(result) cvt = DOUBLE2SINGLE(cvt) - log ("FPSUB32", FRA, FRB, result, cvt) + log ("FPSUB32", FRA, FRB, float(FRA), "-", float(FRB), "=", result, cvt) return cvt -def FPMUL32(FRA, FRB): +def signinv(res, sign): + if sign == 1: + return res + if sign == 0: + return 0.0 + if sign == -1: + return -res + + +def FPMUL32(FRA, FRB, sign=1): from openpower.decoder.isafunctions.double2single import DOUBLE2SINGLE + from openpower.decoder.isafunctions.double2single import DOUBLE #return FPMUL64(FRA, FRB) - #FRA = DOUBLE(SINGLE(FRA)) - #FRB = DOUBLE(SINGLE(FRB)) - result = float(FRA) * float(FRB) - log ("FPMUL32", FRA, FRB, float(FRA), float(FRB), result) + FRA = DOUBLE(SINGLE(FRA)) + FRB = DOUBLE(SINGLE(FRB)) + result = signinv(float(FRA) * float(FRB), sign) + log ("FPMUL32", FRA, FRB, float(FRA), float(FRB), result, sign) cvt = fp64toselectable(result) cvt = DOUBLE2SINGLE(cvt) log (" cvt", cvt) return cvt -def FPMULADD32(FRA, FRB, FRC, sign): +def FPMULADD32(FRA, FRC, FRB, mulsign, addsign): from openpower.decoder.isafunctions.double2single import DOUBLE2SINGLE #return FPMUL64(FRA, FRB) #FRA = DOUBLE(SINGLE(FRA)) #FRB = DOUBLE(SINGLE(FRB)) - if sign == 1: - result = float(FRA) * float(FRB) + float(FRC) - elif sign == -1: - result = float(FRA) * float(FRB) - float(FRC) - elif sign == 0: - result = float(FRA) * float(FRB) - log ("FPMULADD32", FRA, FRB, FRC, - float(FRA), float(FRB), float(FRC), - result) + if addsign == 1: + if mulsign == 1: + result = float(FRA) * float(FRC) + float(FRB) # fmadds + elif mulsign == -1: + result = -(float(FRA) * float(FRC) - float(FRB)) # fnmsubs + elif addsign == -1: + if mulsign == 1: + result = float(FRA) * float(FRC) - float(FRB) # fmsubs + elif mulsign == -1: + result = -(float(FRA) * float(FRC) + float(FRB)) # fnmadds + elif addsign == 0: + result = 0.0 + log ("FPMULADD32 FRA FRC FRB", FRA, FRC, FRB) + log (" FRA", float(FRA)) + log (" FRC", float(FRC)) + log (" FRB", float(FRB)) + log (" (FRA*FRC)+FRB=", mulsign, addsign, result) cvt = fp64toselectable(result) cvt = DOUBLE2SINGLE(cvt) log (" cvt", cvt) return cvt -def FPDIV32(FRA, FRB): +def FPDIV32(FRA, FRB, sign=1): from openpower.decoder.isafunctions.double2single import DOUBLE2SINGLE #return FPDIV64(FRA, FRB) #FRA = DOUBLE(SINGLE(FRA)) #FRB = DOUBLE(SINGLE(FRB)) - result = float(FRA) / float(FRB) + result = signinv(float(FRA) / float(FRB), sign) cvt = fp64toselectable(result) cvt = DOUBLE2SINGLE(cvt) log ("FPDIV32", FRA, FRB, result, cvt) @@ -335,20 +332,33 @@ def FPSUB64(FRA, FRB): return cvt -def FPMUL64(FRA, FRB): - result = float(FRA) * float(FRB) +def FPMUL64(FRA, FRB, sign=1): + result = signinv(float(FRA) * float(FRB), sign) cvt = fp64toselectable(result) - log ("FPMUL64", FRA, FRB, result, cvt) + log ("FPMUL64", FRA, FRB, result, cvt, sign) return cvt -def FPDIV64(FRA, FRB): - result = float(FRA) / float(FRB) +def FPDIV64(FRA, FRB, sign=1): + result = signinv(float(FRA) / float(FRB), sign) cvt = fp64toselectable(result) - log ("FPDIV64", FRA, FRB, result, cvt) + log ("FPDIV64", FRA, FRB, result, cvt, sign) return cvt + +def bitrev(val, VL): + """Returns the integer whose value is the reverse of the lowest + 'width' bits of the integer 'val' + """ + result = 0 + width = VL.bit_length()-1 + for _ in range(width): + result = (result << 1) | (val & 1) + val >>= 1 + return result + + # For these tests I tried to find power instructions that would let me # isolate each of these helper operations. So for instance, when I was # testing the MASK() function, I chose rlwinm and rldicl because if I