76138dc483a45d98a5a572ddbfaedad8b3b8f3b8
2 from copy
import deepcopy
4 from nmutil
.formaltest
import FHDLTestCase
5 from openpower
.decoder
.helpers
import fp64toselectable
6 from openpower
.decoder
.isa
.caller
import SVP64State
7 from openpower
.decoder
.isa
.remap_dct_yield
import halfrev2
, reverse_bits
8 from openpower
.decoder
.isa
.test_caller
import run_tst
9 from openpower
.decoder
.selectable_int
import SelectableInt
10 from openpower
.simulator
.program
import Program
11 from openpower
.insndb
.asm
import SVP64Asm
14 def write_byte(mem
, addr
, val
):
15 addr
, offs
= (addr
// 8)*8, (addr
% 8)*8
17 value
= mem
.get(addr
, 0) & ~mask
18 value
= value |
(val
<< offs
)
19 mem
[addr
] = value
& 0xffff_ffff_ffff_ffff
22 class DecoderTestCase(FHDLTestCase
):
24 def _check_regs(self
, sim
, expected
):
26 self
.assertEqual(sim
.gpr(i
), SelectableInt(expected
[i
], 64))
28 def _check_fpregs(self
, sim
, expected
):
30 self
.assertEqual(sim
.fpr(i
), SelectableInt(expected
[i
], 64))
32 def test_sv_load_store_strncpy(self
):
36 strncpy using post-increment ld/st, sv.bc, and data-dependent ffirst.
37 note that /lf (Load-Fault) mode is not set in this example when it
38 should be. however implementing Load-Fault in ISACaller is tricky
39 (requires implementing multiple hardware models)
44 "mtspr 9, 3", # move r3 to CTR
45 "addi 0,0,0", # initialise r0 to zero
46 # chr-copy loop starts here:
47 # for (i = 0; i < n && src[i] != '\0'; i++)
49 # VL (and r1) = MIN(CTR,MAXVL=4)
50 "setvl 1,0,%d,0,1,1" % maxvl
,
51 # load VL bytes (update r10 addr)
52 "sv.lbzu/pi *16, 1(10)", # should be /lf here as well
53 "sv.cmpi/ff=eq/vli *0,1,*16,0", # cmp against zero, truncate VL
54 # store VL bytes (update r12 addr)
55 "sv.stbu/pi *16, 1(12)",
56 "sv.bc/all 0, *2, -0x1c", # test CTR, stop if cmpi failed
57 # zeroing loop starts here:
60 # VL (and r1) = MIN(CTR,MAXVL=4)
61 "setvl 1,0,%d,0,1,1" % maxvl
,
62 # store VL zeros (update r12 addr)
63 "sv.stbu/pi 0, 1(12)",
64 "sv.bc 16, *0, -0xc", # dec CTR by VL, stop at zero
69 tst_string
= "hello\x00bye\x00"
70 initial_regs
= [0] * 32
71 initial_regs
[3] = len(tst_string
) # including the zero
72 initial_regs
[10] = 16 # load address
73 initial_regs
[12] = 40 # store address
75 # some memory with identifying garbage in it
76 initial_mem
= {16: 0xf0f1_f2f3_f4f5_f6f7,
77 24: 0x4041_4243_4445_4647,
78 40: 0x8081_8283_8485_8687,
79 48: 0x9091_9293_9495_9697,
82 for i
, c
in enumerate(tst_string
):
83 write_byte(initial_mem
, 16+i
, ord(c
))
85 # now get the expected results: copy the string to the other address,
86 # but terminate at first zero (strncpy, duh)
87 expected_mem
= deepcopy(initial_mem
)
90 for i
, c
in enumerate(tst_string
):
93 write_byte(expected_mem
, 40+i
, c
)
96 write_byte(expected_mem
, 40+i
, 0)
100 with
Program(lst
, bigendian
=False) as program
:
101 sim
= self
.run_tst_program(program
, initial_mem
=initial_mem
,
102 initial_regs
=initial_regs
)
103 mem
= sim
.mem
.dump(printout
=True, asciidump
=True)
105 # contents of memory expected at:
106 # element 0: r1=0x10, D=24, => EA = 0x10+24*0 = 16 (0x10)
107 # element 1: r1=0x10, D=24, => EA = 0x10+24*1 = 40 (0x28)
108 # therefore, at address 0x10 ==> 0x1234
109 # therefore, at address 0x28 ==> 0x1235
110 for (k
, val
) in expected_mem
.items():
111 print("mem, val", k
, hex(val
))
112 self
.assertEqual(mem
, list(expected_mem
.items()))
114 # reg 10 (the LD EA) is expected to be nearest
115 # 16 + strlen, rounded up
116 rounded
= ((strlen
+maxvl
-1) // maxvl
) * maxvl
117 self
.assertEqual(sim
.gpr(10), SelectableInt(16+rounded
, 64))
118 # whereas reg 10 (the ST EA) is expected to be 40+strlen
119 self
.assertEqual(sim
.gpr(12), SelectableInt(
120 40+len(tst_string
), 64))
122 def test_sv_load_store_postinc(self
):
123 """>>> lst = ["addi 20, 0, 0x0010",
127 "sv.stwu/pi *4, 24(20)",
128 "sv.lwu/pi *8, 24(20)"]
130 element stride is computed as:
132 EA = (RA|0) + EXTS(D) * i
134 load-update with post-increment will do this however:
137 EA = (RA|0) + EXTS(D)
138 RA = EA # update RA *after*
140 whereas without post-increment it would be:
142 EA = (RA|0) + EXTS(D) # EA calculated (and used) *BEFORE* load
144 RA = EA # still updated after but it's used before
146 lst
= SVP64Asm(["addi 20, 0, 0x0010",
147 "addi 22, 0, 0x0010",
151 "sv.stwu/pi *4, 24(22)", # scalar r22 += 24 on update
152 "sv.lwzu/pi *8, 24(20)" # scalar r20 += 24 on update
156 # SVSTATE (in this case, VL=2)
157 svstate
= SVP64State()
159 svstate
.maxvl
= 2 # MAXVL
160 print("SVSTATE", bin(svstate
.asint()))
162 with
Program(lst
, bigendian
=False) as program
:
163 sim
= self
.run_tst_program(program
, svstate
=svstate
)
164 mem
= sim
.mem
.dump(printout
=False)
166 # contents of memory expected at:
167 # element 0: r1=0x10, D=24, => EA = 0x10+24*0 = 16 (0x10)
168 # element 1: r1=0x10, D=24, => EA = 0x10+24*1 = 40 (0x28)
169 # therefore, at address 0x10 ==> 0x1234
170 # therefore, at address 0x28 ==> 0x1235
171 expected_mem
= [(16, 0x1234),
173 self
.assertEqual(mem
, expected_mem
)
175 self
.assertEqual(sim
.gpr(8), SelectableInt(0x1234, 64))
176 self
.assertEqual(sim
.gpr(9), SelectableInt(0x1235, 64))
177 # reg 20 (the EA) is expected to be the initial 16,
178 # plus 2x24 (2 lots of immediates). 16+2*24=64
179 self
.assertEqual(sim
.gpr(20), SelectableInt(64, 64))
180 # likewise, reg 22 - for the store - also 16+2*24.
181 self
.assertEqual(sim
.gpr(22), SelectableInt(64, 64))
183 def test_sv_load_store_elementstride(self
):
184 """>>> lst = ["addi 2, 0, 0x0010",
188 "sv.stw/els *4, 16(2)",
189 "sv.lwz/els *8, 16(2)"]
191 note: element stride mode is only enabled when RA is a scalar
192 and when the immediate is non-zero
194 element stride is computed as:
196 EA = (RA|0) + EXTS(D) * i
198 lst
= SVP64Asm(["addi 2, 0, 0x0010",
202 "sv.stw/els *4, 24(2)", # scalar r1 + 16 + 24*offs
203 "sv.lwz/els *8, 24(2)"]) # scalar r1 + 16 + 24*offs
206 # SVSTATE (in this case, VL=2)
207 svstate
= SVP64State()
209 svstate
.maxvl
= 2 # MAXVL
210 print("SVSTATE", bin(svstate
.asint()))
212 with
Program(lst
, bigendian
=False) as program
:
213 sim
= self
.run_tst_program(program
, svstate
=svstate
)
214 mem
= sim
.mem
.dump(printout
=False)
216 # contents of memory expected at:
217 # element 0: r1=0x10, D=24, => EA = 0x10+24*0 = 16 (0x10)
218 # element 1: r1=0x10, D=24, => EA = 0x10+24*1 = 40 (0x28)
219 # therefore, at address 0x10 ==> 0x1234
220 # therefore, at address 0x28 ==> 0x1235
221 expected_mem
= [(16, 0x1234),
223 self
.assertEqual(mem
, expected_mem
)
225 self
.assertEqual(sim
.gpr(8), SelectableInt(0x1234, 64))
226 self
.assertEqual(sim
.gpr(9), SelectableInt(0x1235, 64))
228 def test_sv_load_store_unitstride(self
):
229 """>>> lst = ["addi 1, 0, 0x0010",
236 note: unit stride mode is only enabled when RA is a scalar.
238 unit stride is computed as:
240 EA = (RA|0) + EXTS(D) + LDSTsize * i
241 where for stw and lwz, LDSTsize is 4 because it is 32-bit words
243 lst
= SVP64Asm(["addi 1, 0, 0x0010",
247 "sv.stw *8, 8(1)", # scalar r1 + 8 + wordlen*offs
248 "sv.lwz *12, 8(1)"]) # scalar r1 + 8 + wordlen*offs
251 # SVSTATE (in this case, VL=2)
252 svstate
= SVP64State()
254 svstate
.maxvl
= 2 # MAXVL
255 print("SVSTATE", bin(svstate
.asint()))
257 with
Program(lst
, bigendian
=False) as program
:
258 sim
= self
.run_tst_program(program
, svstate
=svstate
)
259 mem
= sim
.mem
.dump(printout
=False)
262 # contents of memory expected at:
263 # element 0: r1=0x10, D=8, wordlen=4 => EA = 0x10+8+4*0 = 0x24
264 # element 1: r1=0x10, D=8, wordlen=4 => EA = 0x10+8+4*8 = 0x28
265 # therefore, at address 0x24 ==> 0x1234
266 # therefore, at address 0x28 ==> 0x1235
267 self
.assertEqual(mem
, [(24, 0x123500001234)])
269 self
.assertEqual(sim
.gpr(12), SelectableInt(0x1234, 64))
270 self
.assertEqual(sim
.gpr(13), SelectableInt(0x1235, 64))
272 @unittest.skip("deprecated, needs Scalar LDST-shifted")
273 def test_sv_load_store_shifted(self
):
274 """>>> lst = ["addi 1, 0, 0x0010",
282 "sv.lwzsh *12, 4(1), 2"]
284 shifted LD is computed as:
286 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
288 lst
= SVP64Asm(["addi 1, 0, 0x0010",
294 "sv.stw *4, 0(1)", # scalar r1 + 0 + wordlen*offs
295 "sv.lwzsh *12, 4(1), 2"]) # bit-reversed
298 # SVSTATE (in this case, VL=4)
299 svstate
= SVP64State()
301 svstate
.maxvl
= 4 # MAXVL
302 print("SVSTATE", bin(svstate
.asint()))
304 with
Program(lst
, bigendian
=False) as program
:
305 sim
= self
.run_tst_program(program
, svstate
=svstate
)
306 mem
= sim
.mem
.dump(printout
=False)
309 self
.assertEqual(mem
, [(16, 0x020200000101),
310 (24, 0x040400000303)])
313 self
.assertEqual(sim
.gpr(4), SelectableInt(0x101, 64))
314 self
.assertEqual(sim
.gpr(5), SelectableInt(0x202, 64))
315 self
.assertEqual(sim
.gpr(6), SelectableInt(0x303, 64))
316 self
.assertEqual(sim
.gpr(7), SelectableInt(0x404, 64))
317 # r1=0x10, RC=0, offs=4: contents of memory expected at:
318 # element 0: EA = r1 + 0b00*4 => 0x10 + 0b00*4 => 0x10
319 # element 1: EA = r1 + 0b01*4 => 0x10 + 0b01*4 => 0x18
320 # element 2: EA = r1 + 0b10*4 => 0x10 + 0b10*4 => 0x14
321 # element 3: EA = r1 + 0b11*4 => 0x10 + 0b11*4 => 0x1c
322 # therefore loaded from (bit-reversed indexing):
323 # r9 => mem[0x10] which was stored from r5
324 # r10 => mem[0x18] which was stored from r6
325 # r11 => mem[0x18] which was stored from r7
326 # r12 => mem[0x1c] which was stored from r8
327 self
.assertEqual(sim
.gpr(12), SelectableInt(0x101, 64))
328 self
.assertEqual(sim
.gpr(13), SelectableInt(0x202, 64))
329 self
.assertEqual(sim
.gpr(14), SelectableInt(0x303, 64))
330 self
.assertEqual(sim
.gpr(15), SelectableInt(0x404, 64))
332 @unittest.skip("deprecated, needs Scalar LDST-shifted")
333 def test_sv_load_store_shifted_fp(self
):
334 """>>> lst = ["addi 1, 0, 0x0010",
342 "sv.lfdbr *12, 4(1), 2"]
344 shifted LD is computed as:
346 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
348 lst
= SVP64Asm(["addi 1, 0, 0x0010",
354 "sv.std *4, 0(1)", # scalar r1 + 0 + wordlen*offs
355 "sv.lfdsh *12, 8(1), 2"]) # shifted
358 # SVSTATE (in this case, VL=4)
359 svstate
= SVP64State()
361 svstate
.maxvl
= 4 # MAXVL
362 print("SVSTATE", bin(svstate
.asint()))
366 with
Program(lst
, bigendian
=False) as program
:
367 sim
= self
.run_tst_program(program
, svstate
=svstate
,
369 mem
= sim
.mem
.dump(printout
=False)
372 self
.assertEqual(mem
, [(16, 0x101),
379 self
.assertEqual(sim
.gpr(4), SelectableInt(0x101, 64))
380 self
.assertEqual(sim
.gpr(5), SelectableInt(0x202, 64))
381 self
.assertEqual(sim
.gpr(6), SelectableInt(0x303, 64))
382 self
.assertEqual(sim
.gpr(7), SelectableInt(0x404, 64))
383 # r1=0x10, RC=0, offs=4: contents of memory expected at:
384 # element 0: EA = r1 + bitrev(0b00)*4 => 0x10 + 0b00*4 => 0x10
385 # element 1: EA = r1 + bitrev(0b01)*4 => 0x10 + 0b10*4 => 0x18
386 # element 2: EA = r1 + bitrev(0b10)*4 => 0x10 + 0b01*4 => 0x14
387 # element 3: EA = r1 + bitrev(0b11)*4 => 0x10 + 0b10*4 => 0x1c
388 # therefore loaded from (bit-reversed indexing):
389 # r9 => mem[0x10] which was stored from r5
390 # r10 => mem[0x18] which was stored from r6
391 # r11 => mem[0x18] which was stored from r7
392 # r12 => mem[0x1c] which was stored from r8
393 self
.assertEqual(sim
.fpr(12), SelectableInt(0x101, 64))
394 self
.assertEqual(sim
.fpr(13), SelectableInt(0x202, 64))
395 self
.assertEqual(sim
.fpr(14), SelectableInt(0x303, 64))
396 self
.assertEqual(sim
.fpr(15), SelectableInt(0x404, 64))
398 @unittest.skip("deprecated, needs Scalar LDST-shifted")
399 def test_sv_load_store_shifted2(self
):
400 """>>> lst = ["addi 1, 0, 0x0010",
404 "sv.lfssh *12, 4(1), 2"]
406 shifted LD is computed as:
408 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
411 lst
= SVP64Asm(["addi 1, 0, 0x0010",
413 "sv.stfs *4, 0(1)", # scalar r1 + 0 + wordlen*offs
414 "sv.lfssh *12, 4(1), 2"]) # shifted (by zero, but hey)
417 # SVSTATE (in this case, VL=4)
418 svstate
= SVP64State()
420 svstate
.maxvl
= 4 # MAXVL
421 print("SVSTATE", bin(svstate
.asint()))
426 fprs
[4] = fp64toselectable(1.0)
427 fprs
[5] = fp64toselectable(2.0)
428 fprs
[6] = fp64toselectable(3.0)
429 fprs
[7] = fp64toselectable(4.0)
431 # expected results, remember that bit-reversed load has been done
432 expected_fprs
= deepcopy(fprs
)
433 expected_fprs
[12] = fprs
[4] # 0b00 -> 0b00
434 expected_fprs
[13] = fprs
[5] # 0b10 -> 0b01
435 expected_fprs
[14] = fprs
[6] # 0b01 -> 0b10
436 expected_fprs
[15] = fprs
[7] # 0b11 -> 0b11
438 with
Program(lst
, bigendian
=False) as program
:
439 sim
= self
.run_tst_program(program
, svstate
=svstate
,
441 mem
= sim
.mem
.dump(printout
=False)
448 # self.assertEqual(mem, [(16, 0x020200000101),
449 # (24, 0x040400000303)])
450 self
._check
_fpregs
(sim
, expected_fprs
)
452 def test_sv_load_store_remap_matrix(self
):
453 """>>> lst = ["addi 1, 0, 0x0010",
460 "sv.stw *4, 0(1)", # scalar r1 + 0 + wordlen*offs
461 "svshape 3, 3, 4, 0, 0",
462 "svremap 1, 1, 2, 0, 0, 0, 0",
466 REMAPed a LD operation via a Matrix Multiply Schedule,
467 which is set up as 3x4 result
469 lst
= SVP64Asm(["addi 1, 0, 0x0010",
486 "sv.stw *4, 0(1)", # scalar r1 + 0 + wordlen*offs
487 "svshape 3, 3, 4, 0, 0",
488 "svremap 1, 1, 2, 0, 0, 0, 0",
493 # SVSTATE (in this case, VL=4)
494 svstate
= SVP64State()
496 svstate
.maxvl
= 12 # MAXVL
497 print("SVSTATE", bin(svstate
.asint()))
501 with
Program(lst
, bigendian
=False) as program
:
502 sim
= self
.run_tst_program(program
, svstate
=svstate
,
504 mem
= sim
.mem
.dump(printout
=False)
508 self
.assertEqual(mem
, [(16, 0x020200000101),
509 (24, 0x040400000303),
510 (32, 0x060600000505),
511 (40, 0x080800000707),
512 (48, 0x0a0a00000909),
513 (56, 0x0c0c00000b0b)])
516 self
.assertEqual(sim
.gpr(4), SelectableInt(0x101, 64))
517 self
.assertEqual(sim
.gpr(5), SelectableInt(0x202, 64))
518 self
.assertEqual(sim
.gpr(6), SelectableInt(0x303, 64))
519 self
.assertEqual(sim
.gpr(7), SelectableInt(0x404, 64))
520 self
.assertEqual(sim
.gpr(8), SelectableInt(0x505, 64))
521 self
.assertEqual(sim
.gpr(9), SelectableInt(0x606, 64))
522 self
.assertEqual(sim
.gpr(10), SelectableInt(0x707, 64))
523 self
.assertEqual(sim
.gpr(11), SelectableInt(0x808, 64))
524 # combination of bit-reversed load with a Matrix REMAP
527 self
.assertEqual(sim
.gpr(20+i
), SelectableInt(0x101, 64))
528 self
.assertEqual(sim
.gpr(23+i
), SelectableInt(0x505, 64))
529 self
.assertEqual(sim
.gpr(26+i
), SelectableInt(0x909, 64))
530 self
.assertEqual(sim
.gpr(29+i
), SelectableInt(0x202, 64))
532 def test_sv_load_store_bitreverse_remap_halfswap(self
):
533 """>>> lst = ["addi 1, 0, 0x0010",
544 "svshape 8, 1, 1, 6, 0",
545 "svremap 31, 1, 2, 3, 0, 0, 0",
546 "sv.lwz/els *12, 4(1)"]
548 shifted LD is computed as:
550 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
552 bitreversal of 0 1 2 3 in binary 0b00 0b01 0b10 0b11
553 produces 0 2 1 3 in binary 0b00 0b10 0b01 0b11
555 and thus creates the butterfly needed for one iteration of FFT.
556 the RC (shift) is to be able to offset the LDs by Radix-2 spans
558 on top of the bit-reversal is a REMAP for half-swaps for DCT
561 lst
= SVP64Asm(["addi 1, 0, 0x0010",
571 "sv.stw *4, 0(1)", # scalar r1 + 0 + wordlen*offs
572 "svshape 8, 1, 1, 6, 0",
573 "svremap 1, 0, 0, 0, 0, 0, 0",
574 #"setvl 0, 0, 8, 0, 1, 1",
575 "sv.lwz/els *12, 4(1)",
580 # SVSTATE (in this case, VL=4)
581 svstate
= SVP64State()
583 svstate
.maxvl
= 8 # MAXVL
584 print("SVSTATE", bin(svstate
.asint()))
588 avi
= [0x001, 0x102, 0x203, 0x304, 0x405, 0x506, 0x607, 0x708]
590 levels
= n
.bit_length() - 1
592 ri
= [ri
[reverse_bits(i
, levels
)] for i
in range(n
)]
593 av
= halfrev2(avi
, False)
594 av
= [av
[ri
[i
]] for i
in range(n
)]
596 with
Program(lst
, bigendian
=False) as program
:
597 sim
= self
.run_tst_program(program
, svstate
=svstate
,
599 mem
= sim
.mem
.dump(printout
=False)
603 self
.assertEqual(mem
, [(16, 0x010200000001),
604 (24, 0x030400000203),
605 (32, 0x050600000405),
606 (40, 0x070800000607)])
608 for i
in range(len(avi
)):
609 print("st gpr", i
, sim
.gpr(i
+4), hex(avi
[i
]))
610 for i
in range(len(avi
)):
611 self
.assertEqual(sim
.gpr(i
+4), avi
[i
])
612 # combination of bit-reversed load with a DCT half-swap REMAP
614 for i
in range(len(avi
)):
615 print("ld gpr", i
, sim
.gpr(i
+12), hex(av
[i
]))
616 for i
in range(len(avi
)):
617 self
.assertEqual(sim
.gpr(i
+12), av
[i
])
619 def test_sv_load_store_bitreverse_remap_halfswap_idct(self
):
620 """>>> lst = ["addi 1, 0, 0x0010",
631 "svshape 8, 1, 1, 6, 0",
632 "svremap 31, 1, 2, 3, 0, 0, 0",
633 "sv.lwz/els *12, 4(1)"]
635 bitreverse LD is computed as:
637 EA = (RA|0) + (EXTS(D) * LDSTsize * i) << RC
639 bitreversal of 0 1 2 3 in binary 0b00 0b01 0b10 0b11
640 produces 0 2 1 3 in binary 0b00 0b10 0b01 0b11
642 and thus creates the butterfly needed for one iteration of FFT.
643 the RC (shift) is to be able to offset the LDs by Radix-2 spans
645 on top of the bit-reversal is a REMAP for half-swaps for DCT
648 lst
= SVP64Asm(["addi 1, 0, 0x0010",
658 "sv.stw *4, 0(1)", # scalar r1 + 0 + wordlen*offs
659 "svshape 8, 1, 1, 14, 0",
660 "svremap 16, 0, 0, 0, 0, 0, 0",
661 #"setvl 0, 0, 8, 0, 1, 1",
662 "sv.lwz/els *12, 4(1)",
667 # SVSTATE (in this case, VL=4)
668 svstate
= SVP64State()
670 svstate
.maxvl
= 8 # MAXVL
671 print("SVSTATE", bin(svstate
.asint()))
675 avi
= [0x001, 0x102, 0x203, 0x304, 0x405, 0x506, 0x607, 0x708]
677 levels
= n
.bit_length() - 1
679 ri
= [ri
[reverse_bits(i
, levels
)] for i
in range(n
)]
680 av
= [avi
[ri
[i
]] for i
in range(n
)]
681 av
= halfrev2(av
, True)
683 with
Program(lst
, bigendian
=False) as program
:
684 sim
= self
.run_tst_program(program
, svstate
=svstate
,
686 mem
= sim
.mem
.dump(printout
=False)
690 self
.assertEqual(mem
, [(16, 0x010200000001),
691 (24, 0x030400000203),
692 (32, 0x050600000405),
693 (40, 0x070800000607)])
695 for i
in range(len(avi
)):
696 print("st gpr", i
, sim
.gpr(i
+4), hex(avi
[i
]))
697 for i
in range(len(avi
)):
698 self
.assertEqual(sim
.gpr(i
+4), avi
[i
])
699 # combination of bit-reversed load with a DCT half-swap REMAP
701 for i
in range(len(avi
)):
702 print("ld gpr", i
, sim
.gpr(i
+12), hex(av
[i
]))
703 for i
in range(len(avi
)):
704 self
.assertEqual(sim
.gpr(i
+12), av
[i
])
706 def test_sv_load_dd_ffirst_excl(self
):
707 """data-dependent fail-first on LD/ST, exclusive (VLi=0)
711 # load VL bytes but test if they are zero and truncate
712 "sv.lbz/ff=RC1 *16, 1(10)", # deliberately offset by 1
717 # SVSTATE (in this case, VL=8)
718 svstate
= SVP64State()
720 svstate
.maxvl
= 8 # MAXVL
721 print("SVSTATE", bin(svstate
.asint()))
723 tst_string
= "hel\x00e\x00"
724 initial_regs
= [0] * 32
725 initial_regs
[3] = len(tst_string
) # including the zero
726 initial_regs
[10] = 16 # load address
727 initial_regs
[12] = 40 # store address
728 for i
in range(8): # set to garbage
729 initial_regs
[16+i
] = (0xbeef00) + i
# identifying garbage
731 # calculate expected regs
732 expected_regs
= deepcopy(initial_regs
)
733 for i
, c
in enumerate(tst_string
[1:]): # note the offset 1(10)
735 if c
== 0: break # strcpy stop at NUL
736 expected_regs
[16+i
] = c
738 # some memory with identifying garbage in it
739 initial_mem
= {16: 0xf0f1_f2f3_f4f5_f6f7,
740 24: 0x4041_4243_4445_4647,
741 40: 0x8081_8283_8485_8687,
742 48: 0x9091_9293_9495_9697,
745 for i
, c
in enumerate(tst_string
):
746 write_byte(initial_mem
, 16+i
, ord(c
))
748 with
Program(lst
, bigendian
=False) as program
:
749 sim
= self
.run_tst_program(program
, svstate
=svstate
,
750 initial_mem
=initial_mem
,
751 initial_regs
=initial_regs
)
752 mem
= sim
.mem
.dump(printout
=True, asciidump
=True)
754 self
.assertEqual(sim
.svstate
.vl
, 2)
755 for i
in range(len(expected_regs
)):
756 print ("%i %x %x" % (i
, sim
.gpr(i
).value
, expected_regs
[i
]))
757 self
.assertEqual(sim
.gpr(i
), expected_regs
[i
])
759 def test_sv_load_dd_ffirst_incl(self
):
760 """data-dependent fail-first on LD/ST, inclusive (/vli)
764 # load VL bytes but test if they are zero and truncate
765 "sv.lbz/ff=RC1/vli *16, 1(10)", # deliberately offset by 1
770 # SVSTATE (in this case, VL=8)
771 svstate
= SVP64State()
773 svstate
.maxvl
= 8 # MAXVL
774 print("SVSTATE", bin(svstate
.asint()))
776 tst_string
= "hel\x00e\x00"
777 initial_regs
= [0] * 32
778 initial_regs
[3] = len(tst_string
) # including the zero
779 initial_regs
[10] = 16 # load address
780 initial_regs
[12] = 40 # store address
781 for i
in range(8): # set to garbage
782 initial_regs
[16+i
] = (0xbeef00) + i
# identifying garbage
784 # calculate expected regs
785 expected_regs
= deepcopy(initial_regs
)
786 for i
, c
in enumerate(tst_string
[1:]): # note the offset 1(10)
788 expected_regs
[16+i
] = c
789 if c
== 0: break # strcpy stop at NUL *including* NUL
791 # some memory with identifying garbage in it
792 initial_mem
= {16: 0xf0f1_f2f3_f4f5_f6f7,
793 24: 0x4041_4243_4445_4647,
794 40: 0x8081_8283_8485_8687,
795 48: 0x9091_9293_9495_9697,
798 for i
, c
in enumerate(tst_string
):
799 write_byte(initial_mem
, 16+i
, ord(c
))
801 with
Program(lst
, bigendian
=False) as program
:
802 sim
= self
.run_tst_program(program
, svstate
=svstate
,
803 initial_mem
=initial_mem
,
804 initial_regs
=initial_regs
)
805 mem
= sim
.mem
.dump(printout
=True, asciidump
=True)
807 self
.assertEqual(sim
.svstate
.vl
, 3)
808 for i
in range(len(expected_regs
)):
809 print ("%i %x %x" % (i
, sim
.gpr(i
).value
, expected_regs
[i
]))
810 self
.assertEqual(sim
.gpr(i
), expected_regs
[i
])
812 def test_sv_load_dd_ffirst_incl(self
):
813 """data-dependent fail-first on LD/ST, inclusive (/vli)
814 performs linked-list walking
818 # load VL bytes but test if they are zero and truncate
819 "sv.ld/ff=RC1/vli *17, 8(*16)", # offset 8 to next addr
824 # SVSTATE (in this case, VL=8)
825 svstate
= SVP64State()
827 svstate
.maxvl
= 8 # MAXVL
828 print("SVSTATE", bin(svstate
.asint()))
830 initial_regs
= [0] * 32
831 for i
in range(8): # set to garbage
832 initial_regs
[16+i
] = (0xbeef00) + i
# identifying garbage
833 initial_regs
[16] = 24 # data starting point
835 # some memory with addresses to get from. all locations are offset 8
836 initial_mem
= { 24: 0xfeed0001, 32: 48, # data @ 24, ptr @ 32+8 -> 48
837 48: 0xfeed0002, 56: 8 , # data @ 48, ptr @ 48+8 -> 8
838 8 : 0xfeed0003, 16: 80, # data @ 16, ptr @ 16+8 -> 80
839 80: 0xfeed0004, 88: 0, # data @ 80, ptr @ 80+8 -> 0
842 # calculate expected regs
843 expected_regs
= deepcopy(initial_regs
)
846 while True: # VLI needs break at end
847 expected_regs
[16+i
] = ptr_addr
848 print ("expected regs", 16+i
, hex(expected_regs
[16+i
]))
850 if ptr_addr
== 0: break
851 print ("ptr_addr", ptr_addr
)
852 ptr_addr
= initial_mem
[ptr_addr
+8] # linked-list walk, offset 8
854 with
Program(lst
, bigendian
=False) as program
:
855 sim
= self
.run_tst_program(program
, svstate
=svstate
,
856 initial_mem
=initial_mem
,
857 initial_regs
=initial_regs
)
858 mem
= sim
.mem
.dump(printout
=True, asciidump
=True)
860 self
.assertEqual(sim
.svstate
.vl
, 4)
861 for i
in range(len(expected_regs
)):
862 print ("%i %x %x" % (i
, sim
.gpr(i
).value
, expected_regs
[i
]))
863 self
.assertEqual(sim
.gpr(i
), expected_regs
[i
])
865 def test_sv_load_update_dd_ffirst_incl(self
):
866 """data-dependent fail-first on LD/ST-with-update, inclusive (/vli)
867 performs linked-list walking, and stores the Effective Address
868 *behind* where it is picked up (on the next element-iteration).
872 # load VL bytes but test if they are zero and truncate
873 "sv.ldu/ff=RC1/vli *17, 8(*16)", # offset 8 to next addr
878 # SVSTATE (in this case, VL=8)
879 svstate
= SVP64State()
881 svstate
.maxvl
= 8 # MAXVL
882 print("SVSTATE", bin(svstate
.asint()))
884 initial_regs
= [0] * 32
885 for i
in range(8): # set to garbage
886 initial_regs
[16+i
] = (0xbeef00) + i
# identifying garbage
887 initial_regs
[16] = 24 # data starting point
889 # some memory with addresses to get from. all locations are offset 8
890 initial_mem
= { 24: 0xfeed0001, 32: 48, # data @ 24, ptr @ 32+8 -> 48
891 48: 0xfeed0002, 56: 8 , # data @ 48, ptr @ 48+8 -> 8
892 8 : 0xfeed0003, 16: 80, # data @ 16, ptr @ 16+8 -> 80
893 80: 0xfeed0004, 88: 0, # data @ 80, ptr @ 80+8 -> 0
896 # calculate expected regs
897 expected_regs
= deepcopy(initial_regs
)
899 while True: # VLI needs break at end
900 ptr_addr
= expected_regs
[16+i
]
901 newptr_addr
= initial_mem
[ptr_addr
+8] # linked-list walk, offset 8
902 expected_regs
[17+i
] = newptr_addr
903 expected_regs
[16+i
] = ptr_addr
+8
904 print ("expected regs", 16+i
, hex(expected_regs
[16+i
]))
906 print ("ptr_addr", ptr_addr
)
907 if newptr_addr
== 0: break # VLI stop at end
909 with
Program(lst
, bigendian
=False) as program
:
910 sim
= self
.run_tst_program(program
, svstate
=svstate
,
911 initial_mem
=initial_mem
,
912 initial_regs
=initial_regs
)
913 mem
= sim
.mem
.dump(printout
=True, asciidump
=True)
915 self
.assertEqual(sim
.svstate
.vl
, 4)
916 for i
in range(len(expected_regs
)):
917 print ("%i %x %x" % (i
, sim
.gpr(i
).value
, expected_regs
[i
]))
918 self
.assertEqual(sim
.gpr(i
), expected_regs
[i
])
920 def run_tst_program(self
, prog
, initial_regs
=None,
921 svstate
=None, initial_fprs
=None,
923 if initial_regs
is None:
924 initial_regs
= [0] * 32
925 if initial_fprs
is None:
926 initial_fprs
= [0] * 32
927 simulator
= run_tst(prog
, initial_regs
, svstate
=svstate
,
928 initial_fprs
=initial_fprs
,
937 if __name__
== "__main__":