From a5604f244fb56c4abc9f4240eaa355f12d46f088 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 3 Dec 2023 20:30:27 +0000 Subject: [PATCH] add initial lwarx unit test and pseudocode --- openpower/isa/fixedsync.mdwn | 38 +++++++++++++++++++--- src/openpower/decoder/isa/caller.py | 44 ++++++++++++++++++++++++-- src/openpower/decoder/pseudo/parser.py | 2 ++ 3 files changed, 78 insertions(+), 6 deletions(-) diff --git a/openpower/isa/fixedsync.mdwn b/openpower/isa/fixedsync.mdwn index 5667c07f..44a6b022 100644 --- a/openpower/isa/fixedsync.mdwn +++ b/openpower/isa/fixedsync.mdwn @@ -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: diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index f6ee4e38..1b042381 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -1302,7 +1302,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: @@ -1455,7 +1456,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: @@ -1483,6 +1498,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 @@ -1589,6 +1620,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 @@ -2358,6 +2392,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"): @@ -2791,6 +2827,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) diff --git a/src/openpower/decoder/pseudo/parser.py b/src/openpower/decoder/pseudo/parser.py index 2d113f6e..ffa52e56 100644 --- a/src/openpower/decoder/pseudo/parser.py +++ b/src/openpower/decoder/pseudo/parser.py @@ -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: -- 2.30.2