'VRSAVE': 256}
+def swap_order(x, nbytes):
+ x = x.to_bytes(nbytes, byteorder='little')
+ x = int.from_bytes(x, byteorder='big', signed=False)
+ return x
+
+
def create_args(reglist, extra=None):
args = OrderedSet()
for reg in reglist:
self.mem = {}
self.bytes_per_word = bytes_per_word
self.word_log2 = math.ceil(math.log2(bytes_per_word))
+ print ("Sim-Mem", initial_mem, self.bytes_per_word, self.word_log2)
if not initial_mem:
return
- print ("Sim-Mem", initial_mem, self.bytes_per_word)
for addr, (val, width) in initial_mem.items():
- self.st(addr, val, width)
+ #val = swap_order(val, width)
+ self.st(addr, val, width, swap=False)
def _get_shifter_mask(self, wid, remainder):
shifter = ((self.bytes_per_word - wid) - remainder) * \
8 # bits per byte
# XXX https://bugs.libre-soc.org/show_bug.cgi?id=377
# BE/LE mode?
- # shifter = remainder * 8
+ shifter = remainder * 8
mask = (1 << (wid * 8)) - 1
print ("width,rem,shift,mask", wid, remainder, hex(shifter), hex(mask))
return shifter, mask
# TODO: Implement ld/st of lesser width
- def ld(self, address, width=8):
+ def ld(self, address, width=8, swap=True):
print("ld from addr 0x{:x} width {:d}".format(address, width))
remainder = address & (self.bytes_per_word - 1)
address = address >> self.word_log2
print ("masking", hex(val), hex(mask<<shifter), shifter)
val = val & (mask << shifter)
val >>= shifter
+ if swap:
+ val = swap_order(val, width)
print("Read 0x{:x} from addr 0x{:x}".format(val, address))
return val
- def st(self, addr, v, width=8):
+ def st(self, addr, v, width=8, swap=True):
staddr = addr
remainder = addr & (self.bytes_per_word - 1)
addr = addr >> self.word_log2
print("Writing 0x{:x} to ST 0x{:x} memaddr 0x{:x}/{:x}".format(v,
- staddr, addr, remainder))
+ staddr, addr, remainder, swap))
assert remainder & (width - 1) == 0, "Unaligned access unsupported!"
+ if swap:
+ v = swap_order(v, width)
if width != self.bytes_per_word:
if addr in self.mem:
val = self.mem[addr]
breakstring = f' {breakpoint}'
return self.gdb.write('-break-delete' + breakstring)
+ def set_byte(self, addr, v):
+ print ("qemu set byte", hex(addr), hex(v))
+ faddr = '&{int}0x%x' % addr
+ res = self.gdb.write('-data-write-memory-bytes %s "%02x"' % (faddr, v))
+ print ("confirm", self.get_mem(addr, 1))
+
def get_mem(self, addr, nbytes):
- res = self.gdb.write("-data-read-memory %d u 8 1 %d" % (addr, nbytes))
- print ("get_mem", res)
+ res = self.gdb.write("-data-read-memory %d u 1 1 %d" % (addr, 8*nbytes))
+ #print ("get_mem", res)
for x in res:
if(x["type"]=="result"):
- return x['payload']['memory'][0]['data']
+ l = list(map(int, x['payload']['memory'][0]['data']))
+ res = []
+ for j in range(0, len(l), 8):
+ b = 0
+ for i, v in enumerate(l[j:j+8]):
+ b += v << (i*8)
+ res.append(b)
+ return res
return None
def get_registers(self):
self.qemu_popen.stdin.close()
-def run_program(program):
+def run_program(program, initial_mem=None):
q = QemuController(program.binfile.name)
q.connect()
# Run to the start of the program
q.break_address(0x20000000)
+ if initial_mem:
+ for addr, (v, wid) in initial_mem.items():
+ for i in range(wid):
+ q.set_byte(addr+i, (v>>i*8) & 0xff)
q.gdb_continue()
# set the CR to 0, matching the simulator
q.gdb_eval('$cr=0')
class DecoderTestCase(FHDLTestCase):
- def run_tst(self, generator):
+ def run_tst(self, generator, initial_mem=None):
m = Module()
comb = m.d.comb
instruction = Signal(32)
m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
- simulator = ISA(pdecode2, [0] * 32, {}, 0, {}, 0)
+ simulator = ISA(pdecode2, [0] * 32, {}, 0, initial_mem, 0)
comb += pdecode2.dec.raw_opcode_in.eq(instruction)
comb += pdecode2.dec.bigendian.eq(0)
gen = generator.generate_instructions()
return simulator
- def test_0_cmp(self):
+ def _tst0_cmp(self):
lst = ["addi 6, 0, 0x10",
"addi 7, 0, 0x05",
"subf. 1, 6, 7",
with Program(lst) as program:
self.run_tst_program(program, [1])
- def test_example(self):
- lst = ["addi 1, 0, 0x1234",
- "addi 2, 0, 0x5678",
+ def _tstexample(self):
+ lst = ["addi 1, 0, 0x5678",
+ "addi 2, 0, 0x1234",
"add 3, 1, 2",
"and 4, 1, 2"]
with Program(lst) as program:
self.run_tst_program(program, [1, 2, 3, 4])
- def test_ldst(self):
- lst = ["addi 1, 0, 0x1234",
- "addi 2, 0, 0x5678",
+ def _tstldst(self):
+ lst = ["addi 1, 0, 0x5678",
+ "addi 2, 0, 0x1234",
"stw 1, 0(2)",
- "lwz 3, 0(2)"]
+ "lwz 3, 0(2)"
+ ]
+ initial_mem = {0x1230: (0x5432123412345678, 8),
+ 0x1238: (0xabcdef0187654321, 8),
+ }
with Program(lst) as program:
- self.run_tst_program(program, [1, 2, 3])
+ self.run_tst_program(program,
+ [1, 2, 3],
+ initial_mem)
- def test_ldst_extended(self):
- lst = ["addi 1, 0, 0x1234",
- "addi 2, 0, 0x5678",
+ def _tstldst_extended(self):
+ lst = ["addi 1, 0, 0x5678",
+ "addi 2, 0, 0x1234",
"addi 4, 0, 0x40",
"stw 1, 0x40(2)",
"lwzx 3, 4, 2"]
with Program(lst) as program:
self.run_tst_program(program, [1, 2, 3])
- def test_0_ldst_widths(self):
+ def _tst0_ldst_widths(self):
lst = ["addis 1, 0, 0xdead",
"ori 1, 1, 0xbeef",
"addi 2, 0, 0x1000",
with Program(lst) as program:
self.run_tst_program(program, [1, 2, 3, 4, 5])
- def test_sub(self):
+ def _tstsub(self):
lst = ["addi 1, 0, 0x1234",
"addi 2, 0, 0x5678",
"subf 3, 1, 2",
with Program(lst) as program:
self.run_tst_program(program, [1, 2, 3, 4, 5])
- def test_add_with_carry(self):
+ def _tstadd_with_carry(self):
lst = ["addi 1, 0, 5",
"neg 1, 1",
"addi 2, 0, 7",
with Program(lst) as program:
self.run_tst_program(program, [1, 2, 3])
- def test_addis(self):
+ def _tstaddis(self):
lst = ["addi 1, 0, 0x0FFF",
"addis 1, 1, 0x0F"
]
self.run_tst_program(program, [1])
@unittest.skip("broken")
- def test_mulli(self):
+ def _tstmulli(self):
lst = ["addi 1, 0, 3",
"mulli 1, 1, 2"
]
with Program(lst) as program:
self.run_tst_program(program, [1])
- def run_tst_program(self, prog, reglist):
+ def test_3_load_store(self):
+ lst = ["addi 1, 0, 0x1004",
+ "addi 2, 0, 0x1002",
+ "addi 3, 0, 0x15eb",
+ "sth 4, 0(2)",
+ "lhz 4, 0(2)"]
+ initial_regs = [0] * 32
+ initial_regs[1] = 0x0004
+ initial_regs[2] = 0x0002
+ initial_regs[3] = 0x15eb
+ initial_mem = {0x1000: (0x5432123412345678, 8),
+ 0x1008: (0xabcdef0187654321, 8),
+ 0x1020: (0x1828384822324252, 8),
+ }
+ with Program(lst) as program:
+ self.run_tst_program(program, [1,2,3,4], initial_mem)
+
+ def run_tst_program(self, prog, reglist, initial_mem=None):
import sys
- simulator = self.run_tst(prog)
+ simulator = self.run_tst(prog, initial_mem=initial_mem)
prog.reset()
- with run_program(prog) as q:
+ with run_program(prog, initial_mem) as q:
self.qemu_register_compare(simulator, q, reglist)
self.qemu_mem_compare(simulator, q, reglist)
print(simulator.gpr.dump())
- def qemu_mem_compare(self, sim, qemu, regs):
- addr = 0x1000
- qmemdump = qemu.get_mem(addr, 16)
- for i in range(len(qmemdump)):
- s = hex(int(qmemdump[i]))
- print ("qemu mem %06x %s" % (addr+i*8, s))
+ def qemu_mem_compare(self, sim, qemu, check=True):
+ if False: # disable convenient large interesting debugging memory dump
+ addr = 0x0
+ qmemdump = qemu.get_mem(addr, 2048)
+ for i in range(len(qmemdump)):
+ s = hex(int(qmemdump[i]))
+ print ("qemu mem %06x %s" % (addr+i*8, s))
+ for k, v in sim.mem.mem.items():
+ qmemdump = qemu.get_mem(k*8, 8)
+ s = hex(int(qmemdump[0]))[2:]
+ print ("qemu mem %06x %16s" % (k*8, s))
for k, v in sim.mem.mem.items():
- print ("sim %06x %016x" % (k, v))
+ print ("sim mem %06x %016x" % (k*8, v))
+ if not check:
+ return
for k, v in sim.mem.mem.items():
- self.assertEqual(int(qmemdump[(k-0x200)//8]), v) # magic constant??
+ qmemdump = qemu.get_mem(k*8, 1)
+ self.assertEqual(int(qmemdump[0]), v)
def qemu_register_compare(self, sim, qemu, regs):
qpc, qxer, qcr = qemu.get_pc(), qemu.get_xer(), qemu.get_cr()