corrections to boundary-wrapped store, and add misaligned store that is
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 30 Dec 2022 13:59:47 +0000 (13:59 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 2 Jun 2023 18:51:16 +0000 (19:51 +0100)
storing to a single line (not wrapping)

src/openpower/decoder/isa/mem.py
src/openpower/decoder/isa/test_mem.py

index 8b3e05631de6a2cc0368d2259be625e50bbbbbf7..41d5b0b4df11592f609dfc07c9da57234e8b5626 100644 (file)
@@ -115,7 +115,7 @@ class Mem:
         addr = addr >> self.word_log2
         log("Writing 0x%x to ST 0x%x memaddr 0x%x/%x swap %s" % \
             (v, staddr, addr, remainder, str(swap)))
-        if remainder & (width - 1) != 0:
+        if not self.misaligned_ok and remainder & (width - 1) != 0:
             exc = MemException("unaligned",
                   "Unaligned access: remainder %x width %d" % \
                   (remainder, width))
@@ -136,31 +136,29 @@ class Mem:
             self.mem[addr] = v
         log("mem @ 0x%x: 0x%x" % (staddr, self.mem[addr]))
 
-    def st(self, addr, v, width=8, swap=True):
-        staddr = addr
-        self.last_st_addr = addr # record last store
+    def st(self, st_addr, v, width=8, swap=True):
+        self.last_st_addr = st_addr # record last store
         # misaligned not allowed: pass straight to Mem._st
         if not self.misaligned_ok:
-            return self._st(addr, v, width, swap)
-        remainder = addr & (self.bytes_per_word - 1)
-        addr = addr >> self.word_log2
+            return self._st(st_addr, v, width, swap)
+        remainder = st_addr & (self.bytes_per_word - 1)
         if swap:
             v = swap_order(v, width)
         # not misaligned: pass through to Mem._st but we've swapped already
         misaligned = remainder & (width - 1)
-        if misaligned == 0:
-            return self._st(addr, v, width, swap=False)
+        if misaligned == 0 or (remainder + width <= self.bytes_per_word):
+            return self._st(st_addr, v, width, swap=False)
         shifter, mask = self._get_shifter_mask(width, remainder)
         # split into two halves. lower first
         maxmask = (1 << (self.bytes_per_word)*8) - 1
         val1 = ((v << shifter) & maxmask) >> shifter
-        self._st(addr+misaligned, val1,
-                 width=width-misaligned, swap=False)
-        # now upper
+        self._st(st_addr, val1, width=width-misaligned, swap=False)
+        # now upper.
         val2 = v >> ((width-misaligned)*8)
-        print ("v, val2", hex(v), hex(val2))
-        self._st(addr+self.bytes_per_word, val2,
-                 width=width-misaligned, swap=False)
+        addr2 = (st_addr >> self.word_log2) << self.word_log2
+        addr2 += self.bytes_per_word
+        print ("v, val2", hex(v), hex(val2), "ad", addr2)
+        self._st(addr2, val2, width=width-misaligned, swap=False)
 
     def __call__(self, addr, sz):
         val = self.ld(addr.value, sz, swap=False)
index 9a5423af655f1bf091fc894bb6443b49343580f7..e02de2f78e2a1489c1efa192a209922b00ed4268 100644 (file)
@@ -9,13 +9,20 @@ from openpower.util import log
 
 class TestMem(unittest.TestCase):
 
-    def test_mem_align_st(self):
+    def tst_mem_align_st(self):
         m = Mem(row_bytes=8, initial_mem={})
         m.st(4, 0x12345678, width=4, swap=False)
         d = m.dump()
         log ("dict", d)
         self.assertEqual(d, [(0, 0x1234567800000000)])
 
+    def test_mem_misalign_st(self):
+        m = Mem(row_bytes=8, initial_mem={}, misaligned_ok=True)
+        m.st(3, 0x12345678, width=4, swap=False)
+        d = m.dump()
+        log ("dict", d)
+        self.assertEqual(d, [(0, 0x0012345678000000)])
+
     def test_mem_misalign_st_rollover(self):
         m = Mem(row_bytes=8, initial_mem={}, misaligned_ok=True)
         m.st(6, 0x912345678, width=8, swap=False)