-Subproject commit 15fa1944f4d59d10efb53978e24a68d4731a5f43
+Subproject commit dab541a4a8cba23a486cbdb9e0fc9219091da3f5
-from nmutil.iocontrol import RecordObject
-from nmigen import Signal
-from soc.sv.svstate import SVSTATERec
+# moved to openpower-isa
+# https://git.libre-soc.org/?p=openpower-isa.git;a=summary
+# wildcard imports here ONLY to support migration
-
-class CoreState(RecordObject):
- """contains "Core State Information" which says exactly where things are
-
- example: eint says to PowerDecoder that it should fire an exception
- rather than let the current decoded instruction proceed. likewise
- if dec goes negative. MSR contains LE/BE and Priv state. PC contains
- the Program Counter, and SVSTATE is the Sub-Program-Counter.
- """
- def __init__(self, name):
- super().__init__(name=name)
- self.pc = Signal(64) # Program Counter (CIA, NIA)
- self.msr = Signal(64) # Machine Status Register (MSR)
- self.eint = Signal() # External Interrupt
- self.dec = Signal(64) # DEC SPR (again, for interrupt generation)
- self.svstate = SVSTATERec(name) # Simple-V SVSTATE
+from openpower.state import *
-# sigh create little-ended versions of bitfield flags
-from nmigen import Cat
+# moved to openpower-isa
+# https://git.libre-soc.org/?p=openpower-isa.git;a=summary
+# wildcard imports here ONLY to support migration
-
-def botchify(bekls, lekls, msb=63):
- for attr in dir(bekls):
- if attr[0] == '_':
- continue
- setattr(lekls, attr, msb-getattr(bekls, attr))
-
-
-# Can't think of a better place to put these functions.
-# Return an arbitrary subfield of a larger field.
-def field_slice(msb0_start, msb0_end, field_width=64):
- """field_slice
-
- Answers with a subfield slice of the signal r ("register"),
- where the start and end bits use IBM "MSB 0" conventions.
-
- see: https://en.wikipedia.org/wiki/Bit_numbering#MSB_0_bit_numbering
-
- * assertion: msb0_start < msb0_end.
- * The range specified is inclusive on both ends.
- * field_width specifies the total number of bits (note: not bits-1)
- """
- if msb0_start >= msb0_end:
- raise ValueError(
- "start ({}) must be less than end ({})".format(msb0_start, msb0_end)
- )
- # sigh. MSB0 (IBM numbering) is inverted. converting to python
- # we *swap names* so as not to get confused by having "end, start"
- lsb0_end = (field_width-1) - msb0_start
- lsb0_start = (field_width-1) - msb0_end
-
- return slice(lsb0_start, lsb0_end + 1)
-
-
-def field(r, msb0_start, msb0_end=None, field_width=64):
- """Answers with a subfield of the signal r ("register"), where
- the start and end bits use IBM conventions. start < end, if
- end is provided. The range specified is inclusive on both ends.
-
- Answers with a subfield of the signal r ("register"),
- where the start and end bits use IBM "MSB 0" conventions.
- If end is not provided, a single bit subfield is returned.
-
- see: https://en.wikipedia.org/wiki/Bit_numbering#MSB_0_bit_numbering
-
- * assertion: msb0_start < msb0_end.
- * The range specified is inclusive on both ends.
- * field_width specifies the total number of bits (note: not bits-1)
-
- Example usage:
-
- comb += field(insn, 0, 6, field_width=32).eq(17)
- # NOTE: NEVER DIRECTLY ACCESS OPCODE FIELDS IN INSTRUCTIONS.
- # This example is purely for illustrative purposes only.
- # Use self.fields.FormXYZ.etcetc instead.
-
- comb += field(msr, MSRb.TEs, MSRb.TEe).eq(0)
-
- Proof by substitution:
-
- field(insn, 0, 6, field_width=32).eq(17)
- == insn[field_slice(0, 6, field_width=32)].eq(17)
- == insn[slice((31-6), (31-0)+1)].eq(17)
- == insn[slice(25, 32)].eq(17)
- == insn[25:32].eq(17)
-
- field(msr, MSRb.TEs, MSRb.TEe).eq(0)
- == field(msr, 53, 54).eq(0)
- == msr[field_slice(53, 54)].eq(0)
- == msr[slice((63-54), (63-53)+1)].eq(0) # note cross-over!
- == msr[slice(9, 11)].eq(0)
- == msr[9:11].eq(0)
- """
- if msb0_end is None:
- return r[(field_width - 1) - msb0_start]
- else:
- return r[field_slice(msb0_start, msb0_end, field_width)]
-
-
-# Listed in V3.0B Book III Chap 4.2.1
-# MSR bit numbers, *bigendian* order (PowerISA format)
-# use this in the simulator
-class MSRb:
- SF = 0 # Sixty-Four bit mode
- HV = 3 # Hypervisor state
- UND = 5 # Undefined behavior state (see Bk 2, Sect. 3.2.1)
- TSs = 29 # Transactional State (subfield)
- TSe = 30 # Transactional State (subfield)
- TM = 31 # Transactional Memory Available
- VEC = 38 # Vector Available
- VSX = 40 # VSX Available
- S = 41 # Secure state
- EE = 48 # External interrupt Enable
- PR = 49 # PRoblem state
- FP = 50 # FP available
- ME = 51 # Machine Check int enable
- FE0 = 52 # Floating-Point Exception Mode 0
- TEs = 53 # Trace Enable (subfield)
- TEe = 54 # Trace Enable (subfield)
- FE1 = 55 # Floating-Point Exception Mode 1
- IR = 58 # Instruction Relocation
- DR = 59 # Data Relocation
- PMM = 60 # Performance Monitor Mark
- RI = 62 # Recoverable Interrupt
- LE = 63 # Little Endian
-
-# use this inside the HDL (where everything is little-endian)
-class MSR:
- pass
-
-botchify(MSRb, MSR)
-
-# Listed in V3.0B Book III 7.5.9 "Program Interrupt"
-
-# note that these correspond to trap_input_record.traptype bits 0,1,2,3,4
-# (TODO: add more?)
-# IMPORTANT: when adding extra bits here it is CRITICALLY IMPORTANT
-# to expand traptype to cope with the increased range
-
-# use this in the simulator
-class PIb:
- INVALID = 33 # 1 for an invalid mem err
- PERMERR = 35 # 1 for an permanent mem err
- TM_BAD_THING = 42 # 1 for a TM Bad Thing type interrupt
- FP = 43 # 1 if FP exception
- ILLEG = 44 # 1 if illegal instruction (not doing hypervisor)
- PRIV = 45 # 1 if privileged interrupt
- TRAP = 46 # 1 if exception is "trap" type
- ADR = 47 # 0 if SRR0 = address of instruction causing exception
-
-# and use this in the HDL
-class PI:
- pass
-
-botchify(PIb, PI)
-
-# see traptype (and trap main_stage.py)
-# IMPORTANT: when adding extra bits here it is CRITICALLY IMPORTANT
-# to expand traptype to cope with the increased range
-
-class TT:
- FP = 1<<0
- PRIV = 1<<1
- TRAP = 1<<2
- ADDR = 1<<3
- EINT = 1<<4 # external interrupt
- DEC = 1<<5 # decrement counter
- MEMEXC = 1<<6 # LD/ST exception
- ILLEG = 1<<7 # currently the max
- # TODO: support for TM_BAD_THING (not included yet in trap main_stage.py)
- size = 8 # MUST update this to contain the full number of Trap Types
-
-
-# EXTRA3 3-bit subfield (spec)
-class SPECb:
- VEC = 0 # 1 for vector, 0 for scalar
- MSB = 1 # augmented register number, MSB
- LSB = 2 # augmented register number, LSB
-
-
-SPEC_SIZE = 3
-SPEC_AUG_SIZE = 2 # augmented subfield size (MSB+LSB above)
-class SPEC:
- pass
-botchify(SPECb, SPEC, SPEC_SIZE-1)
-
-
-# EXTRA field, with EXTRA2 subfield encoding
-class EXTRA2b:
- IDX0_VEC = 0
- IDX0_MSB = 1
- IDX1_VEC = 2
- IDX1_MSB = 3
- IDX2_VEC = 4
- IDX2_MSB = 5
- IDX3_VEC = 6
- IDX3_MSB = 7
- RESERVED = 8
-
-
-EXTRA2_SIZE = 9
-class EXTRA2:
- pass
-botchify(EXTRA2b, EXTRA2, EXTRA2_SIZE-1)
-
-
-# EXTRA field, with EXTRA3 subfield encoding
-class EXTRA3:
- IDX0 = [0, 1, 2]
- IDX1 = [3, 4, 5]
- IDX2 = [6, 7, 8]
- MASK = [6, 7, 8]
-
-
-EXTRA3_SIZE = 9
-
-
-# SVP64 ReMapped Field (from v3.1 EXT001 Prefix)
-class SVP64P:
- OPC = range(0, 6)
- SVP64_7_9 = [7, 9]
- RM = [6, 8] + list(range(10, 32))
-
-# 24 bits in RM
-SVP64P_SIZE = 24
-
-
-# CR SVP64 offsets
-class SVP64CROffs:
- CR0 = 0 # TODO: increase when CRs are expanded to 128
- CR1 = 1 # TODO: increase when CRs are expanded to 128
- CRPred = 4 # TODO: increase when CRs are expanded to 128
-
-
-class SVP64MODEb:
- # mode bits
- MOD2_MSB = 0
- MOD2_LSB = 1
- # when predicate not set: 0=ignore/skip 1=zero
- DZ = 3 # for destination
- SZ = 4 # for source
- # reduce mode
- REDUCE = 2 # 0=normal predication 1=reduce mode
- SVM = 3 # subvector reduce mode 0=independent 1=horizontal
- CRM = 4 # CR mode on reduce (Rc=1) 0=some 1=all
- # saturation mode
- N = 2 # saturation signed mode 0=signed 1=unsigned
- # ffirst and predicate result modes
- INV = 2 # invert CR sense 0=set 1=unset
- CR_MSB = 3 # CR bit to update (with Rc=1)
- CR_LSB = 4
- RC1 = 4 # update CR as if Rc=1 (when Rc=0)
- # LD immediate els (element-stride) locations, depending on mode
- ELS_NORMAL = 2
- ELS_FFIRST_PRED = 3
- ELS_SAT = 4
- # BO bits
- BO_MSB = 2
- BO_LSB = 4
-
-
-SVP64MODE_SIZE = 5
-
-
-class SVP64MODE:
- pass
-
-
-botchify(SVP64MODEb, SVP64MODE, SVP64MODE_SIZE-1)
-
-# add subfields to use with nmutil.sel
-SVP64MODE.MOD2 = [0, 1]
-SVP64MODE.CR = [3, 4]
-
-
-# CR sub-fields
-class CRb:
- LT = 0
- GT = 1
- EQ = 2
- SO = 3
-
-
-CR_SIZE = 4
-
-
-class CR:
- pass
-
-
-botchify(CRb, CR, CR_SIZE-1)
+from openpower.consts import *
-from nmigen import Module, Signal
-from nmigen.back.pysim import Simulator, Delay, Settle
-from nmutil.formaltest import FHDLTestCase
-import unittest
-from soc.decoder.isa.caller import ISACaller
-from soc.decoder.power_decoder import (create_pdecode)
-from soc.decoder.power_decoder2 import (PowerDecode2)
-from soc.simulator.program import Program
-from soc.decoder.isa.caller import ISACaller, inject
-from soc.decoder.selectable_int import SelectableInt
-from soc.decoder.orderedset import OrderedSet
-from soc.decoder.isa.all import ISA
+# moved to openpower-isa
+# https://git.libre-soc.org/?p=openpower-isa.git;a=summary
+# wildcard imports here ONLY to support migration
-
-class Register:
- def __init__(self, num):
- self.num = num
-
-def run_tst(generator, initial_regs, initial_sprs=None, svstate=0, mmu=False,
- initial_cr=0,mem=None):
- if initial_sprs is None:
- initial_sprs = {}
- m = Module()
- comb = m.d.comb
- instruction = Signal(32)
-
- pdecode = create_pdecode()
-
- gen = list(generator.generate_instructions())
- insncode = generator.assembly.splitlines()
- instructions = list(zip(gen, insncode))
-
- m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
- simulator = ISA(pdecode2, initial_regs, initial_sprs, initial_cr,
- initial_insns=gen, respect_pc=True,
- initial_svstate=svstate,
- initial_mem=mem,
- disassembly=insncode,
- bigendian=0,
- mmu=mmu)
- comb += pdecode2.dec.raw_opcode_in.eq(instruction)
- sim = Simulator(m)
-
-
- def process():
-
- yield pdecode2.dec.bigendian.eq(0) # little / big?
- pc = simulator.pc.CIA.value
- index = pc//4
- while index < len(instructions):
- print("instr pc", pc)
- try:
- yield from simulator.setup_one()
- except KeyError: # indicates instruction not in imem: stop
- break
- yield Settle()
-
- ins, code = instructions[index]
- print(" 0x{:X}".format(ins & 0xffffffff))
- opname = code.split(' ')[0]
- print(code, opname)
-
- # ask the decoder to decode this binary data (endian'd)
- yield from simulator.execute_one()
- pc = simulator.pc.CIA.value
- index = pc//4
-
- sim.add_process(process)
- with sim.write_vcd("simulator.vcd", "simulator.gtkw",
- traces=[]):
- sim.run()
- return simulator
-
-
-class DecoderTestCase(FHDLTestCase):
-
- def test_add(self):
- lst = ["add 1, 3, 2"]
- initial_regs = [0] * 32
- initial_regs[3] = 0x1234
- initial_regs[2] = 0x4321
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs)
- self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64))
-
- def test_addi(self):
- lst = ["addi 3, 0, 0x1234",
- "addi 2, 0, 0x4321",
- "add 1, 3, 2"]
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program)
- print(sim.gpr(1))
- self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64))
-
- def test_load_store(self):
- lst = ["addi 1, 0, 0x0010",
- "addi 2, 0, 0x1234",
- "stw 2, 0(1)",
- "lwz 3, 0(1)"]
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program)
- print(sim.gpr(1))
- self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
-
- @unittest.skip("broken")
- def test_addpcis(self):
- lst = ["addpcis 1, 0x1",
- "addpcis 2, 0x1",
- "addpcis 3, 0x1"]
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program)
- self.assertEqual(sim.gpr(1), SelectableInt(0x10004, 64))
- self.assertEqual(sim.gpr(2), SelectableInt(0x10008, 64))
- self.assertEqual(sim.gpr(3), SelectableInt(0x1000c, 64))
-
- def test_branch(self):
- lst = ["ba 0xc", # branch to line 4
- "addi 1, 0, 0x1234", # Should never execute
- "ba 0x1000", # exit the program
- "addi 2, 0, 0x1234", # line 4
- "ba 0x8"] # branch to line 3
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program)
- self.assertEqual(sim.pc.CIA, SelectableInt(0x1000, 64))
- self.assertEqual(sim.gpr(1), SelectableInt(0x0, 64))
- self.assertEqual(sim.gpr(2), SelectableInt(0x1234, 64))
-
- def test_branch_link(self):
- lst = ["bl 0xc",
- "addi 2, 1, 0x1234",
- "ba 0x1000",
- "addi 1, 0, 0x1234",
- "bclr 20, 0, 0"]
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program)
- self.assertEqual(sim.spr['LR'], SelectableInt(0x4, 64))
-
- def test_branch_ctr(self):
- lst = ["addi 1, 0, 0x10", # target of jump
- "mtspr 9, 1", # mtctr 1
- "bcctr 20, 0, 0", # bctr
- "addi 2, 0, 0x1", # should never execute
- "addi 1, 0, 0x1234"] # target of ctr
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program)
- self.assertEqual(sim.spr['CTR'], SelectableInt(0x10, 64))
- self.assertEqual(sim.gpr(1), SelectableInt(0x1234, 64))
- self.assertEqual(sim.gpr(2), SelectableInt(0, 64))
-
- def test_branch_cond(self):
- for i in [0, 10]:
- lst = [f"addi 1, 0, {i}", # set r1 to i
- "cmpi cr0, 1, 1, 10", # compare r1 with 10 and store to cr0
- "bc 12, 2, 0x8", # beq 0x8 -
- # branch if r1 equals 10 to the nop below
- "addi 2, 0, 0x1234", # if r1 == 10 this shouldn't execute
- "or 0, 0, 0"] # branch target
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program)
- if i == 10:
- self.assertEqual(sim.gpr(2), SelectableInt(0, 64))
- else:
- self.assertEqual(sim.gpr(2), SelectableInt(0x1234, 64))
-
- def test_branch_loop(self):
- lst = ["addi 1, 0, 0",
- "addi 1, 0, 0",
- "addi 1, 1, 1",
- "add 2, 2, 1",
- "cmpi cr0, 1, 1, 10",
- "bc 12, 0, -0xc"]
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program)
- # Verified with qemu
- self.assertEqual(sim.gpr(2), SelectableInt(0x37, 64))
-
- def test_branch_loop_ctr(self):
- lst = ["addi 1, 0, 0",
- "addi 2, 0, 7",
- "mtspr 9, 2", # set ctr to 7
- "addi 1, 1, 5",
- "bc 16, 0, -0x4"] # bdnz to the addi above
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program)
- # Verified with qemu
- self.assertEqual(sim.gpr(1), SelectableInt(0x23, 64))
-
-
-
- def test_add_compare(self):
- lst = ["addis 1, 0, 0xffff",
- "addis 2, 0, 0xffff",
- "add. 1, 1, 2",
- "mfcr 3"]
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program)
- # Verified with QEMU
- self.assertEqual(sim.gpr(3), SelectableInt(0x80000000, 64))
-
- def test_cmp(self):
- lst = ["addis 1, 0, 0xffff",
- "addis 2, 0, 0xffff",
- "cmp cr2, 0, 1, 2",
- "mfcr 3"]
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program)
- self.assertEqual(sim.gpr(3), SelectableInt(0x200000, 64))
-
- def test_slw(self):
- lst = ["slw 1, 3, 2"]
- initial_regs = [0] * 32
- initial_regs[3] = 0xdeadbeefcafebabe
- initial_regs[2] = 5
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs)
- self.assertEqual(sim.gpr(1), SelectableInt(0x5fd757c0, 64))
-
- def test_srw(self):
- lst = ["srw 1, 3, 2"]
- initial_regs = [0] * 32
- initial_regs[3] = 0xdeadbeefcafebabe
- initial_regs[2] = 5
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs)
- self.assertEqual(sim.gpr(1), SelectableInt(0x657f5d5, 64))
-
- def test_rlwinm(self):
- lst = ["rlwinm 3, 1, 5, 20, 6"]
- initial_regs = [0] * 32
- initial_regs[1] = -1
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs)
- self.assertEqual(sim.gpr(3), SelectableInt(0xfffffffffe000fff, 64))
-
- def test_rlwimi(self):
- lst = ["rlwimi 3, 1, 5, 20, 6"]
- initial_regs = [0] * 32
- initial_regs[1] = 0xffffffffdeadbeef
- initial_regs[3] = 0x12345678
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs)
- self.assertEqual(sim.gpr(3), SelectableInt(0xd5b7ddfbd4345dfb, 64))
-
- def test_rldic(self):
- lst = ["rldic 3, 1, 5, 20"]
- initial_regs = [0] * 32
- initial_regs[1] = 0xdeadbeefcafec0de
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs)
- self.assertEqual(sim.gpr(3), SelectableInt(0xdf95fd81bc0, 64))
-
- def test_prty(self):
- lst = ["prtyw 2, 1"]
- initial_regs = [0] * 32
- initial_regs[1] = 0xdeadbeeecaffc0de
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs)
- self.assertEqual(sim.gpr(2), SelectableInt(0x100000001, 64))
-
- def test_popcnt(self):
- lst = ["popcntb 2, 1",
- "popcntw 3, 1",
- "popcntd 4, 1"
- ]
- initial_regs = [0] * 32
- initial_regs[1] = 0xdeadbeefcafec0de
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs)
- self.assertEqual(sim.gpr(2),
- SelectableInt(0x605060704070206, 64))
- self.assertEqual(sim.gpr(3),
- SelectableInt(0x1800000013, 64))
- self.assertEqual(sim.gpr(4),
- SelectableInt(0x2b, 64))
-
- def test_cntlz(self):
- lst = ["cntlzd 2, 1",
- "cntlzw 4, 3"]
- initial_regs = [0] * 32
- initial_regs[1] = 0x0000beeecaffc0de
- initial_regs[3] = 0x0000000000ffc0de
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs)
- self.assertEqual(sim.gpr(2), SelectableInt(16, 64))
- self.assertEqual(sim.gpr(4), SelectableInt(8, 64))
-
- def test_cmpeqb(self):
- lst = ["cmpeqb cr0, 2, 1",
- "cmpeqb cr1, 3, 1"]
- initial_regs = [0] * 32
- initial_regs[1] = 0x0102030405060708
- initial_regs[2] = 0x04
- initial_regs[3] = 0x10
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs)
- self.assertEqual(sim.crl[0].get_range().value,
- SelectableInt(4, 4))
- self.assertEqual(sim.crl[1].get_range().value,
- SelectableInt(0, 4))
-
-
-
- def test_mtcrf(self):
- for i in range(4):
- # 0x76540000 gives expected (3+4) (2+4) (1+4) (0+4) for
- # i=0, 1, 2, 3
- # The positions of the CR fields have been verified using
- # QEMU and 'cmp crx, a, b' instructions
- lst = ["addis 1, 0, 0x7654",
- "mtcrf %d, 1" % (1 << (7-i)),
- ]
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program)
- print("cr", sim.cr)
- expected = (7-i)
- # check CR[0]/1/2/3 as well
- print("cr%d", sim.crl[i])
- self.assertTrue(SelectableInt(expected, 4) == sim.crl[i])
- # check CR itself
- self.assertEqual(sim.cr, SelectableInt(expected << ((7-i)*4), 32))
-
- def run_tst_program(self, prog, initial_regs=[0] * 32):
- simulator = run_tst(prog, initial_regs)
- simulator.gpr.dump()
- return simulator
-
-
-if __name__ == "__main__":
- unittest.main()
+from openpower.decoder.isa.test_caller import *
+++ /dev/null
-from nmigen import Module, Signal
-#from nmigen.back.pysim import Simulator, Delay, Settle
-from nmutil.formaltest import FHDLTestCase
-import unittest
-from soc.decoder.isa.caller import ISACaller
-from soc.decoder.power_decoder import (create_pdecode)
-from soc.decoder.power_decoder2 import (PowerDecode2)
-from soc.simulator.program import Program
-from soc.decoder.isa.caller import ISACaller, inject, RADIX
-from soc.decoder.selectable_int import SelectableInt
-from soc.decoder.orderedset import OrderedSet
-from soc.decoder.isa.all import ISA
-from soc.decoder.isa.test_caller import run_tst
-
-from copy import deepcopy
-
-testmem = {
-
- 0x10000: # PARTITION_TABLE_2 (not implemented yet)
- # PATB_GR=1 PRTB=0x1000 PRTS=0xb
- 0x800000000100000b,
-
- 0x30000: # RADIX_ROOT_PTE
- # V = 1 L = 0 NLB = 0x400 NLS = 9
- 0x8000000000040009,
- 0x40000: # RADIX_SECOND_LEVEL
- # V = 1 L = 1 SW = 0 RPN = 0
- # R = 1 C = 1 ATT = 0 EAA 0x7
- 0xc000000000000187,
-
- 0x30800: # RADIX_ROOT_PTE + 8
- # V = 1 L = 0 NLB = 0x408 NLS = 9
- 0x8000000000040809,
- 0x40800: # RADIX_SECOND_LEVEL
- # V = 1 L = 1 SW = 0 RPN = 0
- # R = 1 C = 1 ATT = 0 EAA 0x7
- 0xc000000000000187,
-
- 0x1000000: # PROCESS_TABLE_3
- # RTS1 = 0x2 RPDB = 0x300 RTS2 = 0x5 RPDS = 13
- 0x40000000000300ad,
- 0x1000008: # PROCESS_TABLE_3 + 8
- # RTS1 = 0x2 RPDB = 0x308 RTS2 = 0x5 RPDS = 13
- 0x40000000000308ad,
- }
-
-prtbl = 0x1000000 # matches PROCESS_TABLE_3 above
-
-class DecoderTestCase(FHDLTestCase):
-
- def test_load(self):
- lst = [ "lwz 3, 0(1)"
- ]
- sprs = {'DSISR': SelectableInt(0, 64),
- 'DAR': SelectableInt(0, 64),
- 'PIDR': SelectableInt(0, 64),
- 'PRTBL': SelectableInt(prtbl, 64)
- }
-
- initial_regs=[0] * 32
- initial_regs[1] = 0x1000
- initial_regs[2] = 0x1234
-
- initial_mem = deepcopy(testmem)
- initial_mem[0x1000] = 0x1337 # data to be read
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs=initial_regs,
- initial_mem=initial_mem,
- initial_sprs=sprs)
- self.assertEqual(sim.gpr(3), SelectableInt(0x1337, 64))
-
- def test_load_pid_1(self):
- lst = [ "lwz 3, 0(1)"
- ]
- sprs = {'DSISR': SelectableInt(0, 64),
- 'DAR': SelectableInt(0, 64),
- 'PIDR': SelectableInt(1, 64),
- 'PRTBL': SelectableInt(prtbl, 64)
- }
-
- initial_regs=[0] * 32
- initial_regs[1] = 0x1000
- initial_regs[2] = 0x1234
-
- initial_mem = deepcopy(testmem)
- initial_mem[0x1000] = 0x1337 # data to be read
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs=initial_regs,
- initial_mem=initial_mem,
- initial_sprs=sprs)
- self.assertEqual(sim.gpr(3), SelectableInt(0x1337, 64))
-
- def test_load_store(self):
- lst = ["addi 1, 0, 0x1000",
- "addi 2, 0, 0x1234",
- "stw 2, 0(1)",
- "lwz 3, 0(1)"
- ]
- # set up dummy minimal ISACaller
- sprs = {'DSISR': SelectableInt(0, 64),
- 'DAR': SelectableInt(0, 64),
- 'PIDR': SelectableInt(0, 64),
- 'PRTBL': SelectableInt(prtbl, 64)
- }
-
- initial_regs=[0] * 32
- initial_regs[1] = 0x1000
- initial_regs[2] = 0x1234
- initial_mem = deepcopy(testmem)
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs=initial_regs,
- initial_mem=initial_mem,
- initial_sprs=sprs)
- self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
-
- def run_tst_program(self, prog, initial_regs=None, initial_mem=None,
- initial_sprs=None):
- # DO NOT set complex arguments, it is a "singleton" pattern
- if initial_regs is None:
- initial_regs = [0] * 32
-
- simulator = run_tst(prog, initial_regs, mmu=True, mem=initial_mem,
- initial_sprs=initial_sprs)
- simulator.gpr.dump()
- return simulator
-
-
-if __name__ == "__main__":
- unittest.main()
+++ /dev/null
-from nmigen import Module, Signal
-from nmigen.back.pysim import Simulator, Delay, Settle
-from nmutil.formaltest import FHDLTestCase
-import unittest
-from soc.decoder.isa.caller import ISACaller
-from soc.decoder.power_decoder import (create_pdecode)
-from soc.decoder.power_decoder2 import (PowerDecode2)
-from soc.simulator.program import Program
-from soc.decoder.isa.caller import ISACaller, SVP64State
-from soc.decoder.selectable_int import SelectableInt
-from soc.decoder.orderedset import OrderedSet
-from soc.decoder.isa.all import ISA
-from soc.decoder.isa.test_caller import Register, run_tst
-from soc.sv.trans.svp64 import SVP64Asm
-from soc.consts import SVP64CROffs
-from copy import deepcopy
-
-class DecoderTestCase(FHDLTestCase):
-
- def _check_regs(self, sim, expected):
- for i in range(32):
- self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
-
- def test_setvl_1(self):
- lst = SVP64Asm(["setvl 1, 0, 9, 1, 1",
- ])
- lst = list(lst)
-
- # SVSTATE (in this case, VL=2)
- svstate = SVP64State()
- svstate.vl[0:7] = 2 # VL
- svstate.maxvl[0:7] = 2 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, svstate=svstate)
- print ("SVSTATE after", bin(sim.svstate.spr.asint()))
- print (" vl", bin(sim.svstate.vl.asint(True)))
- print (" mvl", bin(sim.svstate.maxvl.asint(True)))
- self.assertEqual(sim.svstate.vl.asint(True), 10)
- self.assertEqual(sim.svstate.maxvl.asint(True), 10)
- self.assertEqual(sim.svstate.maxvl.asint(True), 10)
- print(" gpr1", sim.gpr(1))
- self.assertEqual(sim.gpr(1), SelectableInt(10, 64))
-
-
- def test_sv_add(self):
- # sets VL=2 then adds:
- # 1 = 5 + 9 => 0x5555 = 0x4321+0x1234
- # 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
- isa = SVP64Asm(["setvl 3, 0, 1, 1, 1",
- 'sv.add 1.v, 5.v, 9.v'
- ])
- lst = list(isa)
- print ("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[9] = 0x1234
- initial_regs[10] = 0x1111
- initial_regs[5] = 0x4321
- initial_regs[6] = 0x2223
-
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[1] = 0x5555
- expected_regs[2] = 0x3334
- expected_regs[3] = 2 # setvl places copy of VL here
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs)
- self._check_regs(sim, expected_regs)
-
- def run_tst_program(self, prog, initial_regs=None,
- svstate=None):
- if initial_regs is None:
- initial_regs = [0] * 32
- simulator = run_tst(prog, initial_regs, svstate=svstate)
- simulator.gpr.dump()
- return simulator
-
-
-if __name__ == "__main__":
- unittest.main()
-
+++ /dev/null
-from nmigen import Module, Signal
-from nmigen.back.pysim import Simulator, Delay, Settle
-from nmutil.formaltest import FHDLTestCase
-import unittest
-from soc.decoder.isa.caller import ISACaller
-from soc.decoder.power_decoder import (create_pdecode)
-from soc.decoder.power_decoder2 import (PowerDecode2)
-from soc.simulator.program import Program
-from soc.decoder.isa.caller import ISACaller, SVP64State
-from soc.decoder.selectable_int import SelectableInt
-from soc.decoder.orderedset import OrderedSet
-from soc.decoder.isa.all import ISA
-from soc.decoder.isa.test_caller import Register, run_tst
-from soc.sv.trans.svp64 import SVP64Asm
-from soc.consts import SVP64CROffs
-from copy import deepcopy
-
-class DecoderTestCase(FHDLTestCase):
-
- def _check_regs(self, sim, expected):
- for i in range(32):
- self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
-
- def test_sv_load_store(self):
- lst = SVP64Asm(["addi 1, 0, 0x0010",
- "addi 2, 0, 0x0008",
- "addi 5, 0, 0x1234",
- "addi 6, 0, 0x1235",
- "sv.stw 5.v, 0(1.v)",
- "sv.lwz 9.v, 0(1.v)"])
- lst = list(lst)
-
- # SVSTATE (in this case, VL=2)
- svstate = SVP64State()
- svstate.vl[0:7] = 2 # VL
- svstate.maxvl[0:7] = 2 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, svstate=svstate)
- print(sim.gpr(1))
- self.assertEqual(sim.gpr(9), SelectableInt(0x1234, 64))
- self.assertEqual(sim.gpr(10), SelectableInt(0x1235, 64))
-
- def test_sv_add(self):
- # adds:
- # 1 = 5 + 9 => 0x5555 = 0x4321+0x1234
- # 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
- isa = SVP64Asm(['sv.add 1.v, 5.v, 9.v'
- ])
- lst = list(isa)
- print ("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[5] = 0x4321
- initial_regs[9] = 0x1234
- initial_regs[10] = 0x1111
- initial_regs[6] = 0x2223
- # SVSTATE (in this case, VL=2)
- svstate = SVP64State()
- svstate.vl[0:7] = 2 # VL
- svstate.maxvl[0:7] = 2 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
- # copy before running, then compute answers
- expected_regs = deepcopy(initial_regs)
- expected_regs[1] = initial_regs[5] + initial_regs[9] # 0x5555
- expected_regs[2] = initial_regs[6] + initial_regs[10] # 0x3334
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def test_sv_add_2(self):
- # adds:
- # 1 = 5 + 9 => 0x5555 = 0x4321+0x1234
- # r1 is scalar so ENDS EARLY
- isa = SVP64Asm(['sv.add 1, 5.v, 9.v'
- ])
- lst = list(isa)
- print ("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[9] = 0x1234
- initial_regs[10] = 0x1111
- initial_regs[5] = 0x4321
- initial_regs[6] = 0x2223
- # SVSTATE (in this case, VL=2)
- svstate = SVP64State()
- svstate.vl[0:7] = 2 # VL
- svstate.maxvl[0:7] = 2 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[1] = initial_regs[5] + initial_regs[9] # 0x5555
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def test_sv_add_3(self):
- # adds:
- # 1 = 5 + 9 => 0x5555 = 0x4321+0x1234
- # 2 = 5 + 10 => 0x5432 = 0x4321+0x1111
- isa = SVP64Asm(['sv.add 1.v, 5, 9.v'
- ])
- lst = list(isa)
- print ("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[9] = 0x1234
- initial_regs[10] = 0x1111
- initial_regs[5] = 0x4321
- initial_regs[6] = 0x2223
- # SVSTATE (in this case, VL=2)
- svstate = SVP64State()
- svstate.vl[0:7] = 2 # VL
- svstate.maxvl[0:7] = 2 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[1] = initial_regs[5] + initial_regs[9] # 0x5555
- expected_regs[2] = initial_regs[5] + initial_regs[10] # 0x5432
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def test_sv_add_vl_0(self):
- # adds:
- # none because VL is zer0
- isa = SVP64Asm(['sv.add 1, 5.v, 9.v'
- ])
- lst = list(isa)
- print ("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[9] = 0x1234
- initial_regs[10] = 0x1111
- initial_regs[5] = 0x4321
- initial_regs[6] = 0x2223
- # SVSTATE (in this case, VL=0)
- svstate = SVP64State()
- svstate.vl[0:7] = 0 # VL
- svstate.maxvl[0:7] = 0 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def test_sv_add_cr(self):
- # adds when Rc=1: TODO CRs higher up
- # 1 = 5 + 9 => 0 = -1+1 CR0=0b100
- # 2 = 6 + 10 => 0x3334 = 0x2223+0x1111 CR1=0b010
- isa = SVP64Asm(['sv.add. 1.v, 5.v, 9.v'
- ])
- lst = list(isa)
- print ("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[9] = 0xffffffffffffffff
- initial_regs[10] = 0x1111
- initial_regs[5] = 0x1
- initial_regs[6] = 0x2223
- # SVSTATE (in this case, VL=2)
- svstate = SVP64State()
- svstate.vl[0:7] = 2 # VL
- svstate.maxvl[0:7] = 2 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[1] = initial_regs[5] + initial_regs[9] # 0x0
- expected_regs[2] = initial_regs[6] + initial_regs[10] # 0x3334
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- # XXX TODO, these need to move to higher range (offset)
- cr0_idx = SVP64CROffs.CR0
- cr1_idx = SVP64CROffs.CR1
- CR0 = sim.crl[cr0_idx].get_range().value
- CR1 = sim.crl[cr1_idx].get_range().value
- print ("CR0", CR0)
- print ("CR1", CR1)
- self._check_regs(sim, expected_regs)
- self.assertEqual(CR0, SelectableInt(2, 4))
- self.assertEqual(CR1, SelectableInt(4, 4))
-
- def run_tst_program(self, prog, initial_regs=None,
- svstate=None):
- if initial_regs is None:
- initial_regs = [0] * 32
- simulator = run_tst(prog, initial_regs, svstate=svstate)
- simulator.gpr.dump()
- return simulator
-
-
-if __name__ == "__main__":
- unittest.main()
+++ /dev/null
-from nmigen import Module, Signal
-from nmigen.back.pysim import Simulator, Delay, Settle
-from nmutil.formaltest import FHDLTestCase
-import unittest
-from soc.decoder.isa.caller import ISACaller
-from soc.decoder.power_decoder import (create_pdecode)
-from soc.decoder.power_decoder2 import (PowerDecode2)
-from soc.simulator.program import Program
-from soc.decoder.isa.caller import ISACaller, SVP64State
-from soc.decoder.selectable_int import SelectableInt
-from soc.decoder.orderedset import OrderedSet
-from soc.decoder.isa.all import ISA
-from soc.decoder.isa.test_caller import Register, run_tst
-from soc.sv.trans.svp64 import SVP64Asm
-from soc.consts import SVP64CROffs
-from copy import deepcopy
-
-class DecoderTestCase(FHDLTestCase):
-
- def _check_regs(self, sim, expected):
- for i in range(32):
- self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
-
- def tst_sv_load_store(self):
- lst = SVP64Asm(["addi 1, 0, 0x0010",
- "addi 2, 0, 0x0008",
- "addi 5, 0, 0x1234",
- "addi 6, 0, 0x1235",
- "sv.stw 5.v, 0(1.v)",
- "sv.lwz 9.v, 0(1.v)"])
- lst = list(lst)
-
- # SVSTATE (in this case, VL=2)
- svstate = SVP64State()
- svstate.vl[0:7] = 2 # VL
- svstate.maxvl[0:7] = 2 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, svstate=svstate)
- print(sim.gpr(1))
- self.assertEqual(sim.gpr(9), SelectableInt(0x1234, 64))
- self.assertEqual(sim.gpr(10), SelectableInt(0x1235, 64))
-
- def test_sv_extsw_intpred(self):
- # extsb, integer twin-pred mask: source is ~r3 (0b01), dest r3 (0b10)
- # works as follows, where any zeros indicate "skip element"
- # - sources are 9 and 10
- # - dests are 5 and 6
- # - source mask says "pick first element from source (5)
- # - dest mask says "pick *second* element from dest (10)
- #
- # therefore the operation that's carried out is:
- # GPR(10) = extsb(GPR(5))
- #
- # this is a type of back-to-back VREDUCE and VEXPAND but it applies
- # to *operations*, not just MVs like in traditional Vector ISAs
- # ascii graphic:
- #
- # reg num 0 1 2 3 4 5 6 7 8 9 10
- # src ~r3=0b01 Y N
- # |
- # +-----+
- # |
- # dest r3=0b10 N Y
-
- isa = SVP64Asm(['sv.extsb/sm=~r3/dm=r3 5.v, 9.v'
- ])
- lst = list(isa)
- print ("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[3] = 0b10 # predicate mask
- initial_regs[9] = 0x91 # source ~r3 is 0b01 so this will be used
- initial_regs[10] = 0x90 # this gets skipped
- # SVSTATE (in this case, VL=2)
- svstate = SVP64State()
- svstate.vl[0:7] = 2 # VL
- svstate.maxvl[0:7] = 2 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[5] = 0x0 # dest r3 is 0b10: skip
- expected_regs[6] = 0xffff_ffff_ffff_ff91 # 2nd bit of r3 is 1
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def test_sv_extsw_intpred_dz(self):
- # extsb, integer twin-pred mask: dest is r3 (0b01), zeroing on dest
- isa = SVP64Asm(['sv.extsb/dm=r3/dz 5.v, 9.v'
- ])
- lst = list(isa)
- print ("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[3] = 0b01 # predicate mask (dest)
- initial_regs[5] = 0xfeed # going to be overwritten
- initial_regs[6] = 0xbeef # going to be overwritten (with zero)
- initial_regs[9] = 0x91 # dest r3 is 0b01 so this will be used
- initial_regs[10] = 0x90 # this gets read but the output gets zero'd
- # SVSTATE (in this case, VL=2)
- svstate = SVP64State()
- svstate.vl[0:7] = 2 # VL
- svstate.maxvl[0:7] = 2 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[5] = 0xffff_ffff_ffff_ff91 # dest r3 is 0b01: store
- expected_regs[6] = 0 # 2nd bit of r3 is 1: zero
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def test_sv_add_intpred(self):
- # adds, integer predicated mask r3=0b10
- # 1 = 5 + 9 => not to be touched (skipped)
- # 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
- isa = SVP64Asm(['sv.add/m=r3 1.v, 5.v, 9.v'
- ])
- lst = list(isa)
- print ("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[1] = 0xbeef # not to be altered
- initial_regs[3] = 0b10 # predicate mask
- initial_regs[9] = 0x1234
- initial_regs[10] = 0x1111
- initial_regs[5] = 0x4321
- initial_regs[6] = 0x2223
- # SVSTATE (in this case, VL=2)
- svstate = SVP64State()
- svstate.vl[0:7] = 2 # VL
- svstate.maxvl[0:7] = 2 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[1] = 0xbeef
- expected_regs[2] = 0x3334
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def test_sv_add_cr_pred(self):
- # adds, CR predicated mask CR4.eq = 1, CR5.eq = 0, invert (ne)
- # 1 = 5 + 9 => not to be touched (skipped)
- # 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
- isa = SVP64Asm(['sv.add/m=ne 1.v, 5.v, 9.v'
- ])
- lst = list(isa)
- print ("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[1] = 0xbeef # not to be altered
- initial_regs[9] = 0x1234
- initial_regs[10] = 0x1111
- initial_regs[5] = 0x4321
- initial_regs[6] = 0x2223
- # SVSTATE (in this case, VL=2)
- svstate = SVP64State()
- svstate.vl[0:7] = 2 # VL
- svstate.maxvl[0:7] = 2 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[1] = 0xbeef
- expected_regs[2] = 0x3334
-
- # set up CR predicate - CR4.eq=1 and CR5.eq=0
- cr = (0b0010) << ((7-4)*4) # CR4.eq (we hope)
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate,
- initial_cr=cr)
- self._check_regs(sim, expected_regs)
-
- def tst_sv_add_2(self):
- # adds:
- # 1 = 5 + 9 => 0x5555 = 0x4321+0x1234
- # r1 is scalar so ENDS EARLY
- isa = SVP64Asm(['sv.add 1, 5.v, 9.v'
- ])
- lst = list(isa)
- print ("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[9] = 0x1234
- initial_regs[10] = 0x1111
- initial_regs[5] = 0x4321
- initial_regs[6] = 0x2223
- # SVSTATE (in this case, VL=2)
- svstate = SVP64State()
- svstate.vl[0:7] = 2 # VL
- svstate.maxvl[0:7] = 2 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[1] = 0x5555
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def tst_sv_add_3(self):
- # adds:
- # 1 = 5 + 9 => 0x5555 = 0x4321+0x1234
- # 2 = 5 + 10 => 0x5432 = 0x4321+0x1111
- isa = SVP64Asm(['sv.add 1.v, 5, 9.v'
- ])
- lst = list(isa)
- print ("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[9] = 0x1234
- initial_regs[10] = 0x1111
- initial_regs[5] = 0x4321
- initial_regs[6] = 0x2223
- # SVSTATE (in this case, VL=2)
- svstate = SVP64State()
- svstate.vl[0:7] = 2 # VL
- svstate.maxvl[0:7] = 2 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[1] = 0x5555
- expected_regs[2] = 0x5432
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def tst_sv_add_vl_0(self):
- # adds:
- # none because VL is zer0
- isa = SVP64Asm(['sv.add 1, 5.v, 9.v'
- ])
- lst = list(isa)
- print ("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[9] = 0x1234
- initial_regs[10] = 0x1111
- initial_regs[5] = 0x4321
- initial_regs[6] = 0x2223
- # SVSTATE (in this case, VL=0)
- svstate = SVP64State()
- svstate.vl[0:7] = 0 # VL
- svstate.maxvl[0:7] = 0 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def tst_sv_add_cr(self):
- # adds when Rc=1: TODO CRs higher up
- # 1 = 5 + 9 => 0 = -1+1 CR0=0b100
- # 2 = 6 + 10 => 0x3334 = 0x2223+0x1111 CR1=0b010
- isa = SVP64Asm(['sv.add. 1.v, 5.v, 9.v'
- ])
- lst = list(isa)
- print ("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[9] = 0xffffffffffffffff
- initial_regs[10] = 0x1111
- initial_regs[5] = 0x1
- initial_regs[6] = 0x2223
- # SVSTATE (in this case, VL=2)
- svstate = SVP64State()
- svstate.vl[0:7] = 2 # VL
- svstate.maxvl[0:7] = 2 # MAXVL
- print ("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[1] = 0
- expected_regs[2] = 0x3334
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- # XXX TODO, these need to move to higher range (offset)
- cr0_idx = SVP64CROffs.CR0
- cr1_idx = SVP64CROffs.CR1
- CR0 = sim.crl[cr0_idx].get_range().value
- CR1 = sim.crl[cr1_idx].get_range().value
- print ("CR0", CR0)
- print ("CR1", CR1)
- self._check_regs(sim, expected_regs)
- self.assertEqual(CR0, SelectableInt(2, 4))
- self.assertEqual(CR1, SelectableInt(4, 4))
-
- def test_intpred_vcompress(self):
- # reg num 0 1 2 3 4 5 6 7 8 9 10 11
- # src r3=0b101 Y N Y
- # | |
- # +-------+ |
- # | +-----------+
- # | |
- # dest always Y Y Y
-
- isa = SVP64Asm(['sv.extsb/sm=r3 5.v, 9.v'])
- lst = list(isa)
- print("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[3] = 0b101 # predicate mask
- initial_regs[9] = 0x90 # source r3 is 0b101 so this will be used
- initial_regs[10] = 0x91 # this gets skipped
- initial_regs[11] = 0x92 # source r3 is 0b101 so this will be used
- # SVSTATE (in this case, VL=3)
- svstate = SVP64State()
- svstate.vl[0:7] = 3 # VL
- svstate.maxvl[0:7] = 3 # MAXVL
- print("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[5] = 0xffff_ffff_ffff_ff90 # (from r9)
- expected_regs[6] = 0xffff_ffff_ffff_ff92 # (from r11)
- expected_regs[7] = 0x0 # (VL loop runs out before we can use it)
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def test_intpred_vexpand(self):
- # reg num 0 1 2 3 4 5 6 7 8 9 10 11
- # src always Y Y Y
- # | |
- # +-------+ |
- # | +------+
- # | |
- # dest r3=0b101 Y N Y
-
- isa = SVP64Asm(['sv.extsb/dm=r3 5.v, 9.v'])
- lst = list(isa)
- print("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[3] = 0b101 # predicate mask
- initial_regs[9] = 0x90 # source is "always", so this will be used
- initial_regs[10] = 0x91 # likewise
- initial_regs[11] = 0x92 # the VL loop runs out before we can use it
- # SVSTATE (in this case, VL=3)
- svstate = SVP64State()
- svstate.vl[0:7] = 3 # VL
- svstate.maxvl[0:7] = 3 # MAXVL
- print("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[5] = 0xffff_ffff_ffff_ff90 # 1st bit of r3 is 1
- expected_regs[6] = 0x0 # skip
- expected_regs[7] = 0xffff_ffff_ffff_ff91 # 3nd bit of r3 is 1
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def test_intpred_twinpred(self):
- # reg num 0 1 2 3 4 5 6 7 8 9 10 11
- # src r3=0b101 Y N Y
- # |
- # +-----+
- # |
- # dest ~r3=0b010 N Y N
-
- isa = SVP64Asm(['sv.extsb/sm=r3/dm=~r3 5.v, 9.v'])
- lst = list(isa)
- print("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[3] = 0b101 # predicate mask
- initial_regs[9] = 0x90 # source r3 is 0b101 so this will be used
- initial_regs[10] = 0x91 # this gets skipped
- initial_regs[11] = 0x92 # VL loop runs out before we can use it
- # SVSTATE (in this case, VL=3)
- svstate = SVP64State()
- svstate.vl[0:7] = 3 # VL
- svstate.maxvl[0:7] = 3 # MAXVL
- print("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[5] = 0x0 # dest ~r3 is 0b010: skip
- expected_regs[6] = 0xffff_ffff_ffff_ff90 # 2nd bit of ~r3 is 1
- expected_regs[7] = 0x0 # dest ~r3 is 0b010: skip
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- # checks that we are able to resume in the middle of a VL loop,
- # after an interrupt, or after the user has updated src/dst step
- # let's assume the user has prepared src/dst step before running this
- # vector instruction
- def test_intpred_reentrant(self):
- # reg num 0 1 2 3 4 5 6 7 8 9 10 11 12
- # srcstep=1 v
- # src r3=0b0101 Y N Y N
- # : |
- # + - - + |
- # : +-------+
- # : |
- # dest ~r3=0b1010 N Y N Y
- # dststep=2 ^
-
- isa = SVP64Asm(['sv.extsb/sm=r3/dm=~r3 5.v, 9.v'])
- lst = list(isa)
- print("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[3] = 0b0101 # mask
- initial_regs[9] = 0x90 # srcstep starts at 2, so this gets skipped
- initial_regs[10] = 0x91 # skip
- initial_regs[11] = 0x92 # this will be used
- initial_regs[12] = 0x93 # skip
-
- # SVSTATE (in this case, VL=4)
- svstate = SVP64State()
- svstate.vl[0:7] = 4 # VL
- svstate.maxvl[0:7] = 4 # MAXVL
- # set src/dest step on the middle of the loop
- svstate.srcstep[0:7] = 1
- svstate.dststep[0:7] = 2
- print("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[5] = 0x0 # skip
- expected_regs[6] = 0x0 # dststep starts at 3, so this gets skipped
- expected_regs[7] = 0x0 # skip
- expected_regs[8] = 0xffff_ffff_ffff_ff92 # this will be used
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def test_shift_one_by_r3_dest(self):
- # reg num 0 1 2 3 4 5 6 7 8 9 10 11
- # src r30=0b100 N N Y
- # |
- # +-----------+
- # |
- # dest r3=1: 1<<r3=0b010 N Y N
-
- isa = SVP64Asm(['sv.extsb/dm=1<<r3/sm=r30 5.v, 9.v'])
- lst = list(isa)
- print("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[3] = 1 # dest mask = 1<<r3 = 0b010
- initial_regs[30] = 0b100 # source mask
- initial_regs[9] = 0x90 # skipped
- initial_regs[10] = 0x91 # skipped
- initial_regs[11] = 0x92 # 3rd bit of r30 is 1
- # SVSTATE (in this case, VL=3)
- svstate = SVP64State()
- svstate.vl[0:7] = 3 # VL
- svstate.maxvl[0:7] = 3 # MAXVL
- print("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[5] = 0x0 # skip
- expected_regs[6] = 0xffff_ffff_ffff_ff92 # r3 is 1, so this is used
- expected_regs[7] = 0x0 # skip
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def test_shift_one_by_r3_source(self):
- # reg num 0 1 2 3 4 5 6 7 8 9 10 11
- # src r3=2: 1<<r3=0b100 N N Y
- # |
- # +-----------+
- # |
- # dest r30=0b010 N Y N
-
- isa = SVP64Asm(['sv.extsb/sm=1<<r3/dm=r30 5.v, 9.v'])
- lst = list(isa)
- print("listing", lst)
-
- # initial values in GPR regfile
- initial_regs = [0] * 32
- initial_regs[3] = 2 # source mask = 1<<r3 = 0b100
- initial_regs[30] = 0b010 # dest mask
- initial_regs[9] = 0x90 # skipped
- initial_regs[10] = 0x91 # skipped
- initial_regs[11] = 0x92 # r3 is 2, so this will be used
- # SVSTATE (in this case, VL=3)
- svstate = SVP64State()
- svstate.vl[0:7] = 3 # VL
- svstate.maxvl[0:7] = 3 # MAXVL
- print("SVSTATE", bin(svstate.spr.asint()))
- # copy before running
- expected_regs = deepcopy(initial_regs)
- expected_regs[5] = 0x0 # skip
- expected_regs[6] = 0xffff_ffff_ffff_ff92 # 2nd bit of r30 is 1
- expected_regs[7] = 0x0 # skip
-
- with Program(lst, bigendian=False) as program:
- sim = self.run_tst_program(program, initial_regs, svstate)
- self._check_regs(sim, expected_regs)
-
- def run_tst_program(self, prog, initial_regs=None,
- svstate=None,
- initial_cr=0):
- if initial_regs is None:
- initial_regs = [0] * 32
- simulator = run_tst(prog, initial_regs, svstate=svstate,
- initial_cr=initial_cr)
- simulator.gpr.dump()
- return simulator
-
-
-if __name__ == "__main__":
- unittest.main()
-# Reads OpenPOWER ISA pages from http://libre-riscv.org/openpower/isa
-"""OpenPOWER ISA page parser
+# moved to openpower-isa
+# https://git.libre-soc.org/?p=openpower-isa.git;a=summary
+# wildcard imports here ONLY to support migration
-returns an OrderedDict of namedtuple "Ops" containing details of all
-instructions listed in markdown files.
-
-format must be strictly as follows (no optional sections) including whitespace:
-
-# Compare Logical
-
-X-Form
-
-* cmpl BF,L,RA,RB
-
- if L = 0 then a <- [0]*32 || (RA)[32:63]
- b <- [0]*32 || (RB)[32:63]
- else a <- (RA)
- b <- (RB)
- if a <u b then c <- 0b100
- else if a >u b then c <- 0b010
- else c <- 0b001
- CR[4*BF+32:4*BF+35] <- c || XER[SO]
-
-Special Registers Altered:
-
- CR field BF
- Another field
-
-this translates to:
-
- # heading
- blank
- Some-Form
- blank
- * instruction registerlist
- * instruction registerlist
- blank
- 4-space-indented pseudo-code
- 4-space-indented pseudo-code
- blank
- Special Registers Altered:
- 4-space-indented register description
- blank
- blank(s) (optional for convenience at end-of-page)
-"""
-
-from collections import namedtuple, OrderedDict
-from copy import copy
-import os
-
-opfields = ("desc", "form", "opcode", "regs", "pcode", "sregs", "page")
-Ops = namedtuple("Ops", opfields)
-
-
-def get_isa_dir():
- fdir = os.path.abspath(os.path.dirname(__file__))
- fdir = os.path.split(fdir)[0]
- fdir = os.path.split(fdir)[0]
- fdir = os.path.split(fdir)[0]
- fdir = os.path.split(fdir)[0]
- return os.path.join(fdir, "libreriscv", "openpower", "isa")
-
-
-class ISA:
-
- def __init__(self):
- self.instr = OrderedDict()
- self.forms = {}
- self.page = {}
- for pth in os.listdir(os.path.join(get_isa_dir())):
- print(get_isa_dir(), pth)
- if "swp" in pth:
- continue
- assert pth.endswith(".mdwn"), "only %s in isa dir" % pth
- self.read_file(pth)
- continue
- # code which helped add in the keyword "Pseudo-code:" automatically
- rewrite = self.read_file_for_rewrite(pth)
- name = os.path.join("/tmp", pth)
- with open(name, "w") as f:
- f.write('\n'.join(rewrite) + '\n')
-
- def read_file_for_rewrite(self, fname):
- pagename = fname.split('.')[0]
- fname = os.path.join(get_isa_dir(), fname)
- with open(fname) as f:
- lines = f.readlines()
- rewrite = []
-
- l = lines.pop(0).rstrip() # get first line
- rewrite.append(l)
- while lines:
- print(l)
- # look for HTML comment, if starting, skip line.
- # XXX this is braindead! it doesn't look for the end
- # so please put ending of comments on one line:
- # <!-- line 1 comment -->
- # <!-- line 2 comment -->
- if l.startswith('<!--'):
- # print ("skipping comment", l)
- l = lines.pop(0).rstrip() # get first line
- continue
-
- # Ignore blank lines before the first #
- if len(l.strip()) == 0:
- continue
-
- # expect get heading
- assert l.startswith('#'), ("# not found in line %s" % l)
-
- # whitespace expected
- l = lines.pop(0).strip()
- print(repr(l))
- assert len(l) == 0, ("blank line not found %s" % l)
- rewrite.append(l)
-
- # Form expected
- l = lines.pop(0).strip()
- assert l.endswith('-Form'), ("line with -Form expected %s" % l)
- rewrite.append(l)
-
- # whitespace expected
- l = lines.pop(0).strip()
- assert len(l) == 0, ("blank line not found %s" % l)
- rewrite.append(l)
-
- # get list of opcodes
- while True:
- l = lines.pop(0).strip()
- rewrite.append(l)
- if len(l) == 0:
- break
- assert l.startswith('*'), ("* not found in line %s" % l)
-
- rewrite.append("Pseudo-code:")
- rewrite.append("")
- # get pseudocode
- while True:
- l = lines.pop(0).rstrip()
- rewrite.append(l)
- if len(l) == 0:
- break
- assert l.startswith(' '), ("4spcs not found in line %s" % l)
-
- # "Special Registers Altered" expected
- l = lines.pop(0).rstrip()
- assert l.startswith("Special"), ("special not found %s" % l)
- rewrite.append(l)
-
- # whitespace expected
- l = lines.pop(0).strip()
- assert len(l) == 0, ("blank line not found %s" % l)
- rewrite.append(l)
-
- # get special regs
- while lines:
- l = lines.pop(0).rstrip()
- rewrite.append(l)
- if len(l) == 0:
- break
- assert l.startswith(' '), ("4spcs not found in line %s" % l)
-
- # expect and drop whitespace
- while lines:
- l = lines.pop(0).rstrip()
- rewrite.append(l)
- if len(l) != 0 and not l.startswith('<!--'):
- break
-
- return rewrite
-
- def read_file(self, fname):
- pagename = fname.split('.')[0]
- fname = os.path.join(get_isa_dir(), fname)
- with open(fname) as f:
- lines = f.readlines()
-
- # set up dict with current page name
- d = {'page': pagename}
-
- # line-by-line lexer/parser, quite straightforward: pops one
- # line off the list and checks it. nothing complicated needed,
- # all sections are mandatory so no need for a full LALR parser.
-
- l = lines.pop(0).rstrip() # get first line
- while lines:
- print(l)
- # look for HTML comment, if starting, skip line.
- # XXX this is braindead! it doesn't look for the end
- # so please put ending of comments on one line:
- # <!-- line 1 comment -->
- # <!-- line 2 comment -->
- if l.startswith('<!--'):
- # print ("skipping comment", l)
- l = lines.pop(0).rstrip() # get next line
- continue
-
- # Ignore blank lines before the first #
- if len(l) == 0:
- l = lines.pop(0).rstrip() # get next line
- continue
-
- # expect get heading
- assert l.startswith('#'), ("# not found in line '%s'" % l)
- d['desc'] = l[1:].strip()
-
- # whitespace expected
- l = lines.pop(0).strip()
- print(repr(l))
- assert len(l) == 0, ("blank line not found %s" % l)
-
- # Form expected
- l = lines.pop(0).strip()
- assert l.endswith('-Form'), ("line with -Form expected %s" % l)
- d['form'] = l.split('-')[0]
-
- # whitespace expected
- l = lines.pop(0).strip()
- assert len(l) == 0, ("blank line not found %s" % l)
-
- # get list of opcodes
- li = []
- while True:
- l = lines.pop(0).strip()
- if len(l) == 0:
- break
- assert l.startswith('*'), ("* not found in line %s" % l)
- l = l[1:].split(' ') # lose star
- l = filter(lambda x: len(x) != 0, l) # strip blanks
- li.append(list(l))
- opcodes = li
-
- # "Pseudocode" expected
- l = lines.pop(0).rstrip()
- assert l.startswith("Pseudo-code:"), ("pseudocode found %s" % l)
-
- # whitespace expected
- l = lines.pop(0).strip()
- print(repr(l))
- assert len(l) == 0, ("blank line not found %s" % l)
-
- # get pseudocode
- li = []
- while True:
- l = lines.pop(0).rstrip()
- if len(l) == 0:
- break
- assert l.startswith(' '), ("4spcs not found in line %s" % l)
- l = l[4:] # lose 4 spaces
- li.append(l)
- d['pcode'] = li
-
- # "Special Registers Altered" expected
- l = lines.pop(0).rstrip()
- assert l.startswith("Special"), ("special not found %s" % l)
-
- # whitespace expected
- l = lines.pop(0).strip()
- assert len(l) == 0, ("blank line not found %s" % l)
-
- # get special regs
- li = []
- while lines:
- l = lines.pop(0).rstrip()
- if len(l) == 0:
- break
- assert l.startswith(' '), ("4spcs not found in line %s" % l)
- l = l[4:] # lose 4 spaces
- li.append(l)
- d['sregs'] = li
-
- # add in opcode
- for o in opcodes:
- self.add_op(o, d)
-
- # expect and drop whitespace
- while lines:
- l = lines.pop(0).rstrip()
- if len(l) != 0 and not l.startswith('<!--'):
- break
-
- def add_op(self, o, d):
- opcode, regs = o[0], o[1:]
- op = copy(d)
- op['regs'] = regs
- if len(regs) != 0:
- regs[0] = regs[0].split(",")
- op['opcode'] = opcode
- self.instr[opcode] = Ops(**op)
-
- # create list of instructions by form
- form = op['form']
- fl = self.forms.get(form, [])
- self.forms[form] = fl + [opcode]
-
- # create list of instructions by page
- page = op['page']
- pl = self.page.get(page, [])
- self.page[page] = pl + [opcode]
-
- def pprint_ops(self):
- for k, v in self.instr.items():
- print("# %s %s" % (v.opcode, v.desc))
- print("Form: %s Regs: %s" % (v.form, v.regs))
- print('\n'.join(map(lambda x: " %s" % x, v.pcode)))
- print("Specials")
- print('\n'.join(map(lambda x: " %s" % x, v.sregs)))
- print()
- for k, v in isa.forms.items():
- print(k, v)
-
-
-if __name__ == '__main__':
- isa = ISA()
- isa.pprint_ops()
- # example on how to access cmp regs:
- print ("cmp regs:", isa.instr["cmp"].regs)
+from openpower.decoder.pseudo.pagereader import *
-# python code-writer for OpenPOWER ISA pseudo-code parsing
+# moved to openpower-isa
+# https://git.libre-soc.org/?p=openpower-isa.git;a=summary
+# wildcard imports here ONLY to support migration
-import os
-import sys
-import shutil
-import subprocess
-from soc.decoder.pseudo.pagereader import ISA
-from soc.decoder.power_pseudo import convert_to_python
-from soc.decoder.orderedset import OrderedSet
-from soc.decoder.isa.caller import create_args
-
-
-def get_isasrc_dir():
- fdir = os.path.abspath(os.path.dirname(__file__))
- fdir = os.path.split(fdir)[0]
- return os.path.join(fdir, "isa")
-
-
-header = """\
-# auto-generated by pywriter.py, do not edit or commit
-
-from soc.decoder.isa.caller import inject, instruction_info
-from soc.decoder.helpers import (EXTS, EXTS64, EXTZ64, ROTL64, ROTL32, MASK,
- ne, eq, gt, ge, lt, le, ltu, gtu, length,
- trunc_divs, trunc_rems, MULS, DIVS, MODS,
- EXTS128, undefined)
-from soc.decoder.selectable_int import SelectableInt
-from soc.decoder.selectable_int import selectconcat as concat
-from soc.decoder.orderedset import OrderedSet
-
-class %s:
-
-"""
-
-iinfo_template = """instruction_info(func=%s,
- read_regs=%s,
- uninit_regs=%s, write_regs=%s,
- special_regs=%s, op_fields=%s,
- form='%s',
- asmregs=%s)"""
-
-
-class PyISAWriter(ISA):
- def __init__(self):
- ISA.__init__(self)
- self.pages_written = []
-
- def write_pysource(self, pagename):
- self.pages_written.append(pagename)
- instrs = isa.page[pagename]
- isadir = get_isasrc_dir()
- fname = os.path.join(isadir, "%s.py" % pagename)
- with open(fname, "w") as f:
- iinf = ''
- f.write(header % pagename) # write out header
- # go through all instructions
- for page in instrs:
- d = self.instr[page]
- print("page", pagename, page, fname, d.opcode)
- pcode = '\n'.join(d.pcode) + '\n'
- print(pcode)
- incl_carry = pagename == 'fixedshift'
- pycode, rused = convert_to_python(pcode, d.form, incl_carry)
- # create list of arguments to call
- regs = list(rused['read_regs']) + list(rused['uninit_regs'])
- regs += list(rused['special_regs'])
- args = ', '.join(create_args(regs, 'self'))
- # create list of arguments to return
- retargs = ', '.join(create_args(rused['write_regs']))
- # write out function. pre-pend "op_" because some instrs are
- # also python keywords (cmp). also replace "." with "_"
- op_fname = "op_%s" % page.replace(".", "_")
- f.write(" @inject()\n")
- f.write(" def %s(%s):\n" % (op_fname, args))
- if 'NIA' in pycode: # HACK - TODO fix
- f.write(" global NIA\n")
- pycode = pycode.split("\n")
- pycode = '\n'.join(map(lambda x: " %s" % x, pycode))
- pycode = pycode.rstrip()
- f.write(pycode + '\n')
- if retargs:
- f.write(" return (%s,)\n\n" % retargs)
- else:
- f.write("\n")
- # accumulate the instruction info
- ops = repr(rused['op_fields'])
- iinfo = iinfo_template % (op_fname, rused['read_regs'],
- rused['uninit_regs'],
- rused['write_regs'],
- rused['special_regs'],
- ops, d.form, d.regs)
- iinf += " %s_instrs['%s'] = %s\n" % (pagename, page, iinfo)
- # write out initialisation of info, for ISACaller to use
- f.write(" %s_instrs = {}\n" % pagename)
- f.write(iinf)
-
- def patch_if_needed(self, source):
- isadir = get_isasrc_dir()
- fname = os.path.join(isadir, "%s.py" % source)
- patchname = os.path.join(isadir, "%s.patch" % source)
-
- try:
- with open(patchname, 'r') as patch:
- newfname = fname + '.orig'
- shutil.copyfile(fname, newfname)
- subprocess.check_call(['patch', fname],
- stdin=patch)
- except:
- pass
-
- def write_isa_class(self):
- isadir = get_isasrc_dir()
- fname = os.path.join(isadir, "all.py")
-
- with open(fname, "w") as f:
- f.write('# auto-generated by pywriter.py: do not edit or commit\n')
- f.write('from soc.decoder.isa.caller import ISACaller\n')
- for page in self.pages_written:
- f.write('from soc.decoder.isa.%s import %s\n' % (page, page))
- f.write('\n')
-
- classes = ', '.join(['ISACaller'] + self.pages_written)
- f.write('class ISA(%s):\n' % classes)
- f.write(' def __init__(self, *args, **kwargs):\n')
- f.write(' super().__init__(*args, **kwargs)\n')
- f.write(' self.instrs = {\n')
- for page in self.pages_written:
- f.write(' **self.%s_instrs,\n' % page)
- f.write(' }\n')
-
-
-if __name__ == '__main__':
- isa = PyISAWriter()
- write_isa_class = True
- if len(sys.argv) == 1: # quick way to do it
- print(dir(isa))
- sources = isa.page.keys()
- else:
- sources = sys.argv[1:]
- if sources[0] == "noall": # don't rewrite all.py
- write_isa_class = False
- sources.pop(0)
- print ("sources", write_isa_class, sources)
- for source in sources:
- isa.write_pysource(source)
- isa.patch_if_needed(source)
- if write_isa_class:
- isa.write_isa_class()
+from openpower.decoder.pseudo.pywriter import *
from nmutil.iocontrol import RecordObject
from nmigen import Signal
-# https://bugs.libre-soc.org/show_bug.cgi?id=465
-class LDSTException(RecordObject):
- _exc_types = ['happened', 'alignment', 'instr_fault', 'invalid', 'badtree',
- 'perm_error', 'rc_error', 'segment_fault',]
- def __init__(self, name=None):
- RecordObject.__init__(self, name=name)
- for f in self._exc_types:
- setattr(self, f, Signal())
+from openpower.exceptions import LDSTException
class DCacheToLoadStore1Type(RecordObject):
-import os
-
-# set up environment variable overrides, can use for different versions
-# as well as native (TALOS-II POWER9) builds.
-cmds = {}
-for cmd in ['objcopy', 'as', 'ld', 'gcc', 'ar', 'gdb']:
- cmds[cmd] = os.environ.get(cmd.upper(), "powerpc64-linux-gnu-%s" % cmd)
-
+# moved to openpower-isa
+# https://git.libre-soc.org/?p=openpower-isa.git;a=summary
+# wildcard imports here ONLY to support migration
+from openpower.simulator.envcmds import *
-# License: LPGLv3
-# Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
-# Copyright (C) 2020 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+# moved to openpower-isa
+# https://git.libre-soc.org/?p=openpower-isa.git;a=summary
+# wildcard imports here ONLY to support migration
-import tempfile
-import subprocess
-import struct
-
-
-def get_assembled_instruction(instruction, bigendian=False):
- if bigendian:
- endian_fmt = "elf64-big"
- obj_fmt = "-be"
- else:
- endian_fmt = "elf64-little"
- obj_fmt = "-le"
- with tempfile.NamedTemporaryFile(suffix=".o") as outfile:
- args = ["powerpc64-linux-gnu-as",
- obj_fmt,
- "-o",
- outfile.name]
- p = subprocess.Popen(args, stdin=subprocess.PIPE)
- p.communicate(instruction.encode('utf-8'))
- assert(p.wait() == 0)
-
- with tempfile.NamedTemporaryFile(suffix=".bin") as binfile:
- args = ["powerpc64-linux-gnu-objcopy",
- "-I", endian_fmt,
- "-O", "binary",
- outfile.name,
- binfile.name]
- subprocess.check_output(args)
- binary = struct.unpack('>i', binfile.read(4))[0]
- return binary
+from openpower.simulator.gas import *
-# License: LGPLv3+
-# Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
-# Copyright (C) 2020 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+# moved to openpower-isa
+# https://git.libre-soc.org/?p=openpower-isa.git;a=summary
+# wildcard imports here ONLY to support migration
-"""POWER Program
-
-takes powerpc assembly instructions and turns them into LE/BE binary
-data. calls powerpc64-linux-gnu-as, ld and objcopy to do so.
-"""
-
-import tempfile
-import subprocess
-import struct
-import os
-import sys
-from io import BytesIO
-
-from soc.simulator.envcmds import cmds
-
-filedir = os.path.dirname(os.path.realpath(__file__))
-memmap = os.path.join(filedir, "memmap")
-
-
-class Program:
- def __init__(self, instructions, bigendian):
- self.bigendian = bigendian
- if self.bigendian:
- self.endian_fmt = "elf64-big"
- self.obj_fmt = "-be"
- self.ld_fmt = "-EB"
- else:
- self.ld_fmt = "-EL"
- self.endian_fmt = "elf64-little"
- self.obj_fmt = "-le"
-
- if isinstance(instructions, bytes): # actual bytes
- self.binfile = BytesIO(instructions)
- self.binfile.name = "assembly"
- self.assembly = '' # noo disassemble number fiiive
- elif isinstance(instructions, str): # filename
- # read instructions into a BytesIO to avoid "too many open files"
- with open(instructions, "rb") as f:
- b = f.read()
- self.binfile = BytesIO(b)
- self.assembly = '' # noo disassemble number fiiive
- print("program", self.binfile)
- else:
- if isinstance(instructions, list):
- instructions = '\n'.join(instructions)
- self.assembly = instructions + '\n' # plus final newline
- self._assemble()
- self._instructions = list(self._get_instructions())
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, traceback):
- self.close()
-
- def _get_binary(self, elffile):
- self.binfile = tempfile.NamedTemporaryFile(suffix=".bin")
- args = [cmds['objcopy'],
- "-O", "binary",
- "-I", self.endian_fmt,
- elffile.name,
- self.binfile.name]
- subprocess.check_output(args)
-
- def _link(self, ofile):
- with tempfile.NamedTemporaryFile(suffix=".elf") as elffile:
- args = [cmds['ld'],
- self.ld_fmt,
- "-o", elffile.name,
- "-T", memmap,
- ofile.name]
- subprocess.check_output(args)
- self._get_binary(elffile)
-
- def _assemble(self):
- with tempfile.NamedTemporaryFile(suffix=".o") as outfile:
- args = [cmds['as'],
- '-mpower9',
- '-mregnames',
- self.obj_fmt,
- "-o",
- outfile.name]
- p = subprocess.Popen(args, stdin=subprocess.PIPE)
- p.communicate(self.assembly.encode('utf-8'))
- if p.wait() != 0:
- print("Error in program:")
- print(self.assembly)
- sys.exit(1)
- self._link(outfile)
-
- def _get_instructions(self):
- while True:
- data = self.binfile.read(4)
- if not data:
- break
- yield struct.unpack('<I', data)[0] # unsigned int
-
- def generate_instructions(self):
- yield from self._instructions
-
- def reset(self):
- self.binfile.seek(0)
-
- def size(self):
- curpos = self.binfile.tell()
- self.binfile.seek(0, 2) # Seek to end of file
- size = self.binfile.tell()
- self.binfile.seek(curpos, 0)
- return size
-
- def write_bin(self, fname):
- self.reset()
- data = self.binfile.read()
- with open(fname, "wb") as f:
- f.write(data)
-
- def close(self):
- self.binfile.close()
-
-if __name__ == '__main__':
- lst = ['addi 5, 0, 4660/2',
- 'mtcrf 255, 5+3',
- 'mfocrf 2, 1',
- 'addi r2, 3, 1',
- 'attn',
- ]
- lst = ["addi 9, 0, 0x10", # i = 16
- "addi 9,9,-1", # i = i - 1
- "cmpi 2,1,9,12", # compare 9 to value 12, store in CR2
- "bc 4,10,-8", # branch if CR2 "test was != 12"
- 'attn',
- ]
-
- with Program(lst, False) as p:
- for instruction in p.generate_instructions():
- print (hex(instruction))
- p.write_bin("/tmp/test.bin")
+from openpower.simulator.program import *
-from pygdbmi.gdbcontroller import GdbController
-import subprocess
+# moved to openpower-isa
+# https://git.libre-soc.org/?p=openpower-isa.git;a=summary
+# wildcard imports here ONLY to support migration
-launch_args_be = ['qemu-system-ppc64',
- '-machine', 'powernv9',
- '-nographic',
- '-s', '-S']
-
-launch_args_le = ['qemu-system-ppc64le',
- '-machine', 'powernv9',
- '-nographic',
- '-s', '-S']
-
-
-def swap_order(x, nbytes):
- x = x.to_bytes(nbytes, byteorder='little')
- x = int.from_bytes(x, byteorder='big', signed=False)
- return x
-
-
-class QemuController:
- def __init__(self, kernel, bigendian):
- if bigendian:
- args = launch_args_be + ['-kernel', kernel]
- else:
- args = launch_args_le + ['-kernel', kernel]
- self.qemu_popen = subprocess.Popen(args,
- stdout=subprocess.PIPE,
- stdin=subprocess.PIPE)
- self.gdb = GdbController(gdb_path='powerpc64-linux-gnu-gdb')
- self.bigendian = bigendian
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, traceback):
- self.exit()
-
- def connect(self):
- return self.gdb.write('-target-select remote localhost:1234')
-
- def set_endian(self, bigendian):
- if bigendian:
- cmd = '-gdb-set endian big'
- else:
- cmd = '-gdb-set endian little'
- return self.gdb.write(cmd)
-
- def break_address(self, addr):
- cmd = '-break-insert *0x{:x}'.format(addr)
- return self.gdb.write(cmd)
-
- def delete_breakpoint(self, breakpoint=None):
- breakstring = ''
- if breakpoint:
- 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 1 1 %d" %
- (addr, 8*nbytes))
- #print ("get_mem", res)
- for x in res:
- if(x["type"] == "result"):
- 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):
- return self.gdb.write('-data-list-register-values x')
-
- def _get_register(self, fmt):
- res = self.gdb.write('-data-list-register-values '+fmt,
- timeout_sec=1.0) # increase this timeout if needed
- for x in res:
- if(x["type"] == "result"):
- assert 'register-values' in x['payload']
- res = int(x['payload']['register-values'][0]['value'], 0)
- return res
- # return swap_order(res, 8)
- return None
-
- # TODO: use -data-list-register-names instead of hardcoding the values
- def get_pc(self): return self._get_register('x 64')
- def get_msr(self): return self._get_register('x 65')
- def get_cr(self): return self._get_register('x 66')
- def get_lr(self): return self._get_register('x 67')
- def get_ctr(self): return self._get_register('x 68') # probably
- def get_xer(self): return self._get_register('x 69')
- def get_fpscr(self): return self._get_register('x 70')
- def get_mq(self): return self._get_register('x 71')
-
- def get_register(self, num):
- return self._get_register('x {}'.format(num))
-
- def step(self):
- return self.gdb.write('-exec-next-instruction')
-
- def gdb_continue(self):
- return self.gdb.write('-exec-continue')
-
- def gdb_eval(self, expr):
- return self.gdb.write(f'-data-evaluate-expression {expr}')
-
- def exit(self):
- self.gdb.exit()
- self.qemu_popen.kill()
- outs, errs = self.qemu_popen.communicate()
- self.qemu_popen.stdout.close()
- self.qemu_popen.stdin.close()
-
-
-def run_program(program, initial_mem=None, extra_break_addr=None,
- bigendian=False):
- q = QemuController(program.binfile.name, bigendian)
- q.connect()
- q.set_endian(True) # easier to set variables this way
-
- # Run to the start of the program
- 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)
-
- # set breakpoint at start
- q.break_address(0x20000000)
- q.gdb_continue()
- # set the MSR bit 63, to set bigendian/littleendian mode
- msr = q.get_msr()
- print("msr", bigendian, hex(msr))
- if bigendian:
- msr &= ~(1 << 0)
- msr = msr & ((1 << 64)-1)
- else:
- msr |= (1 << 0)
- q.gdb_eval('$msr=%d' % msr)
- print("msr set to", hex(msr))
- # set the CR to 0, matching the simulator
- q.gdb_eval('$cr=0')
- # delete the previous breakpoint so loops don't screw things up
- q.delete_breakpoint()
- # run to completion
- q.break_address(0x20000000 + program.size())
- # or to trap
- q.break_address(0x700)
- # or to alternative (absolute) address)
- if extra_break_addr:
- q.break_address(extra_break_addr)
- q.gdb_continue()
- q.set_endian(bigendian)
-
- return q
-
-
-if __name__ == '__main__':
- q = QemuController("simulator/qemu_test/kernel.bin", bigendian=True)
- q.connect()
- q.break_address(0x20000000)
- q.gdb_continue()
- print(q.get_register(1))
- print(q.step())
- print(q.get_register(1))
- q.exit()
+from openpower.simulator.qemu import *
+++ /dev/null
-from nmigen import Module, Signal
-from nmigen.back.pysim import Simulator, Delay, Settle
-from nmutil.formaltest import FHDLTestCase
-import unittest
-from soc.decoder.power_decoder import (create_pdecode)
-from soc.decoder.power_enums import (Function, MicrOp,
- In1Sel, In2Sel, In3Sel,
- OutSel, RC, LdstLen, CryIn,
- single_bit_flags, Form, SPR,
- get_signal_name, get_csv)
-from soc.decoder.power_decoder2 import (PowerDecode2)
-from soc.simulator.program import Program
-from soc.simulator.qemu import run_program
-from soc.decoder.isa.all import ISA
-from soc.fu.test.common import TestCase
-from soc.simulator.test_sim import DecoderBase
-
-
-
-class DivTestCases(FHDLTestCase):
- test_data = []
-
- def __init__(self, name="div"):
- super().__init__(name)
- self.test_name = name
-
- def test_0_divw(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x1234",
- "divw 3, 1, 2",
- ]
- with Program(lst) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- def test_1_divw_(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x1234",
- "divw. 3, 1, 2",
- ]
- with Program(lst) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- def test_2_divw_(self):
- lst = ["addi 1, 0, 0x1234",
- "addi 2, 0, 0x5678",
- "divw. 3, 1, 2",
- ]
- with Program(lst) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- def test_1_divwe(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x1234",
- "divwe 3, 1, 2",
- ]
- with Program(lst) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- def test_2_divweu(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x1234",
- "divweu 3, 1, 2",
- ]
- with Program(lst) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- def test_4_moduw(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x1234",
- "moduw 3, 1, 2",
- ]
- with Program(lst) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- def test_5_div_regression(self):
- lst = ["addi 1, 0, 0x4",
- "addi 2, 0, 0x2",
- "neg 2, 2",
- "neg 1, 1",
- "divwo 3, 1, 2",
- ]
- with Program(lst) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- def run_tst_program(self, prog, initial_regs=None, initial_sprs=None,
- initial_mem=None):
- initial_regs = [0] * 32
- tc = TestCase(prog, self.test_name, initial_regs, initial_sprs, 0,
- initial_mem, 0)
- self.test_data.append(tc)
-
-
-class DivZeroTestCases(FHDLTestCase):
- test_data = []
-
- def __init__(self, name="divbyzero"):
- super().__init__(name)
- self.test_name = name
-
- def test_0_divw(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x0",
- "divw 3, 1, 2",
- ]
- with Program(lst) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- def test_1_divwe(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x0",
- "divwe 3, 1, 2",
- ]
- with Program(lst) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- def test_2_divweu(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x0",
- "divweu 3, 1, 2",
- ]
- with Program(lst) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- def test_4_moduw(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x0",
- "moduw 3, 1, 2",
- ]
- with Program(lst) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- def run_tst_program(self, prog, initial_regs=None, initial_sprs=None,
- initial_mem=None):
- initial_regs = [0] * 32
- tc = TestCase(prog, self.test_name, initial_regs, initial_sprs, 0,
- initial_mem, 0)
- self.test_data.append(tc)
-
-
-
-class DivDecoderTestCase(DecoderBase, DivTestCases):
- pass
-
-class DivZeroDecoderTestCase(DecoderBase, DivZeroTestCases):
- pass
-
-if __name__ == "__main__":
- unittest.main()
+++ /dev/null
-from nmigen import Module, Signal
-from nmigen.back.pysim import Simulator, Delay, Settle
-from nmutil.formaltest import FHDLTestCase
-import unittest
-from soc.decoder.power_decoder import (create_pdecode)
-from soc.decoder.power_enums import (Function, MicrOp,
- In1Sel, In2Sel, In3Sel,
- OutSel, RC, LdstLen, CryIn,
- single_bit_flags, Form, SPR,
- get_signal_name, get_csv)
-from soc.decoder.power_decoder2 import (PowerDecode2)
-from soc.simulator.program import Program
-from soc.simulator.qemu import run_program
-from soc.decoder.isa.all import ISA
-from soc.fu.test.common import TestCase
-from soc.simulator.test_sim import DecoderBase
-from soc.config.endian import bigendian
-
-
-class HelloTestCases(FHDLTestCase):
- test_data = []
-
- def __init__(self, name="div"):
- super().__init__(name)
- self.test_name = name
-
- def test_microwatt_helloworld(self):
- lst = ["addis 1,0,0",
- "ori 1,1,0",
- "rldicr 1,1,32,31",
- "oris 1,1,0",
- "ori 1,1,7936",
- "addis 12,0,0",
- "ori 12,12,0",
- "rldicr 12,12,32,31",
- "oris 12,12,0",
- "ori 12,12,4116",
- "mtspr 9, 12", # mtctr r12
- "bcctrl 20,0,0", # bctrl
- ]
- self.run_tst_program(Program(lst, bigendian),
- [1,12], extra_break_addr=0x1014)
-
- def run_tst_program(self, prog, initial_regs=None, initial_sprs=None,
- initial_mem=None, extra_break_addr=None):
- initial_regs = [0] * 32
- tc = TestCase(prog, self.test_name, initial_regs, initial_sprs, 0,
- initial_mem, 0,
- extra_break_addr=extra_break_addr)
- self.test_data.append(tc)
-
-
-class HelloDecoderTestCase(DecoderBase, HelloTestCases):
- pass
-
-
-if __name__ == "__main__":
- unittest.main()
+++ /dev/null
-from nmigen import Module, Signal
-from nmigen.back.pysim import Simulator, Delay, Settle
-from nmutil.formaltest import FHDLTestCase
-import unittest
-from soc.decoder.power_decoder import (create_pdecode)
-from soc.decoder.power_enums import (Function, MicrOp,
- In1Sel, In2Sel, In3Sel,
- OutSel, RC, LdstLen, CryIn,
- single_bit_flags, Form, SPR,
- get_signal_name, get_csv)
-from soc.decoder.power_decoder2 import (PowerDecode2)
-from soc.simulator.program import Program
-from soc.simulator.qemu import run_program
-from soc.decoder.isa.all import ISA
-from soc.fu.test.common import TestCase
-from soc.simulator.test_sim import DecoderBase
-from soc.config.endian import bigendian
-
-
-
-class MulTestCases(FHDLTestCase):
- test_data = []
-
- def __init__(self, name="div"):
- super().__init__(name)
- self.test_name = name
-
- def tst_mullw(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x1234",
- "mullw 3, 1, 2"]
- self.run_tst_program(Program(lst, bigendian), [3])
-
- def test_mullwo(self):
- lst = ["addi 1, 0, 0x5678",
- "neg 1, 1",
- "addi 2, 0, 0x1234",
- "neg 2, 2",
- "mullwo 3, 1, 2"]
- self.run_tst_program(Program(lst, bigendian), [3])
-
- def run_tst_program(self, prog, initial_regs=None, initial_sprs=None,
- initial_mem=None):
- initial_regs = [0] * 32
- tc = TestCase(prog, self.test_name, initial_regs, initial_sprs, 0,
- initial_mem, 0)
- self.test_data.append(tc)
-
-
-class MulDecoderTestCase(DecoderBase, MulTestCases):
- pass
-
-
-if __name__ == "__main__":
- unittest.main()
+++ /dev/null
-from nmigen import Module, Signal
-from nmigen.back.pysim import Simulator, Delay, Settle
-from nmutil.formaltest import FHDLTestCase
-import unittest
-from soc.decoder.power_decoder import (create_pdecode)
-from soc.decoder.power_enums import (Function, MicrOp,
- In1Sel, In2Sel, In3Sel,
- OutSel, RC, LdstLen, CryIn,
- single_bit_flags, Form, SPR,
- get_signal_name, get_csv)
-from soc.decoder.power_decoder2 import (PowerDecode2)
-from soc.simulator.program import Program
-from soc.simulator.qemu import run_program
-from soc.decoder.isa.all import ISA
-from soc.fu.test.common import TestCase
-from soc.simulator.test_sim import DecoderBase
-from soc.config.endian import bigendian
-
-
-
-class MulTestCases(FHDLTestCase):
- test_data = []
-
- def __init__(self, name="div"):
- super().__init__(name)
- self.test_name = name
-
- def test_1_extswsli(self):
- lst = ["addi 1, 0, 0x5678",
- "extswsli 3, 1, 34"]
- self.run_tst_program(Program(lst, bigendian), [3])
-
- def run_tst_program(self, prog, initial_regs=None, initial_sprs=None,
- initial_mem=None):
- initial_regs = [0] * 32
- tc = TestCase(prog, self.test_name, initial_regs, initial_sprs, 0,
- initial_mem, 0)
- self.test_data.append(tc)
-
-
-class MulDecoderTestCase(DecoderBase, MulTestCases):
- pass
-
-
-if __name__ == "__main__":
- unittest.main()
+++ /dev/null
-from nmigen import Module, Signal
-from nmigen.back.pysim import Simulator, Delay, Settle
-from nmutil.formaltest import FHDLTestCase
-import unittest
-from soc.decoder.power_decoder import (create_pdecode)
-from soc.decoder.power_enums import (Function, MicrOp,
- In1Sel, In2Sel, In3Sel,
- OutSel, RC, LdstLen, CryIn,
- single_bit_flags, Form,
- get_signal_name, get_csv)
-from soc.decoder.power_decoder2 import (PowerDecode2)
-from soc.simulator.program import Program
-from soc.simulator.qemu import run_program
-from soc.decoder.isa.all import ISA
-from soc.fu.test.common import TestCase
-from soc.config.endian import bigendian
-
-
-class AttnTestCase(FHDLTestCase):
- test_data = []
-
- def __init__(self, name="general"):
- super().__init__(name)
- self.test_name = name
-
- def test_0_attn(self):
- """simple test of attn. program is 4 long: should halt at 2nd op
- """
- lst = ["addi 6, 0, 0x10",
- "attn",
- "subf. 1, 6, 7",
- "cmp cr2, 1, 6, 7",
- ]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1])
-
- def run_tst_program(self, prog, initial_regs=None, initial_sprs=None,
- initial_mem=None):
- initial_regs = [0] * 32
- tc = TestCase(prog, self.test_name, initial_regs, initial_sprs, 0,
- initial_mem, 0)
- self.test_data.append(tc)
-
-
-class GeneralTestCases(FHDLTestCase):
- test_data = []
-
- def __init__(self, name="general"):
- super().__init__(name)
- self.test_name = name
-
- @unittest.skip("disable")
- def test_0_litex_bios_ctr_loop(self):
- """
- 32a4: ff ff 63 38 addi r3,r3,-1
- 32a8: 20 00 63 78 clrldi r3,r3,32
- 32ac: 01 00 23 39 addi r9,r3,1
- 32b0: a6 03 29 7d mtctr r9
- 32b4: 00 00 00 60 nop
- 32b8: fc ff 00 42 bdnz 32b4 <cdelay+0x10>
- 32bc: 20 00 80 4e blr
-
- notes on converting pseudo-assembler to actual:
-
- * bdnz target (equivalent to: bc 16,0,target)
- * Clear left immediate clrldi ra,rs,n (n < 64) rldicl ra,rs,0,n
- * CTR mtctr Rx mtspr 9,Rx
- """
- pass
-
- @unittest.skip("disable")
- def test_0_litex_bios_cmp(self):
- """litex bios cmp test
- """
- lst = [ "addis 26, 0, 21845",
- "ori 26, 26, 21845",
- "addi 5, 26, 0",
- "rldicr 5,5,32,31",
- "addi 5, 26, 0",
- "cmp 0, 0, 5, 26",
- "bc 12, 2, 28",
- "addis 6, 0, 1",
- "addis 7, 0, 1",
- ]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [5,6,7,26], initial_mem={})
-
- @unittest.skip("disable")
- def test_0_litex_bios_r1(self):
- """litex bios IMM64 macro test
- """
- lst = [ "addis 1,0,0",
- "ori 1,1,0",
- "rldicr 1,1,32,31",
- "oris 1,1,256",
- "ori 1,1,3832",
- ]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1], initial_mem={})
-
- @unittest.skip("disable")
- def test_0_litex_trampoline(self):
- lst = ["tdi 0,0,0x48",
- "b 0x28",
- "mfmsr r11",
- "bcl 20,31,4",
- "mflr r10",
- "addi r10,r10,20",
- "mthsrr0 r10",
- "mthsrr1 r11",
- "hrfid",
- ]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [], initial_mem={})
-
- @unittest.skip("disable")
- def test_0_cmp(self):
- lst = ["addi 6, 0, 0x10",
- "addi 7, 0, 0x05",
- "subf. 1, 6, 7",
- "cmp cr2, 1, 6, 7",
- ]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1])
-
- @unittest.skip("disable")
- def test_example(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x1234",
- "add 3, 1, 2",
- "and 4, 1, 2"]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1, 2, 3, 4])
-
- @unittest.skip("disable")
- def test_ldst(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x1234",
- "stw 1, 0(2)",
- "lwz 3, 0(2)"
- ]
- initial_mem = {0x1230: (0x5432123412345678, 8),
- 0x1238: (0xabcdef0187654321, 8),
- }
- with Program(lst, bigendian) as program:
- self.run_tst_program(program,
- [1, 2, 3],
- initial_mem)
-
- @unittest.skip("disable")
- def test_ldst_update(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x1234",
- "stwu 1, 0(2)",
- "lwz 3, 0(2)"
- ]
- initial_mem = {0x1230: (0x5432123412345678, 8),
- 0x1238: (0xabcdef0187654321, 8),
- }
- with Program(lst, bigendian) as program:
- self.run_tst_program(program,
- [1, 2, 3],
- initial_mem)
-
- @unittest.skip("disable")
- def test_ld_rev_ext(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x1234",
- "addi 4, 0, 0x40",
- "stw 1, 0x40(2)",
- "lwbrx 3, 4, 2"]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- @unittest.skip("disable")
- def test_st_rev_ext(self):
- lst = ["addi 1, 0, 0x5678",
- "addi 2, 0, 0x1234",
- "addi 4, 0, 0x40",
- "stwbrx 1, 4, 2",
- "lwzx 3, 4, 2"]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- @unittest.skip("disable")
- def test_ldst_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, bigendian) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- @unittest.skip("disable")
- def test_0_ldst_widths(self):
- lst = ["addis 1, 0, 0xdead",
- "ori 1, 1, 0xbeef",
- "addi 2, 0, 0x1000",
- "std 1, 0(2)",
- "lbz 1, 5(2)",
- "lhz 3, 4(2)",
- "lwz 4, 4(2)",
- "addi 5, 0, 0x12",
- "stb 5, 5(2)",
- "ld 5, 0(2)"]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1, 2, 3, 4, 5])
-
- @unittest.skip("disable")
- def test_sub(self):
- lst = ["addi 1, 0, 0x1234",
- "addi 2, 0, 0x5678",
- "subf 3, 1, 2",
- "subfic 4, 1, 0x1337",
- "neg 5, 1"]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1, 2, 3, 4, 5])
-
- @unittest.skip("disable")
- def test_add_with_carry(self):
- lst = ["addi 1, 0, 5",
- "neg 1, 1",
- "addi 2, 0, 7",
- "neg 2, 2",
- "addc 3, 2, 1",
- "addi 3, 3, 1"
- ]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1, 2, 3])
-
- @unittest.skip("disable")
- def test_addis(self):
- lst = ["addi 1, 0, 0x0FFF",
- "addis 1, 1, 0x0F"
- ]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1])
-
- @unittest.skip("broken")
- def test_mulli(self):
- lst = ["addi 1, 0, 3",
- "mulli 1, 1, 2"
- ]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1])
-
- #@unittest.skip("disable")
- def test_crxor(self):
- lst = ["addi 1, 0, 0x1004",
- "addi 2, 0, 0x1008",
- "addi 3, 0, 0x01ee",
- "mtcrf 0b1111111, 3",
- "crxor 3, 30, 4",
- "mfcr 3",
- ]
- initial_regs = [0] * 32
- initial_regs[1] = 0x1004
- initial_regs[2] = 0x1008
- initial_regs[3] = 0x01ee
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [3, 4])
-
- #@unittest.skip("disable")
- def test_crxor_2(self):
- lst = ["addi 1, 0, 0x1004",
- "addi 2, 0, 0x1008",
- "addi 3, 0, 0x01ee",
- "mtcrf 0b1111111, 3",
- "crxor 29, 30, 29",
- "mfcr 3",
- ]
- initial_regs = [0] * 32
- initial_regs[1] = 0x1004
- initial_regs[2] = 0x1008
- initial_regs[3] = 0x01ee
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [3, 4])
-
- #@unittest.skip("disable")
- def test_crnand(self):
- lst = ["addi 1, 0, 0x1004",
- "addi 2, 0, 0x1008",
- "addi 3, 0, 0x01ee",
- "mtcrf 0b1111111, 3",
- "crnand 3, 30, 4",
- "mfcr 3",
- ]
- initial_regs = [0] * 32
- initial_regs[1] = 0x1004
- initial_regs[2] = 0x1008
- initial_regs[3] = 0x01ee
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [3, 4])
-
- #@unittest.skip("disable")
- def test_crnand_2(self):
- lst = ["addi 1, 0, 0x1004",
- "addi 2, 0, 0x1008",
- "addi 3, 0, 0x01ee",
- "mtcrf 0b1111111, 3",
- "crnand 28, 30, 29",
- "mfcr 3",
- ]
- initial_regs = [0] * 32
- initial_regs[1] = 0x1004
- initial_regs[2] = 0x1008
- initial_regs[3] = 0x01ee
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [3, 4])
-
- @unittest.skip("disable")
- def test_isel_1(self):
- lst = ["addi 1, 0, 0x1004",
- "addi 2, 0, 0x1008",
- "addi 3, 0, 0x01ee",
- "mtcrf 0b1111111, 3",
- "isel 4, 1, 2, 2"
- ]
- initial_regs = [0] * 32
- initial_regs[1] = 0x1004
- initial_regs[2] = 0x1008
- initial_regs[3] = 0x00ee
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [3, 4])
-
- #@unittest.skip("disable")
- def test_isel_2(self):
- lst = ["addi 1, 0, 0x1004",
- "addi 2, 0, 0x1008",
- "addi 3, 0, 0x01ee",
- "mtcrf 0b1111111, 3",
- "isel 4, 1, 2, 30"
- ]
- initial_regs = [0] * 32
- initial_regs[1] = 0x1004
- initial_regs[2] = 0x1008
- initial_regs[3] = 0x00ee
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [3, 4])
-
- @unittest.skip("disable")
- def test_isel_3(self):
- lst = ["addi 1, 0, 0x1004",
- "addi 2, 0, 0x1008",
- "addi 3, 0, 0x01ee",
- "mtcrf 0b1111111, 3",
- "isel 4, 1, 2, 31"
- ]
- initial_regs = [0] * 32
- initial_regs[1] = 0x1004
- initial_regs[2] = 0x1008
- initial_regs[3] = 0x00ee
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [3, 4])
-
- @unittest.skip("disable")
- def test_2_load_store(self):
- lst = ["addi 1, 0, 0x1004",
- "addi 2, 0, 0x1008",
- "addi 3, 0, 0x00ee",
- "stb 3, 1(2)",
- "lbz 4, 1(2)",
- ]
- initial_regs = [0] * 32
- initial_regs[1] = 0x1004
- initial_regs[2] = 0x1008
- initial_regs[3] = 0x00ee
- initial_mem = {0x1000: (0x5432123412345678, 8),
- 0x1008: (0xabcdef0187654321, 8),
- 0x1020: (0x1828384822324252, 8),
- }
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [3, 4], initial_mem)
-
- @unittest.skip("disable")
- 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] = 0x1004
- initial_regs[2] = 0x1002
- initial_regs[3] = 0x15eb
- initial_mem = {0x1000: (0x5432123412345678, 8),
- 0x1008: (0xabcdef0187654321, 8),
- 0x1020: (0x1828384822324252, 8),
- }
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1, 2, 3, 4], initial_mem)
-
- @unittest.skip("disable")
- def test_nop(self):
- lst = ["addi 1, 0, 0x1004",
- "ori 0,0,0", # "preferred" form of nop
- "addi 3, 0, 0x15eb",
- ]
- initial_regs = [0] * 32
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1, 3])
-
- @unittest.skip("disable")
- def test_zero_illegal(self):
- lst = bytes([0x10,0x00,0x20,0x39,
- 0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0 ])
- disassembly = ["addi 9, 0, 0x10",
- "nop", # not quite
- "nop"] # not quite
- initial_regs = [0] * 32
- with Program(lst, bigendian) as program:
- program.assembly = '\n'.join(disassembly) + '\n' # XXX HACK!
- self.run_tst_program(program, [1, 3])
-
- def test_loop(self):
- """
- in godbolt.org:
- register unsigned long i asm ("r9");
- void square(void) {
- i = 16;
- do {
- i = i - 1;
- } while (i != 12);
- }
- """
- lst = ["addi 9, 0, 0x10", # i = 16
- "addi 9,9,-1", # i = i - 1
- "cmpi 2,1,9,12", # compare 9 to value 12, store in CR2
- "bc 4,10,-8" # branch if CR2 "test was != 12"
- ]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [9], initial_mem={})
-
- @unittest.skip("disable")
- def test_30_addis(self):
- lst = [ # "addi 0, 0, 5",
- "addis 12, 0, 0",
- ]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [12])
-
- @unittest.skip("disable")
- def test_31_addis(self):
- """tests for zero not in register zero
- """
- lst = [ "rldicr 0, 0, 32, 31",
- "oris 0, 0, 32767",
- "ori 0, 0, 65535",
- "addis 1, 0, 1",
- "ori 1, 1, 515",
- "rldicr 1, 1, 32, 31",
- "oris 1, 1, 1029",
- "ori 1, 1, 1543",
- "addis 2, 0, -1",
- ]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [0, 1, 2])
-
- def run_tst_program(self, prog, initial_regs=None, initial_sprs=None,
- initial_mem=None):
- initial_regs = [0] * 32
- tc = TestCase(prog, self.test_name, initial_regs, initial_sprs, 0,
- initial_mem, 0)
- self.test_data.append(tc)
-
-
-class DecoderBase:
-
- def run_tst(self, generator, initial_mem=None, initial_pc=0):
- m = Module()
- comb = m.d.comb
-
- gen = list(generator.generate_instructions())
- insn_code = generator.assembly.splitlines()
- instructions = list(zip(gen, insn_code))
-
- pdecode = create_pdecode()
- m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
-
- # place program at requested address
- gen = (initial_pc, gen)
-
- simulator = ISA(pdecode2, [0] * 32, {}, 0, initial_mem, 0,
- initial_insns=gen, respect_pc=True,
- disassembly=insn_code,
- initial_pc=initial_pc,
- bigendian=bigendian)
-
- sim = Simulator(m)
-
- def process():
- # yield pdecode2.dec.bigendian.eq(bigendian)
- yield Settle()
-
- while True:
- try:
- yield from simulator.setup_one()
- except KeyError: # indicates instruction not in imem: stop
- break
- yield Settle()
- yield from simulator.execute_one()
- yield Settle()
-
- sim.add_process(process)
- with sim.write_vcd("pdecode_simulator.vcd"):
- sim.run()
-
- return simulator
-
- def run_tst_program(self, prog, reglist, initial_mem=None,
- extra_break_addr=None):
- import sys
- simulator = self.run_tst(prog, initial_mem=initial_mem,
- initial_pc=0x20000000)
- prog.reset()
- with run_program(prog, initial_mem, extra_break_addr,
- bigendian=bigendian) as q:
- self.qemu_register_compare(simulator, q, reglist)
- self.qemu_mem_compare(simulator, q, True)
- print(simulator.gpr.dump())
-
- 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 mem %06x %016x" % (k*8, v))
- if not check:
- return
- for k, v in sim.mem.mem.items():
- 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()
- sim_cr = sim.cr.value
- sim_pc = sim.pc.CIA.value
- sim_xer = sim.spr['XER'].value
- print("qemu pc", hex(qpc))
- print("qemu cr", hex(qcr))
- print("qemu xer", bin(qxer))
- print("sim nia", hex(sim.pc.NIA.value))
- print("sim pc", hex(sim.pc.CIA.value))
- print("sim cr", hex(sim_cr))
- print("sim xer", hex(sim_xer))
- self.assertEqual(qpc, sim_pc)
- for reg in regs:
- qemu_val = qemu.get_register(reg)
- sim_val = sim.gpr(reg).value
- self.assertEqual(qemu_val, sim_val,
- "expect %x got %x" % (qemu_val, sim_val))
- self.assertEqual(qcr, sim_cr)
-
-
-class DecoderTestCase(DecoderBase, GeneralTestCases):
- pass
-
-
-if __name__ == "__main__":
- unittest.main()
+++ /dev/null
-from nmigen import Module, Signal
-from nmigen.back.pysim import Simulator, Delay, Settle
-from nmutil.formaltest import FHDLTestCase
-import unittest
-from soc.decoder.power_decoder import (create_pdecode)
-from soc.decoder.power_enums import (Function, MicrOp,
- In1Sel, In2Sel, In3Sel,
- OutSel, RC, LdstLen, CryIn,
- single_bit_flags, Form, SPR,
- get_signal_name, get_csv)
-from soc.decoder.power_decoder2 import (PowerDecode2)
-from soc.simulator.program import Program
-from soc.simulator.qemu import run_program
-from soc.decoder.isa.all import ISA
-from soc.fu.test.common import TestCase
-from soc.simulator.test_sim import DecoderBase
-from soc.config.endian import bigendian
-
-
-class TrapSimTestCases(FHDLTestCase):
- test_data = []
-
- def __init__(self, name="div"):
- super().__init__(name)
- self.test_name = name
-
- def test_0_not_twi(self):
- lst = ["addi 1, 0, 0x5678",
- "twi 4, 1, 0x5677",
- ]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1])
-
- def test_1_twi_eq(self):
- lst = ["addi 1, 0, 0x5678",
- "twi 4, 1, 0x5678",
- ]
- with Program(lst, bigendian) as program:
- self.run_tst_program(program, [1])
-
- def run_tst_program(self, prog, initial_regs=None, initial_sprs=None,
- initial_mem=None):
- initial_regs = [0] * 32
- tc = TestCase(prog, self.test_name, initial_regs, initial_sprs, 0,
- initial_mem, 0)
- self.test_data.append(tc)
-
-
-class TrapDecoderTestCase(DecoderBase, TrapSimTestCases):
- pass
-
-
-if __name__ == "__main__":
- unittest.main()