SVM-Form
-* svstate SVxd, SVyd, SVzd, SVRM
+* svremap SVxd, SVyd, SVzd, SVRM
Pseudo-code:
SVSHAPE1[0:31] <- [0] * 32
SVSHAPE2[0:31] <- [0] * 32
SVSHAPE3[0:31] <- [0] * 32
- # set up FRT and FRB
+ # set up template in SVSHAPE0, then copy to 1-3
SVSHAPE0[0:5] <- (0b0 || SVxd) # xdim
- SVSHAPE3[0:5] <- (0b0 || SVxd) # xdim
+ SVSHAPE0[6:11] <- (0b0 || SVyd) # ydim
+ SVSHAPE0[12:17] <- (0b0 || SVzd) # zdim
+ SVSHAPE0[28:29] <- 0b11 # skip z
+ # copy
+ SVSHAPE1[0:31] <- SVSHAPE0[0:31]
+ SVSHAPE2[0:31] <- SVSHAPE0[0:31]
+ SVSHAPE3[0:31] <- SVSHAPE0[0:31]
# set up FRA
- SVSHAPE0[0:5] <- (0b0 || SVxd) # xdim
- SVSHAPE0[6:11] <- (0b0 || SVyd) # ydim
- SVSHAPE0[18:20] <- 0b010 # permute y,x,z
+ SVSHAPE1[18:20] <- 0b001 # permute x,z,y
+ SVSHAPE1[28:29] <- 0b01 # skip z
+ # FRC
+ SVSHAPE2[18:20] <- 0b001 # permute x,z,y
+ SVSHAPE2[28:29] <- 0b11 # skip y
Special Registers Altered:
SVyd (11:15)
Simple-V "REMAP" y-dimension size
Formats: SVM
+ SVzd (16:20)
+ Simple-V "REMAP" z-dimension size
+ Formats: SVM
SX,S (28,6:10)
Fields SX and S are concatenated to specify a
VSR to be used as a source.
"TAR": 0,
"MSR": 0,
"SVSTATE": 0,
+ "SVSHAPE0": 0,
+ "SVSHAPE1": 0,
+ "SVSHAPE2": 0,
+ "SVSHAPE3": 0,
"CA": 0,
"CA32": 0,
self.gpr = GPR(decoder2, self, self.svstate, regfile)
self.fpr = GPR(decoder2, self, self.svstate, fpregfile)
self.spr = SPR(decoder2, initial_sprs) # initialise SPRs before MMU
+ for i in range(4):
+ sname = 'SVSHAPE%d' % i
+ if sname not in self.spr:
+ self.spr[sname] = SVSHAPE(0)
+
# "raw" memory
self.mem = Mem(row_bytes=8, initial_mem=initial_mem)
self.imem = Mem(row_bytes=4, initial_mem=initial_insns)
'NIA': self.pc.NIA,
'CIA': self.pc.CIA,
'SVSTATE': self.svstate.spr,
+ 'SVSHAPE0': self.spr['SVSHAPE0'],
+ 'SVSHAPE1': self.spr['SVSHAPE1'],
+ 'SVSHAPE2': self.spr['SVSHAPE2'],
+ 'SVSHAPE3': self.spr['SVSHAPE3'],
'CR': self.cr,
'MSR': self.msr,
'undefined': undefined,
illegal = False
name = 'setvl'
+ # and svremap not being supported by binutils (.long)
+ if asmop.startswith('svremap'):
+ illegal = False
+ name = 'svremap'
+
# sigh also deal with ffmadds not being supported by binutils (.long)
if asmop == 'ffmadds':
illegal = False
--- /dev/null
+from nmigen import Module, Signal
+from nmigen.back.pysim import Simulator, Delay, Settle
+from nmutil.formaltest import FHDLTestCase
+import unittest
+from openpower.decoder.isa.caller import ISACaller
+from openpower.decoder.power_decoder import (create_pdecode)
+from openpower.decoder.power_decoder2 import (PowerDecode2)
+from openpower.simulator.program import Program
+from openpower.decoder.isa.caller import ISACaller, SVP64State
+from openpower.decoder.selectable_int import SelectableInt
+from openpower.decoder.orderedset import OrderedSet
+from openpower.decoder.isa.all import ISA
+from openpower.decoder.isa.test_caller import Register, run_tst
+from openpower.sv.trans.svp64 import SVP64Asm
+from openpower.consts import SVP64CROffs
+from copy import deepcopy
+from openpower.decoder.helpers import fp64toselectable
+from openpower.decoder.isafunctions.double2single import DOUBLE2SINGLE
+
+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_remap(self):
+ """>>> lst = ["svremap 2, 2, 3, 0"
+ ]
+ """
+ lst = SVP64Asm(["svremap 2, 2, 3, 0"
+ ])
+ lst = list(lst)
+
+ fprs = [0] * 32
+ if False:
+ av = [7.0, -9.8, 2.0, -32.3] # first half of array 0..3
+ bv = [-2.0, 2.0, -9.8, 32.3] # second half of array 4..7
+ coe = [-1.0, 4.0, 3.1, 6.2] # coefficients
+ res = []
+ # work out the results with the twin mul/add-sub
+ for i, (a, b, c) in enumerate(zip(av, bv, coe)):
+ fprs[i+2] = fp64toselectable(a)
+ fprs[i+6] = fp64toselectable(b)
+ fprs[i+10] = fp64toselectable(c)
+ mul = a * c
+ t = a + mul
+ u = b - mul
+ t = DOUBLE2SINGLE(fp64toselectable(t)) # convert to Power single
+ u = DOUBLE2SINGLE(fp64toselectable(u)) # from double
+ res.append((t, u))
+ print ("FFT", i, "in", a, b, "coeff", c, "mul",
+ mul, "res", t, u)
+
+ # SVSTATE (in this case, VL=12, to cover all of matrix)
+ svstate = SVP64State()
+ svstate.vl[0:7] = 12 # VL
+ svstate.maxvl[0:7] = 12 # MAXVL
+ print ("SVSTATE", bin(svstate.spr.asint()))
+
+ with Program(lst, bigendian=False) as program:
+ sim = self.run_tst_program(program, svstate=svstate,
+ initial_fprs=fprs)
+ print ("spr svshape0", sim.spr['SVSHAPE0'])
+ print ("spr svshape1", sim.spr['SVSHAPE1'])
+ print ("spr svshape2", sim.spr['SVSHAPE2'])
+ print ("spr svshape3", sim.spr['SVSHAPE3'])
+ # confirm that the results are as expected
+ #for i, (t, u) in enumerate(res):
+ # self.assertEqual(sim.fpr(i+2), t)
+ # self.assertEqual(sim.fpr(i+6), u)
+
+ def run_tst_program(self, prog, initial_regs=None,
+ svstate=None,
+ initial_mem=None,
+ initial_fprs=None):
+ if initial_regs is None:
+ initial_regs = [0] * 32
+ simulator = run_tst(prog, initial_regs, mem=initial_mem,
+ initial_fprs=initial_fprs,
+ svstate=svstate)
+
+ print ("GPRs")
+ simulator.gpr.dump()
+ print ("FPRs")
+ simulator.fpr.dump()
+
+ return simulator
+
+
+if __name__ == "__main__":
+ unittest.main()
this saves drastically on the size of the regfile
"""
short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
+ 'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
'SPRG3'
}
if self.include_ca_in_write:
if name in ['CA', 'CA32']:
self.write_regs.add(name)
- if name in ['CR', 'LR', 'CTR', 'TAR', 'FPSCR', 'MSR', 'SVSTATE']:
+ if name in ['CR', 'LR', 'CTR', 'TAR', 'FPSCR', 'MSR',
+ 'SVSTATE', 'SVSHAPE0', 'SVSHAPE1', 'SVSHAPE2', 'SVSHAPE3']:
self.special_regs.add(name)
self.write_regs.add(name) # and add to list to write
p[0] = ast.Name(id=name, ctx=ast.Load())
yield ".long 0x%x" % insn
return
+ # and svremap
+ if opcode == 'svremap':
+ insn = 22 << (31-5) # opcode 22, bits 0-5
+ fields = list(map(int, fields))
+ insn |= fields[0] << (31-10) # SVxd , bits 6-10
+ insn |= fields[1] << (31-15) # SVyd , bits 11-15
+ insn |= fields[2] << (31-16) # SVzd , bits 16-20
+ insn |= fields[3] << (31-21) # SVRM , bits 21-25
+ insn |= 0b00001 << (31-30) # XO , bits 26..30
+ log ("svremap", bin(insn))
+ yield ".long 0x%x" % insn
+ return
+
# identify if is a svp64 mnemonic
if not opcode.startswith('sv.'):
yield insn # unaltered
for line in lines:
ls = line.split("#")
# identify macros
- if ls[0].strip().startswith("setvl"):
+ op = ls[0].strip()
+ if op.startswith("setvl") or op.startswith("svremap"):
ws, line = get_ws(ls[0])
lst = list(isa.translate_one(ls[0].strip(), macros))
lst = '; '.join(lst)
#'sv.lhzbr 5.v, 11(9.v), 15',
#'sv.lwzbr 5.v, 11(9.v), 15',
'sv.ffmadds 6.v, 2.v, 4.v, 6.v',
+ 'svremap 2, 2, 3, 0',
]
isa = SVP64Asm(lst, macros=macros)
print ("list", list(isa))