add initial lwarx unit test and pseudocode
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 3 Dec 2023 20:30:27 +0000 (20:30 +0000)
committerJacob Lifshay <programmerjake@gmail.com>
Mon, 4 Dec 2023 06:32:30 +0000 (22:32 -0800)
openpower/isa/fixedsync.mdwn
src/openpower/decoder/isa/caller.py
src/openpower/decoder/pseudo/parser.py

index 5667c07fc4443065e5635e667e75b6c4e064ee47..44a6b02271cc8a2ecc7a285e88fa98244b1a3c9a 100644 (file)
@@ -55,8 +55,11 @@ X-Form
 
 Pseudo-code:
 
-    # TODO
-    undefined(0)
+    EA <- (RA|0) + (RB)
+    RESERVE <- 1
+    RESERVE_LENGTH <- 4
+    RESERVE_ADDR <- EA # real_addr(EA)
+    RT <- [0]*32 || MEM(EA, 4)
 
 Special Registers Altered:
 
@@ -115,8 +118,35 @@ X-Form
 
 Pseudo-code:
 
-    # TODO
-    undefined(0)
+    EA <- (RA|0) + (RB)
+    undefined_case <- 0
+    store_performed <- 0
+    if RESERVE then
+      if (RESERVE_LENGTH = 4 &
+         RESERVE_ADDR = real_addr(EA)) then
+           MEM(EA, 1) <- (RS)[32:63]
+           undefined_case <- 0
+           store_performed <- 1
+      else
+           z <- REAL_PAGE_SIZE # smallest implementation's real page size 
+           if RESERVE_ADDR / z = real_addr(EA) / z then
+              undefined_case <- 1
+           else
+             undefined_case <- 0
+             store_performed <- 0
+    else
+      undefined_case <- 0
+      store_performed <- 0
+    if undefined_case then
+      u1 <- undefined(0b1)
+      if u1 then
+         MEM(EA, 1) <- (RS)[32:63]
+      u2 <- undefined(0b0)
+      CR0 <- 0b00 || u2 || XER[SO]
+    else
+      CR0 <- 0b00 || store_performed || XER[SO]
+    RESERVE <- 0
+
 
 Special Registers Altered:
 
index 46876cf94eaa3345745aecec8e07b77d1e9feca8..6a452f0a8cdda36ccc3a0653190d614018170de3 100644 (file)
@@ -1293,7 +1293,8 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
                  insnlog=None,
                  use_mmap_mem=False,
                  use_syscall_emu=False,
-                 emulating_mmap=False):
+                 emulating_mmap=False,
+                 real_page_size=None):
         if use_syscall_emu:
             self.syscall = SyscallEmulator(isacaller=self)
             if not use_mmap_mem:
@@ -1446,7 +1447,21 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
                                'undefined': undefined,
                                'mode_is_64bit': True,
                                'SO': XER_bits['SO'],
-                               'XLEN': 64  # elwidth overrides
+                               'XLEN': 64,  # elwidth overrides
+                               })
+
+        # for LR/SC
+        if real_page_size is None:
+            real_page_size = 4096
+        self.real_page_size = real_page_size
+        self.reserve_addr = SelectableInt(0, self.XLEN)
+        self.reserve = SelectableInt(0, 1)
+        self.reserve_length = SelectableInt(0, 4)
+
+        self.namespace.update({'RESERVE': self.RESERVE,
+                               'RESERVE_ADDR': self.RESERVE_ADDR,
+                               'RESERVE_LENGTH': self.RESERVE_LENGTH,
+                               'REAL_PAGE_SIZE': self.REAL_PAGE_SIZE,
                                })
 
         for name in BFP_FLAG_NAMES:
@@ -1474,6 +1489,22 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
     def XLEN(self):
         return self.namespace["XLEN"]
 
+    @property
+    def RESERVE(self):
+        return self.reserve
+
+    @property
+    def RESERVE_LENGTH(self):
+        return self.reserve_length
+
+    @property
+    def RESERVE_ADDR(self):
+        return self.reserve_addr
+
+    @property
+    def REAL_PAGE_SIZE(self):
+        return self.real_page_size
+
     @property
     def FPSCR(self):
         return self.fpscr
@@ -1580,6 +1611,9 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
         self.namespace['OV'] = self.spr['XER'][XER_bits['OV']].value
         self.namespace['OV32'] = self.spr['XER'][XER_bits['OV32']].value
         self.namespace['XLEN'] = xlen
+        self.namespace['RESERVE'] = self.reserve
+        self.namespace['RESERVE_ADDR'] = self.reserve_addr
+        self.namespace['RESERVE_LENGTH'] = self.reserve_length
 
         # add some SVSTATE convenience variables
         vl = self.svstate.vl
@@ -2339,6 +2373,8 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
         for name in input_names:
             if name == "overflow":
                 inputs[name] = SelectableInt(0, 1)
+            elif name.startswith("RESERVE"):
+                inputs[name] = getattr(self, name)
             elif name == "FPSCR":
                 inputs[name] = self.FPSCR
             elif name in ("CA", "CA32", "OV", "OV32"):
@@ -2759,6 +2795,10 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
         if isinstance(output, int):
             output = SelectableInt(output, EFFECTIVELY_UNLIMITED)
         # write FPSCR
+        if name.startswith("RESERVE"):
+            log("write %s 0x%x" % (name, output.value))
+            getattr(self, name).eq(output)
+            return
         if name in ['FPSCR', ]:
             log("write FPSCR 0x%x" % (output.value))
             self.FPSCR.eq(output)
index b1086440a1d8f17f3944cf10af9657d49fc8d5ab..c69bcf544e061aeab2321b649482d34c4afd806c 100644 (file)
@@ -680,6 +680,8 @@ class PowerParser:
         name = p[1]
         if name in self.available_op_fields:
             self.op_fields.add(name)
+        if name.startswith("RESERVE"):
+            self.write_regs.add(name)
         if name in ['overflow', 'CR0']:
             self.write_regs.add(name)
         if self.include_ca_in_write: