From: Luke Kenneth Casson Leighton Date: Tue, 11 Oct 2022 12:31:58 +0000 (+0100) Subject: add /pi to sv/trans/svp64.py and power_insns.py X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=417aefc276386f1a8adf62d23b9ded54207fc662;p=openpower-isa.git add /pi to sv/trans/svp64.py and power_insns.py --- diff --git a/src/openpower/decoder/power_insn.py b/src/openpower/decoder/power_insn.py index c87e7e2a..e086a832 100644 --- a/src/openpower/decoder/power_insn.py +++ b/src/openpower/decoder/power_insn.py @@ -1615,9 +1615,16 @@ class LDSTImmSimpleRM(ElsBaseRM, ZZBaseRM, LDSTImmBaseRM): sz: BaseRM.mode[3] -class LDSTImmRsvdRM(LDSTImmBaseRM): - """ld/st immediate: rsvd""" - pass +class LDSTImmPostRM(LDSTImmBaseRM): + """ld/st immediate: postinc mode (and load-fault)""" + pi: BaseRM.mode[3] # Post-Increment Mode + lf: BaseRM.mode[4] # Fault-First Mode (not *Data-Dependent* Fail-First) + + def specifiers(self, record): + if self.pi: + yield "pi" + if self.lf: + yield "lf" class LDSTImmFFRc1RM(FFPRRc1BaseRM, LDSTImmBaseRM): @@ -1669,7 +1676,7 @@ class LDSTImmPRRc0RM(FFPRRc0BaseRM, ElsBaseRM, LDSTImmBaseRM): class LDSTImmRM(LDSTImmBaseRM): simple: LDSTImmSimpleRM - rsvd: LDSTImmRsvdRM + post: LDSTImmPostRM ffrc1: LDSTImmFFRc1RM ffrc0: LDSTImmFFRc0RM sat: LDSTImmSatRM @@ -1935,7 +1942,7 @@ class RM(BaseRM): # mode except reserved in place of mr table = ( (0b000000, 0b111000, "simple"), # simple (no Rc) - (0b001000, 0b111000, "rsvd"), # rsvd (no Rc) + (0b001000, 0b111000, "post"), # post (no Rc) (0b010001, 0b110001, "ffrc1"), # ffirst, Rc=1 (0b010000, 0b110001, "ffrc0"), # ffirst, Rc=0 (0b100000, 0b110000, "sat"), # saturation (no Rc) diff --git a/src/openpower/sv/trans/svp64.py b/src/openpower/sv/trans/svp64.py index 6c87f6d8..a798085e 100644 --- a/src/openpower/sv/trans/svp64.py +++ b/src/openpower/sv/trans/svp64.py @@ -1056,6 +1056,7 @@ class SVP64Asm: # see https://libre-soc.org/openpower/sv/ldst/ is_ldst = rm['mode'] in ['LDST_IDX', 'LDST_IMM'] is_ldst_idx = rm['mode'] == 'LDST_IDX' + is_ldst_imm = rm['mode'] == 'LDST_IMM' is_ld = v30b_op.startswith("l") and is_ldst is_st = v30b_op.startswith("s") and is_ldst @@ -1088,6 +1089,7 @@ class SVP64Asm: predresult = False failfirst = False ldst_elstride = 0 + ldst_postinc = 0 sea = False vli = False @@ -1127,6 +1129,12 @@ class SVP64Asm: # just src width elif encmode.startswith("sw="): srcwid = decode_elwidth(encmode[3:]) + # post-increment + elif encmode == 'pi': + ldst_postinc = 1 + # in indexed mode, set sv_mode=0b00 + assert is_ldst_imm is True + sv_mode = 0b00 # element-strided LD/ST elif encmode == 'els': ldst_elstride = 1 @@ -1220,6 +1228,10 @@ class SVP64Asm: else: raise AssertionError("unknown encmode %s" % encmode) + # post-inc only available on ld-with-update + if ldst_postinc: + assert "u" in opcode, "/pi only available on ld/st-update" + # sanity check if dz/zz used in branch-mode if is_bc and dst_zero: raise AssertionError("dz/zz not supported in branch, use 'sz'") @@ -1290,7 +1302,7 @@ class SVP64Asm: | 0-1 | 2 | 3 4 | description | | --- | --- |---------|--------------------------- | | 00 | 0 | zz els | normal mode | - | 00 | 1 | / / | reserved | + | 00 | 1 | pi lf | post-inc, LD-fault-first | | 01 | inv | CR-bit | Rc=1: ffirst CR sel | | 01 | inv | els RC1 | Rc=0: ffirst z/nonz | | 10 | N | zz els | sat mode: N=0/1 u/s | @@ -1342,6 +1354,12 @@ class SVP64Asm: pass sv_mode = 0b00 + ###################################### + # ldst-immediate "post" (and "load-fault-first" modes) + elif sv_mode == 0b00 and ldst_postinc == 1: # (or ldst_ld_ffirst) + mode |= (0b1 << SVP64MODE.LDI_POST) # sets bit 2 + mode |= (ldst_postinc << SVP64MODE.LDI_PI) # sets post-inc + ###################################### # "mapreduce" modes elif sv_mode == 0b00: diff --git a/src/openpower/sv/trans/test_pysvp64dis.py b/src/openpower/sv/trans/test_pysvp64dis.py index 808b3b50..54cbf638 100644 --- a/src/openpower/sv/trans/test_pysvp64dis.py +++ b/src/openpower/sv/trans/test_pysvp64dis.py @@ -384,6 +384,12 @@ class SVSTATETestCase(unittest.TestCase): ] self._do_tst(expected) + def test_29_postinc(self): + expected = [ + "sv.ldu/pi 5,8(2)", + ] + self._do_tst(expected) + if __name__ == "__main__": unittest.main()