converted test_caller_svp64_fp.py to new reg format
[openpower-isa.git] / src / openpower / decoder / isa / test_caller_svp64_fp.py
1 from nmigen import Module, Signal
2 from nmigen.back.pysim import Simulator, Delay, Settle
3 from nmutil.formaltest import FHDLTestCase
4 import unittest
5 from openpower.decoder.isa.caller import ISACaller
6 from openpower.decoder.power_decoder import (create_pdecode)
7 from openpower.decoder.power_decoder2 import (PowerDecode2)
8 from openpower.simulator.program import Program
9 from openpower.decoder.isa.caller import ISACaller, SVP64State
10 from openpower.decoder.selectable_int import SelectableInt
11 from openpower.decoder.orderedset import OrderedSet
12 from openpower.decoder.isa.all import ISA
13 from openpower.decoder.isa.test_caller import Register, run_tst
14 from openpower.sv.trans.svp64 import SVP64Asm
15 from openpower.consts import SVP64CROffs
16 from copy import deepcopy
17
18
19 class DecoderTestCase(FHDLTestCase):
20
21 def _check_regs(self, sim, expected):
22 for i in range(32):
23 self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
24
25 def test_sv_fpload(self):
26 """>>> lst = ["sv.lfsx *2, 0, *0"
27 ]
28 """
29 lst = SVP64Asm(["sv.lfsx *2, 0, *0"
30 ])
31 lst = list(lst)
32
33 # SVSTATE (in this case, VL=2)
34 svstate = SVP64State()
35 svstate.vl = 2 # VL
36 svstate.maxvl = 2 # MAXVL
37 print ("SVSTATE", bin(svstate.asint()))
38
39 # memory addresses 0x0000 and 0x0008
40 initial_mem = {0x0000: (0x42013333, 8), # 32.3
41 0x0008: (0xC0200000, 8), # -2.5
42 }
43
44 # and RB will move on from 0 for first iteration to 1 in 2nd
45 # therefore we must point GPR(0) at initial mem 0x0000
46 # and GPR(1) at initial mem 0x0008
47 initial_regs = [0] * 32
48 initial_regs[0] = 0x0000 # points at memory address 0x0000 (element 0)
49 initial_regs[1] = 0x0008 # points at memory address 0x0008 (element 1)
50
51 with Program(lst, bigendian=False) as program:
52 sim = self.run_tst_program(program, initial_regs,
53 svstate=svstate,
54 initial_mem=initial_mem)
55 print(sim.fpr(2))
56 print(sim.fpr(3))
57 self.assertEqual(sim.fpr(2), SelectableInt(0x4040266660000000, 64))
58 self.assertEqual(sim.fpr(3), SelectableInt(0xC004000000000000, 64))
59
60 def test_fp_single_ldst(self):
61 """>>> lst = ["sv.lfsx *0, 0, *4", # load fp 1/2 from mem 0/8
62 "sv.stfsu *0, 16(*4)", # store fp 1/2, update RA *twice*
63 "sv.lfs *2, 0(*4)", # re-load from UPDATED r4/r5
64 ]
65
66 This is quite an involved (deceptively simple looking) test.
67 The sv.stfsu is creating a *Vector* of Effective Addresses, and
68 consequently is updating (writing) a *Vector* of EAs into the GPR.
69
70 Walkthrough:
71
72 1) sv.lfsx *0, 0, *4 VL=2 so there are *two* lfsx operations
73 lfsx 0, 0, 4 loads from MEM[GPR(4)], stores in FPR(0)
74 lfsx 1, 0, 5 loads from MEM[GPR(5)], stores in FPR(1)
75
76 2) sv.stfsu *0, 16(*4) again, VL=2 so there are two ST-FP-update ops
77 stfsu 0, 16(4) EA=GPR(4)+16, FPR(0) to MEM[EA], EA to GPR(4)
78 stfsu 1, 16(5) EA=GPR(5)+16, FPR(0) to MEM[EA], EA to GPR(5)
79
80 note that there are **TWO** FP writes to memory, and **TWO**
81 writes of the calculated Effective Address to GPR, in regs 4 and 5
82 GPRs 4 and 5 are *overwritten*.
83
84 3) sv.lfs *3, 0(*4) VL=2, so two immediate-LDs
85 lfs 3, 0(4) EA=GPR(4)+0, FPR(3) = MEM[EA]
86 lfs 4, 0(5) EA=GPR(5)+0, FPR(4) = MEM[EA]
87
88 here we have loaded from the *overwritten* GPRs 4 and 5.
89
90 strictly speaking this unit test should also verify the contents
91 of the memory locations 0x10 and 0x18, which should contain the
92 single-precision FP numbers in the bottom 4 bytes. TODO
93 """
94 lst = SVP64Asm(["sv.lfsx *0, 0, *4",
95 "sv.stfsu *0, 16(*4)",
96 "sv.lfs *2, 0(*4)",
97 ])
98 lst = list(lst)
99
100 # SVSTATE (in this case, VL=2)
101 svstate = SVP64State()
102 svstate.vl = 2 # VL
103 svstate.maxvl = 2 # MAXVL
104 print ("SVSTATE", bin(svstate.asint()))
105
106 # memory addresses 0x0000 and 0x0008
107 initial_mem = {0x0000: (0x42013333, 8), # 32.3
108 0x0008: (0xC0200000, 8), # -2.5
109 0x0020: (0x1828384822324252, 8),
110 }
111
112 # and RB will move on from 0 for first iteration to 1 in 2nd
113 # therefore we must point GPR(4) at initial mem 0x0000
114 # and GPR(5) at initial mem 0x0008
115 initial_regs = [0] * 32
116 initial_regs[4] = 0x0000 # points at memory address 0x0000 (element 0)
117 initial_regs[5] = 0x0008 # points at memory address 0x0008 (element 1)
118
119 with Program(lst, bigendian=False) as program:
120 sim = self.run_tst_program(program, initial_regs,
121 svstate=svstate,
122 initial_mem=initial_mem)
123 print("FPR 1", sim.fpr(0))
124 print("FPR 2", sim.fpr(1))
125 print("GPR 1", sim.gpr(4)) # should be 0x10 due to update
126 print("GPR 2", sim.gpr(5)) # should be 0x18 due to update
127 self.assertEqual(sim.gpr(4), SelectableInt(0x10, 64))
128 self.assertEqual(sim.gpr(5), SelectableInt(0x18, 64))
129 self.assertEqual(sim.fpr(0), SelectableInt(0x4040266660000000, 64))
130 self.assertEqual(sim.fpr(1), SelectableInt(0xC004000000000000, 64))
131 self.assertEqual(sim.fpr(2), SelectableInt(0x4040266660000000, 64))
132 self.assertEqual(sim.fpr(3), SelectableInt(0xC004000000000000, 64))
133
134 def test_sv_fpadd(self):
135 """>>> lst = ["sv.fadds *6, *2, *4"
136 ]
137 """
138 lst = SVP64Asm(["sv.fadds *6, *2, *4"
139 ])
140 lst = list(lst)
141
142 fprs = [0] * 32
143 fprs[2] = 0xC040266660000000 # -32.3
144 fprs[3] = 0xC040266660000000 # -32.3
145 fprs[4] = 0x4040266660000000 # +32.3
146 fprs[5] = 0xC040266660000000 # -32.3
147
148 # SVSTATE (in this case, VL=2)
149 svstate = SVP64State()
150 svstate.vl = 2 # VL
151 svstate.maxvl = 2 # MAXVL
152 print ("SVSTATE", bin(svstate.asint()))
153
154 with Program(lst, bigendian=False) as program:
155 sim = self.run_tst_program(program, svstate=svstate,
156 initial_fprs=fprs)
157 self.assertEqual(sim.fpr(6), SelectableInt(0x0, 64))
158 self.assertEqual(sim.fpr(7), SelectableInt(0xc050266660000000, 64))
159
160 def test_sv_fpmadds(self):
161 """>>> lst = ["sv.fmadds *6, *2, *4, 8"
162 ]
163 two vector mul-adds with a scalar in f8
164 * fp6 = fp2 * fp4 + f8 = 7.0 * 2.0 - 2.0 = 12.0
165 * fp7 = fp3 * fp5 + f8 = 7.0 * 2.0 - 2.0 = 12.0
166 """
167 lst = SVP64Asm(["sv.fmadds *6, *2, *4, 8"
168 ])
169 lst = list(lst)
170
171 fprs = [0] * 32
172 fprs[2] = 0x401C000000000000 # 7.0
173 fprs[3] = 0xC02399999999999A # -9.8
174 fprs[4] = 0x4000000000000000 # 2.0
175 fprs[5] = 0xC040266660000000 # -32.3
176 fprs[6] = 0x4000000000000000 # 2.0
177 fprs[7] = 0x4000000000000000 # 2.0
178 fprs[8] = 0xc000000000000000 # -2.0
179
180 # SVSTATE (in this case, VL=2)
181 svstate = SVP64State()
182 svstate.vl = 2 # VL
183 svstate.maxvl = 2 # MAXVL
184 print ("SVSTATE", bin(svstate.asint()))
185
186 with Program(lst, bigendian=False) as program:
187 sim = self.run_tst_program(program, svstate=svstate,
188 initial_fprs=fprs)
189 self.assertEqual(sim.fpr(6), SelectableInt(0x4028000000000000, 64))
190 self.assertEqual(sim.fpr(7), SelectableInt(0x4073a8a3c0000000, 64))
191
192 def run_tst_program(self, prog, initial_regs=None,
193 svstate=None,
194 initial_mem=None,
195 initial_fprs=None):
196 if initial_regs is None:
197 initial_regs = [0] * 32
198 simulator = run_tst(prog, initial_regs, mem=initial_mem,
199 initial_fprs=initial_fprs,
200 svstate=svstate)
201
202 print ("GPRs")
203 simulator.gpr.dump()
204 print ("FPRs")
205 simulator.fpr.dump()
206
207 return simulator
208
209
210 if __name__ == "__main__":
211 unittest.main()