From 0cb15bc1756f7b1a80a18f4ef4072cf9c47b9ac5 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Fri, 30 Dec 2022 13:59:47 +0000 Subject: [PATCH] corrections to boundary-wrapped store, and add misaligned store that is storing to a single line (not wrapping) --- src/openpower/decoder/isa/mem.py | 28 +++++++++++++-------------- src/openpower/decoder/isa/test_mem.py | 9 ++++++++- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/openpower/decoder/isa/mem.py b/src/openpower/decoder/isa/mem.py index 8b3e0563..41d5b0b4 100644 --- a/src/openpower/decoder/isa/mem.py +++ b/src/openpower/decoder/isa/mem.py @@ -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) diff --git a/src/openpower/decoder/isa/test_mem.py b/src/openpower/decoder/isa/test_mem.py index 9a5423af..e02de2f7 100644 --- a/src/openpower/decoder/isa/test_mem.py +++ b/src/openpower/decoder/isa/test_mem.py @@ -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) -- 2.30.2