<!-- FRS is automatically calculated by SVP64 to FRT+VL (default elwidth) -->
<!-- (Vector FRS data sequentially starts immediately after FRT vectors) -->
+<!-- PLEASE NOTE THESE ARE UNAPPROVED AND DRAFT, NOT SUBMITTED TO OPF ISA WG -->
+
# Floating Add FFT/DCT [Single]
A-Form
VXSNAN VXISI VXIMZ
CR1 (if Rc=1)
+# Floating SIN [Single]
+
+X-Form
+
+* fsins FRT,FRB (Rc=0)
+* fsins. FRT,FRB (Rc=1)
+
+Pseudo-code:
+
+ FRT <- FPSIN32(FRB)
+
+Special Registers Altered:
+
+ FPRF FR FI
+ FX OX UX XX
+ VXSNAN VXISI VXIMZ
+ CR1 (if Rc=1)
+
+# Floating COS [Single]
+
+X-Form
+
+* fcoss FRT,FRB (Rc=0)
+* fcoss. FRT,FRB (Rc=1)
+
+Pseudo-code:
+
+ FRT <- FPCOS32(FRB)
+
+Special Registers Altered:
+
+ FPRF FR FI
+ FX OX UX XX
+ VXSNAN VXISI VXIMZ
+ CR1 (if Rc=1)
+
fsqrts,,2P,EXTRA3,d:FRT;d:CR1,s:FRB,0,0,0,FRB,0,FRT,0,CR1,0
fres,,2P,EXTRA3,d:FRT;d:CR1,s:FRB,0,0,0,FRB,0,FRT,0,CR1,0
frsqrtes,,2P,EXTRA3,d:FRT;d:CR1,s:FRB,0,0,0,FRB,0,FRT,0,CR1,0
+fsins,,2P,EXTRA3,d:FRT;d:CR1,s:FRB,0,0,0,FRB,0,FRT,0,CR1,0
+fcoss,,2P,EXTRA3,d:FRT;d:CR1,s:FRB,0,0,0,FRB,0,FRT,0,CR1,0
fcfids,,2P,EXTRA3,d:FRT;d:CR1,s:FRB,0,0,0,FRB,0,FRT,0,CR1,0
fcfidus,,2P,EXTRA3,d:FRT;d:CR1,s:FRB,0,0,0,FRB,0,FRT,0,CR1,0
fsqrt,,2P,EXTRA3,d:FRT;d:CR1,s:FRB,0,0,0,FRB,0,FRT,0,CR1,0
-----00110,FPU,OP_FP_MADD,FRA,FRB,FRC,FRT,NONE,CR1,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,ffnmsubs,A,
-----00111,FPU,OP_FP_MADD,FRA,FRB,FRC,FRT,NONE,CR1,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,ffnmadds,A,
-----01101,FPU,OP_FPOP,FRA,FRB,NONE,FRT,NONE,CR1,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,ffadds,A,
+1000001100,FPU,OP_FPOP,NONE,FRB,NONE,FRT,NONE,CR1,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,fsins,X,
+1000101100,FPU,OP_FPOP,NONE,FRB,NONE,FRT,NONE,CR1,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,fcoss,X,
from openpower.decoder.selectable_int import check_extsign
from openpower.util import log
+import math
trunc_div = floordiv
trunc_rem = mod
return SelectableInt(val, 64)
+def FPSIN32(FRB):
+ from openpower.decoder.isafunctions.double2single import DOUBLE2SINGLE
+ #FRB = DOUBLE(SINGLE(FRB))
+ result = math.sin(float(FRB))
+ cvt = fp64toselectable(result)
+ cvt = DOUBLE2SINGLE(cvt)
+ log ("FPSIN32", FRB, float(FRB), "=", result, cvt)
+ return cvt
+
+
+def FPCOS32(FRB):
+ from openpower.decoder.isafunctions.double2single import DOUBLE2SINGLE
+ #FRB = DOUBLE(SINGLE(FRB))
+ result = math.cos(float(FRB))
+ cvt = fp64toselectable(result)
+ cvt = DOUBLE2SINGLE(cvt)
+ log ("FPCOS32", FRB, float(FRB), "=", result, cvt)
+ return cvt
+
+
def FPADD32(FRA, FRB):
from openpower.decoder.isafunctions.double2single import DOUBLE2SINGLE
#return FPADD64(FRA, FRB)
illegal = False
name = 'svshape'
+ # and fsin and fcos
+ if asmop == 'fsins':
+ illegal = False
+ name = 'fsins'
+ if asmop == 'fcoss':
+ illegal = False
+ name = 'fcoss'
+
# 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 copy import deepcopy
+from openpower.sv.trans.svp64 import SVP64Asm
+from openpower.decoder.helpers import fp64toselectable
+from openpower.decoder.isafunctions.double2single import DOUBLE2SINGLE
+
+import math
+
+class FPTranscendentalsTestCase(FHDLTestCase):
+
+ def _check_regs(self, sim, expected_int, expected_fpr):
+ for i in range(32):
+ self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
+ for i in range(32):
+ self.assertEqual(sim.fpr(i), SelectableInt(expected_fpr[i], 64))
+
+ def test_fp_sins_coss(self):
+ """>>> lst = ["fsins 1, 2",
+ "fcoss 3, 2",
+ ]
+ """
+ lst = SVP64Asm(["fsins 1, 2",
+ "fcoss 3, 2",
+ ])
+ lst = list(lst)
+
+ with Program(lst, bigendian=False) as program:
+ fprs = [0] * 32
+ for i in range(-8, 9):
+ a = math.pi * (i / 8.0) * 2.0
+ fprs[2] = fp64toselectable(a)
+ t = math.sin(a)
+ u = math.cos(a)
+ a1 = fp64toselectable(a) # convert to Power single
+ t = DOUBLE2SINGLE(fp64toselectable(t)) # convert to Power single
+ u = DOUBLE2SINGLE(fp64toselectable(u)) # convert to Power single
+
+ with self.subTest():
+ sim = self.run_tst_program(program, initial_fprs=fprs)
+ print("FPR 1", sim.fpr(1))
+ print("FPR 2", sim.fpr(2))
+ print("FPR 3", sim.fpr(3))
+ self.assertEqual(sim.fpr(2), SelectableInt(a1, 64))
+ self.assertEqual(sim.fpr(1), SelectableInt(t, 64))
+ self.assertEqual(sim.fpr(3), SelectableInt(u, 64))
+
+ def run_tst_program(self, prog, initial_regs=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)
+ print ("GPRs")
+ simulator.gpr.dump()
+ print ("FPRs")
+ simulator.fpr.dump()
+ return simulator
+
+
+if __name__ == "__main__":
+ unittest.main()
"ffmsubs", "ffmadds", "ffnmsubs", "ffnmadds", # FFT FP 3-arg
"fmul", "fmuls", "fdiv", "fdivs", # FP mul / div
"fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
+ "fsins", "fcoss", # FP SIN/COS
"hrfid", "icbi", "icbt", "isel", "isync",
"lbarx", "lbz", "lbzu", "lbzux", "lbzx", # load byte
"ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
FPADD32, FPSUB32, FPMUL32, FPDIV32,
FPADD64, FPSUB64, FPMUL64, FPDIV64,
FPMULADD32,
+ FPSIN32, FPCOS32,
)
from openpower.decoder.isafunctions.fpfromint import INT2FP
yield ".long 0x%x" % insn
return
+ # and fsins
+ # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
+ # however we are out of space with opcode 22
+ if opcode.startswith('fsins'):
+ fields = list(map(int, fields))
+ insn = 59 << (31-5) # opcode 59, bits 0-5
+ insn |= fields[0] << (31-10) # RT , bits 6-10
+ insn |= fields[1] << (31-20) # RB , bits 16-20
+ insn |= 0b1000001100 << (31-30) # XO , bits 21..30
+ if opcode == 'fsins.':
+ insn |= 1 << (31-31) # Rc=1 , bit 31
+ log ("fsins", bin(insn))
+ yield ".long 0x%x" % insn
+ return
+
+ # and fcoss
+ # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
+ # however we are out of space with opcode 22
+ if opcode.startswith('fcoss'):
+ fields = list(map(int, fields))
+ insn = 59 << (31-5) # opcode 59, bits 0-5
+ insn |= fields[0] << (31-10) # RT , bits 6-10
+ insn |= fields[1] << (31-20) # RB , bits 16-20
+ insn |= 0b1000101100 << (31-30) # XO , bits 21..30
+ if opcode == 'fsins.':
+ insn |= 1 << (31-31) # Rc=1 , bit 31
+ log ("fsins", bin(insn))
+ yield ".long 0x%x" % insn
+ return
+
# identify if is a svp64 mnemonic
if not opcode.startswith('sv.'):
yield insn # unaltered