X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsoc%2Fdecoder%2Fhelpers.py;h=b54bcfd86233f50a5467347458547c8e6fd7cec7;hb=HEAD;hp=d920b920f89614c07809aca3194e326f15811f98;hpb=a56985dfb4fb3197700417f480fd214aa7d1e84e;p=soc.git diff --git a/src/soc/decoder/helpers.py b/src/soc/decoder/helpers.py index d920b920..b54bcfd8 100644 --- a/src/soc/decoder/helpers.py +++ b/src/soc/decoder/helpers.py @@ -1,12 +1,22 @@ import unittest -from soc.decoder.selectable_int import SelectableInt -from nmutil.divmod import trunc_div, trunc_rem +from openpower.decoder.selectable_int import SelectableInt, onebit +from nmutil.divmod import trunc_divs, trunc_rems +from operator import floordiv, mod +from openpower.decoder.selectable_int import selectltu as ltu +from openpower.decoder.selectable_int import selectgtu as gtu +from openpower.decoder.selectable_int import check_extsign + +trunc_div = floordiv +trunc_rem = mod +DIVS = trunc_divs +MODS = trunc_rems """ Links: * https://bugs.libre-soc.org/show_bug.cgi?id=324 - add trunc_div and trunc_rem """ + def exts(value, bits): sign = 1 << (bits - 1) return (value & (sign - 1)) - (value & sign) @@ -18,6 +28,7 @@ def EXTS(value): assert isinstance(value, SelectableInt) return SelectableInt(exts(value.value, value.bits) & ((1 << 256)-1), 256) + def EXTS64(value): """ extends sign bit out from current MSB to 64 bits """ @@ -25,11 +36,32 @@ def EXTS64(value): return SelectableInt(exts(value.value, value.bits) & ((1 << 64)-1), 64) +def EXTS128(value): + """ extends sign bit out from current MSB to 128 bits + """ + assert isinstance(value, SelectableInt) + return SelectableInt(exts(value.value, value.bits) & ((1 << 128)-1), 128) + + +# signed version of MUL +def MULS(a, b): + if isinstance(b, int): + b = SelectableInt(b, self.bits) + b = check_extsign(a, b) + a_s = a.value & (1 << (a.bits-1)) != 0 + b_s = b.value & (1 << (b.bits-1)) != 0 + result = abs(a) * abs(b) + print("MULS", result, a_s, b_s) + if a_s == b_s: + return result + return -result + + # XXX should this explicitly extend from 32 to 64? def EXTZ64(value): if isinstance(value, SelectableInt): value = value.value - return SelectableInt(value & ((1<<32)-1), 64) + return SelectableInt(value & ((1 << 32)-1), 64) def rotl(value, bits, wordlen): @@ -69,33 +101,51 @@ def MASK(x, y): mask_b = (~((1 << y) - 1)) & ((1 << 64) - 1) return mask_a ^ mask_b + def ne(a, b): - return SelectableInt((a != b), bits=1) + return onebit(a != b) + def eq(a, b): - return SelectableInt((a == b), bits=1) + return onebit(a == b) + def gt(a, b): - return SelectableInt((a > b), bits=1) + return onebit(a > b) + def ge(a, b): - return SelectableInt((a >= b), bits=1) + return onebit(a >= b) + def lt(a, b): - return SelectableInt((a < b), bits=1) + return onebit(a < b) + def le(a, b): - return SelectableInt((a <= b), bits=1) + return onebit(a <= b) + def length(a): return len(a) + +def undefined(v): + """ function that, for Power spec purposes, returns undefined bits of + the same shape as the input bits. however, for purposes of matching + POWER9's behavior returns the input bits unchanged. this effectively + "marks" (tags) locations in the v3.0B spec that need to be submitted + for clarification. + """ + return v + # 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 # set the shift equal to 0 and passed in a value of all ones, the # result I got would be exactly the same as the output of MASK() + class HelperTests(unittest.TestCase): def test_MASK(self): # Verified using rlwinm, rldicl, rldicr in qemu @@ -168,5 +218,5 @@ class HelperTests(unittest.TestCase): if __name__ == '__main__': - print (SelectableInt.__bases__) + print(SelectableInt.__bases__) unittest.main()