08488bfb05a387fdf3b762ad2f6b5d28b57e3c6c
[openpower-isa.git] / src / openpower / decoder / isa / test_caller_transcendentals.py
1 from nmigen import Module, Signal
2 from nmigen.sim 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 copy import deepcopy
15 from openpower.sv.trans.svp64 import SVP64Asm
16 from openpower.decoder.helpers import fp64toselectable
17 from openpower.decoder.isafunctions.double2single import ISACallerFnHelper
18
19 # really bad hack. need to access the DOUBLE2SINGLE function auto-generated
20 # from pseudo-code.
21 fph = ISACallerFnHelper(XLEN=64)
22
23
24 import math
25
26 class FPTranscendentalsTestCase(FHDLTestCase):
27
28 def _check_regs(self, sim, expected_int, expected_fpr):
29 for i in range(32):
30 self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
31 for i in range(32):
32 self.assertEqual(sim.fpr(i), SelectableInt(expected_fpr[i], 64))
33
34 def tst_fp_sins_coss(self):
35 """>>> lst = ["fsins 1, 2",
36 "fcoss 3, 2",
37 ]
38 """
39 lst = SVP64Asm(["fsins 1, 2",
40 "fcoss 3, 2",
41 ])
42 lst = list(lst)
43
44 with Program(lst, bigendian=False) as program:
45 fprs = [0] * 32
46 for i in range(-8, 9):
47 a = math.pi * (i / 8.0) * 2.0
48 fprs[2] = fp64toselectable(a)
49 t = math.sin(a)
50 u = math.cos(a)
51 a1 = fp64toselectable(a) # convert to Power single
52 t = fph.DOUBLE2SINGLE(fp64toselectable(t)) # to Power single
53 u = fph.DOUBLE2SINGLE(fp64toselectable(u)) # to Power single
54
55 with self.subTest():
56 sim = self.run_tst_program(program, initial_fprs=fprs)
57 print("FPR 1", sim.fpr(1))
58 print("FPR 2", sim.fpr(2))
59 print("FPR 3", sim.fpr(3))
60 self.assertEqual(sim.fpr(2), SelectableInt(a1, 64))
61 self.assertEqual(sim.fpr(1), SelectableInt(t, 64))
62 self.assertEqual(sim.fpr(3), SelectableInt(u, 64))
63
64 def test_fp_coss_cvt(self):
65 """>>> lst = [
66 "fcoss 3, 2",
67 ]
68
69 this is a base / proving-ground for the more complex SVP64
70 variant in test_caller_svp64_dct.py:
71 test_sv_remap_dct_cos_precompute_8
72 """
73 lst = SVP64Asm(["std 1, 0(0)",
74 "lfd 0, 0(0)",
75 "fcfids 0, 0",
76 "fadds 0, 0, 3", # plus 0.5
77 "fmuls 0, 0, 1", # times PI
78 "fdivs 0, 0, 2", # div 4.0
79 "fcoss 4, 0",
80 ])
81 lst = list(lst)
82
83 with Program(lst, bigendian=False) as program:
84 gprs = [0] * 32
85 fprs = [0] * 32
86 # constants
87 fprs[3] = fp64toselectable(0.5) # 0.5
88 fprs[1] = fp64toselectable(math.pi) # pi
89 fprs[2] = fp64toselectable(4.0) # 4.0
90 #for i in range(-8, 9):
91 for i in range(7, 8):
92 a = math.pi * ((i+0.5) / 4.0)
93 gprs[1] = i
94 a1 = fph.DOUBLE2SINGLE(fp64toselectable(a)) # to Power single
95 a = float(a1)
96 u = math.cos(a)
97 u = fph.DOUBLE2SINGLE(fp64toselectable(u)) # to Power single
98
99 with self.subTest():
100 sim = self.run_tst_program(program, gprs, initial_fprs=fprs)
101 print("FPR 0", sim.fpr(0), float(sim.fpr(0)))
102 print("FPR 1", sim.fpr(1), float(sim.fpr(1)))
103 print("FPR 2", sim.fpr(2), float(sim.fpr(2)))
104 print("FPR 3", sim.fpr(3), float(sim.fpr(3)))
105 print("FPR 4", sim.fpr(4), float(sim.fpr(4)))
106 # sign should not do this, but hey
107 actual_r = float(sim.fpr(0))
108 expected_r = float(a1)
109 err = abs(actual_r - expected_r ) / expected_r
110 self.assertTrue(err < 1e-6)
111 actual_r = float(sim.fpr(4))
112 expected_r = float(u)
113 err = abs(actual_r - expected_r ) / expected_r
114 self.assertTrue(err < 1e-6)
115
116 def run_tst_program(self, prog, initial_regs=None,
117 initial_mem=None,
118 initial_fprs=None):
119 if initial_regs is None:
120 initial_regs = [0] * 32
121 simulator = run_tst(prog, initial_regs, mem=initial_mem,
122 initial_fprs=initial_fprs)
123 print ("GPRs")
124 simulator.gpr.dump()
125 print ("FPRs")
126 simulator.fpr.dump()
127 return simulator
128
129
130 if __name__ == "__main__":
131 unittest.main()