From 012b936d50e0ad876bf3426842672f980eb1d27d Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Fri, 23 Apr 2021 15:16:23 +0100 Subject: [PATCH] removing more as moved over to openpower-isa --- openpower-isa | 2 +- src/soc/config/state.py | 23 +- src/soc/consts.py | 277 +-------- src/soc/decoder/isa/test_caller.py | 332 +--------- src/soc/decoder/isa/test_caller_radix.py | 132 ---- src/soc/decoder/isa/test_caller_setvl.py | 85 --- src/soc/decoder/isa/test_caller_svp64.py | 205 ------- .../isa/test_caller_svp64_predication.py | 532 ---------------- src/soc/decoder/pseudo/pagereader.py | 320 +--------- src/soc/decoder/pseudo/pywriter.py | 151 +---- src/soc/experiment/mem_types.py | 9 +- src/soc/simulator/envcmds.py | 12 +- src/soc/simulator/gas.py | 37 +- src/soc/simulator/program.py | 144 +---- src/soc/simulator/qemu.py | 178 +----- src/soc/simulator/test_div_sim.py | 148 ----- src/soc/simulator/test_helloworld_sim.py | 58 -- src/soc/simulator/test_mul_sim.py | 55 -- src/soc/simulator/test_shift_sim.py | 46 -- src/soc/simulator/test_sim.py | 569 ------------------ src/soc/simulator/test_trap_sim.py | 54 -- 21 files changed, 38 insertions(+), 3331 deletions(-) delete mode 100644 src/soc/decoder/isa/test_caller_radix.py delete mode 100644 src/soc/decoder/isa/test_caller_setvl.py delete mode 100644 src/soc/decoder/isa/test_caller_svp64.py delete mode 100644 src/soc/decoder/isa/test_caller_svp64_predication.py delete mode 100644 src/soc/simulator/test_div_sim.py delete mode 100644 src/soc/simulator/test_helloworld_sim.py delete mode 100644 src/soc/simulator/test_mul_sim.py delete mode 100644 src/soc/simulator/test_shift_sim.py delete mode 100644 src/soc/simulator/test_sim.py delete mode 100644 src/soc/simulator/test_trap_sim.py diff --git a/openpower-isa b/openpower-isa index 15fa1944..dab541a4 160000 --- a/openpower-isa +++ b/openpower-isa @@ -1 +1 @@ -Subproject commit 15fa1944f4d59d10efb53978e24a68d4731a5f43 +Subproject commit dab541a4a8cba23a486cbdb9e0fc9219091da3f5 diff --git a/src/soc/config/state.py b/src/soc/config/state.py index a3972ef1..2295eda0 100644 --- a/src/soc/config/state.py +++ b/src/soc/config/state.py @@ -1,20 +1,5 @@ -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 * diff --git a/src/soc/consts.py b/src/soc/consts.py index 3060c826..40ff0cd5 100644 --- a/src/soc/consts.py +++ b/src/soc/consts.py @@ -1,274 +1,5 @@ -# 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 * diff --git a/src/soc/decoder/isa/test_caller.py b/src/soc/decoder/isa/test_caller.py index 77b54c7c..d788ddcc 100644 --- a/src/soc/decoder/isa/test_caller.py +++ b/src/soc/decoder/isa/test_caller.py @@ -1,329 +1,5 @@ -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 * diff --git a/src/soc/decoder/isa/test_caller_radix.py b/src/soc/decoder/isa/test_caller_radix.py deleted file mode 100644 index 26c813d0..00000000 --- a/src/soc/decoder/isa/test_caller_radix.py +++ /dev/null @@ -1,132 +0,0 @@ -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() diff --git a/src/soc/decoder/isa/test_caller_setvl.py b/src/soc/decoder/isa/test_caller_setvl.py deleted file mode 100644 index ad7991f1..00000000 --- a/src/soc/decoder/isa/test_caller_setvl.py +++ /dev/null @@ -1,85 +0,0 @@ -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() - diff --git a/src/soc/decoder/isa/test_caller_svp64.py b/src/soc/decoder/isa/test_caller_svp64.py deleted file mode 100644 index 7cc04f40..00000000 --- a/src/soc/decoder/isa/test_caller_svp64.py +++ /dev/null @@ -1,205 +0,0 @@ -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() diff --git a/src/soc/decoder/isa/test_caller_svp64_predication.py b/src/soc/decoder/isa/test_caller_svp64_predication.py deleted file mode 100644 index 20b7c278..00000000 --- a/src/soc/decoder/isa/test_caller_svp64_predication.py +++ /dev/null @@ -1,532 +0,0 @@ -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<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: - # - # - if l.startswith(' - # - if l.startswith('