test,arch-riscv: Removed the RISCV Insttests

These tests verify RISCV instructions. This is already one by the
asmtests:
https://gem5.googlesource.com/public/gem5/+/refs/heads/develop/tests/gem5/asmtest/tests.py

The asmtests do this better.

Furthermore, the insttests have some bugs associated with them, which
would require some engineering effort fix:
https://gem5.atlassian.net/browse/GEM5-729
https://gem5.atlassian.net/browse/GEM5-748
https://gem5.atlassian.net/browse/GEM5-749

This patch removes the RISCV insttests.

Change-Id: I9ee3c88d06778823f655ef9222071beb57c6c995
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/33147
Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Bobby R. Bruce
2020-08-21 16:14:38 -07:00
parent 101e16facf
commit d753719ee3
28 changed files with 1 additions and 5161 deletions

View File

@@ -1,62 +1,13 @@
test-insttest-rv64a-linux-MinorCPU-RISCV-x86_64-opt
test-insttest-rv64c-linux-MinorCPU-RISCV-x86_64-opt
test-insttest-rv64d-linux-MinorCPU-RISCV-x86_64-opt
test-insttest-rv64f-linux-MinorCPU-RISCV-x86_64-opt
test-insttest-rv64i-linux-MinorCPU-RISCV-x86_64-opt
test-insttest-rv64m-linux-MinorCPU-RISCV-x86_64-opt
test-insttest-rv64i-linux-AtomicSimpleCPU-RISCV-x86_64-opt
test-insttest-rv64i-linux-TimingSimpleCPU-RISCV-x86_64-opt
test-insttest-rv64i-linux-DerivO3CPU-RISCV-x86_64-opt
test-insttest-linux-AtomicSimpleCPU-SPARC-x86_64-opt
test-insttest-linux-TimingSimpleCPU-SPARC-x86_64-opt
test-insttest-rv64a-linux-MinorCPU-RISCV-x86_64-debug
test-insttest-rv64c-linux-MinorCPU-RISCV-x86_64-debug
test-insttest-rv64d-linux-MinorCPU-RISCV-x86_64-debug
test-insttest-rv64f-linux-MinorCPU-RISCV-x86_64-debug
test-insttest-rv64i-linux-MinorCPU-RISCV-x86_64-debug
test-insttest-rv64m-linux-MinorCPU-RISCV-x86_64-debug
test-insttest-rv64i-linux-AtomicSimpleCPU-RISCV-x86_64-debug
test-insttest-rv64i-linux-TimingSimpleCPU-RISCV-x86_64-debug
test-insttest-rv64i-linux-DerivO3CPU-RISCV-x86_64-debug
test-insttest-linux-AtomicSimpleCPU-SPARC-x86_64-debug
test-insttest-linux-TimingSimpleCPU-SPARC-x86_64-debug
test-insttest-rv64i-linux-MinorCPU-RISCV-x86_64-fast
test-insttest-rv64i-linux-AtomicSimpleCPU-RISCV-x86_64-fast
test-insttest-rv64i-linux-TimingSimpleCPU-RISCV-x86_64-fast
test-insttest-rv64i-linux-DerivO3CPU-RISCV-x86_64-fast
test-insttest-linux-AtomicSimpleCPU-SPARC-x86_64-fast
test-insttest-linux-TimingSimpleCPU-SPARC-x86_64-fast
test-insttest-rv64a-linux-MinorCPU-RISCV-aarch64-opt
test-insttest-rv64c-linux-MinorCPU-RISCV-aarch64-opt
test-insttest-rv64d-linux-MinorCPU-RISCV-aarch64-opt
test-insttest-rv64f-linux-MinorCPU-RISCV-aarch64-opt
test-insttest-rv64i-linux-MinorCPU-RISCV-aarch64-opt
test-insttest-rv64m-linux-MinorCPU-RISCV-aarch64-opt
test-insttest-rv64i-linux-AtomicSimpleCPU-RISCV-aarch64-opt
test-insttest-rv64i-linux-TimingSimpleCPU-RISCV-aarch64-opt
test-insttest-rv64i-linux-DerivO3CPU-RISCV-aarch64-opt
test-insttest-linux-AtomicSimpleCPU-SPARC-aarch64-opt
test-insttest-linux-TimingSimpleCPU-SPARC-aarch64-opt
test-insttest-rv64a-linux-MinorCPU-RISCV-aarch64-debug
test-insttest-rv64c-linux-MinorCPU-RISCV-aarch64-debug
test-insttest-rv64d-linux-MinorCPU-RISCV-aarch64-debug
test-insttest-rv64f-linux-MinorCPU-RISCV-aarch64-debug
test-insttest-rv64i-linux-MinorCPU-RISCV-aarch64-debug
test-insttest-rv64m-linux-MinorCPU-RISCV-aarch64-debug
test-insttest-rv64i-linux-AtomicSimpleCPU-RISCV-aarch64-debug
test-insttest-rv64i-linux-TimingSimpleCPU-RISCV-aarch64-debug
test-insttest-rv64i-linux-DerivO3CPU-RISCV-aarch64-debug
test-insttest-linux-AtomicSimpleCPU-SPARC-aarch64-debug
test-insttest-linux-TimingSimpleCPU-SPARC-aarch64-debug
test-insttest-rv64a-linux-MinorCPU-RISCV-aarch64-fast
test-insttest-rv64c-linux-MinorCPU-RISCV-aarch64-fast
test-insttest-rv64d-linux-MinorCPU-RISCV-aarch64-fast
test-insttest-rv64f-linux-MinorCPU-RISCV-aarch64-fast
test-insttest-rv64i-linux-MinorCPU-RISCV-aarch64-fast
test-insttest-rv64m-linux-MinorCPU-RISCV-aarch64-fast
test-insttest-rv64i-linux-AtomicSimpleCPU-RISCV-aarch64-fast
test-insttest-rv64i-linux-TimingSimpleCPU-RISCV-aarch64-fast
test-insttest-rv64i-linux-DerivO3CPU-RISCV-aarch64-fast
test-insttest-linux-AtomicSimpleCPU-SPARC-aarch64-fast
test-insttest-linux-TimingSimpleCPU-SPARC-aarch64-fast
realview-o3-checker-ARM-x86_64-opt

View File

@@ -1,41 +0,0 @@
gem5 Simulator System. http://gem5.org
gem5 is copyrighted software; use the --copyright option for details.
Global frequency set at 1000000000000 ticks per second
**** REAL SIMULATION ****
lr.w/sc.w: PASS
sc.w, no preceding lr.d: PASS
amoswap.w: PASS
amoswap.w, sign extend: PASS
amoswap.w, truncate: PASS
amoadd.w: PASS
amoadd.w, truncate/overflow: PASS
amoadd.w, sign extend: PASS
amoxor.w, truncate: PASS
amoxor.w, sign extend: PASS
amoand.w, truncate: PASS
amoand.w, sign extend: PASS
amoor.w, truncate: PASS
amoor.w, sign extend: PASS
amomin.w, truncate: PASS
amomin.w, sign extend: PASS
amomax.w, truncate: PASS
amomax.w, sign extend: PASS
amominu.w, truncate: PASS
amominu.w, sign extend: PASS
amomaxu.w, truncate: PASS
amomaxu.w, sign extend: PASS
lr.d/sc.d: PASS
sc.d, no preceding lr.d: PASS
amoswap.d: PASS
amoadd.d: PASS
amoadd.d, overflow: PASS
amoxor.d (1): PASS
amoxor.d (0): PASS
amoand.d: PASS
amoor.d: PASS
amomin.d: PASS
amomax.d: PASS
amominu.d: PASS
amomaxu.d: PASS

View File

@@ -1,60 +0,0 @@
gem5 Simulator System. http://gem5.org
gem5 is copyrighted software; use the --copyright option for details.
Global frequency set at 1000000000000 ticks per second
**** REAL SIMULATION ****
c.lwsp: PASS
c.ldsp: PASS
c.fldsp: PASS
c.swsp: PASS
c.sdsp: PASS
c.fsdsp: PASS
c.lw, positive: PASS
c.lw, negative: PASS
c.ld: PASS
c.fld: PASS
c.sw: PASS
c.sd: PASS
c.fsd: PASS
c.j: PASS
c.jr: PASS
c.jalr: PASS
c.beqz, zero: PASS
c.beqz, not zero: PASS
c.bnez, not zero: PASS
c.bnez, zero: PASS
c.li: PASS
c.li, sign extend: PASS
c.lui: PASS
c.addi: PASS
c.addiw: PASS
c.addiw, overflow: PASS
c.addiw, truncate: PASS
c.addi16sp: PASS
c.addi4spn: PASS
c.slli: PASS
c.slli, overflow: PASS
c.srli: PASS
c.srli, overflow: PASS
c.srli, -1: PASS
c.srai: PASS
c.srai, overflow: PASS
c.srai, -1: PASS
c.andi (0): PASS
c.andi (1): PASS
c.mv: PASS
c.add: PASS
c.and (0): PASS
c.and (-1): PASS
c.or (1): PASS
c.or (A): PASS
c.xor (1): PASS
c.xor (0): PASS
c.sub: PASS
c.addw: PASS
c.addw, overflow: PASS
c.addw, truncate: PASS
c.subw: PASS
c.subw, "overflow": PASS
c.subw, truncate: PASS

View File

@@ -1,218 +0,0 @@
gem5 Simulator System. http://gem5.org
gem5 is copyrighted software; use the --copyright option for details.
Global frequency set at 1000000000000 ticks per second
**** REAL SIMULATION ****
fld: PASS
fsd: PASS
fmadd.d: PASS
fmadd.d, quiet NaN: PASS
fmadd.d, signaling NaN: PASS
fmadd.d, infinity: PASS
fmadd.d, -infinity: PASS
fmsub.d: PASS
fmsub.d, quiet NaN: PASS
fmsub.d, signaling NaN: PASS
fmsub.d, infinity: PASS
fmsub.d, -infinity: PASS
fmsub.d, subtract infinity: PASS
fnmsub.d: PASS
fnmsub.d, quiet NaN: PASS
fnmsub.d, signaling NaN: PASS
fnmsub.d, infinity: PASS
fnmsub.d, -infinity: PASS
fnmsub.d, subtract infinity: PASS
fnmadd.d: PASS
fnmadd.d, quiet NaN: PASS
fnmadd.d, signaling NaN: PASS
fnmadd.d, infinity: PASS
fnmadd.d, -infinity: PASS
fadd.d: PASS
fadd.d, quiet NaN: PASS
fadd.d, signaling NaN: PASS
fadd.d, infinity: PASS
fadd.d, -infinity: PASS
fsub.d: PASS
fsub.d, quiet NaN: PASS
fsub.d, signaling NaN: PASS
fsub.d, infinity: PASS
fsub.d, -infinity: PASS
fsub.d, subtract infinity: PASS
fmul.d: PASS
fmul.d, quiet NaN: PASS
fmul.d, signaling NaN: PASS
fmul.d, infinity: PASS
fmul.d, -infinity: PASS
fmul.d, 0*infinity: PASS
fmul.d, overflow: PASS
fmul.d, underflow: PASS
fdiv.d: PASS
fdiv.d, quiet NaN: PASS
fdiv.d, signaling NaN: PASS
fdiv.d/0: PASS
fdiv.d/infinity: PASS
fdiv.d, infinity/infinity: PASS
fdiv.d, 0/0: PASS
fdiv.d, infinity/0: PASS
fdiv.d, 0/infinity: PASS
fdiv.d, underflow: PASS
fdiv.d, overflow: PASS
fsqrt.d: PASS
fsqrt.d, NaN: PASS
fsqrt.d, quiet NaN: PASS
fsqrt.d, signaling NaN: PASS
fsqrt.d, infinity: PASS
fsgnj.d, ++: PASS
fsgnj.d, +-: PASS
fsgnj.d, -+: PASS
fsgnj.d, --: PASS
fsgnj.d, quiet NaN: PASS
fsgnj.d, signaling NaN: PASS
fsgnj.d, inject NaN: PASS
fsgnj.d, inject -NaN: PASS
fsgnjn.d, ++: PASS
fsgnjn.d, +-: PASS
fsgnjn.d, -+: PASS
fsgnjn.d, --: PASS
fsgnjn.d, quiet NaN: PASS
fsgnjn.d, signaling NaN: PASS
fsgnjn.d, inject NaN: PASS
fsgnjn.d, inject NaN: PASS
fsgnjx.d, ++: PASS
fsgnjx.d, +-: PASS
fsgnjx.d, -+: PASS
fsgnjx.d, --: PASS
fsgnjx.d, quiet NaN: PASS
fsgnjx.d, signaling NaN: PASS
fsgnjx.d, inject NaN: PASS
fsgnjx.d, inject NaN: PASS
fmin.d: PASS
fmin.d, -infinity: PASS
fmin.d, infinity: PASS
fmin.d, quiet NaN first: PASS
fmin.d, quiet NaN second: PASS
fmin.d, quiet NaN both: PASS
fmin.d, signaling NaN first: PASS
fmin.d, signaling NaN second: PASS
fmin.d, signaling NaN both: PASS
fmax.d: PASS
fmax.d, -infinity: PASS
fmax.d, infinity: PASS
fmax.d, quiet NaN first: PASS
fmax.d, quiet NaN second: PASS
fmax.d, quiet NaN both: PASS
fmax.d, signaling NaN first: PASS
fmax.d, signaling NaN second: PASS
fmax.d, signaling NaN both: PASS
fcvt.s.d: PASS
fcvt.s.d, quiet NaN: PASS
fcvt.s.d, signaling NaN: PASS
fcvt.s.d, infinity: PASS
fcvt.s.d, overflow: PASS
fcvt.s.d, underflow: PASS
fcvt.d.s: PASS
fcvt.d.s, quiet NaN: PASS
fcvt.d.s, signaling NaN: PASS
fcvt.d.s, infinity: PASS
feq.d, equal: PASS
feq.d, not equal: PASS
feq.d, 0 == -0: PASS
feq.d, quiet NaN first: PASS
feq.d, quiet NaN second: PASS
feq.d, quiet NaN both: PASS
feq.d, signaling NaN first: PASS
feq.d, signaling NaN second: PASS
feq.d, signaling NaN both: PASS
flt.d, equal: PASS
flt.d, less: PASS
flt.d, greater: PASS
flt.d, quiet NaN first: PASS
flt.d, quiet NaN second: PASS
flt.d, quiet NaN both: PASS
flt.d, signaling NaN first: PASS
flt.d, signaling NaN second: PASS
flt.d, signaling NaN both: PASS
fle.d, equal: PASS
fle.d, less: PASS
fle.d, greater: PASS
fle.d, 0 == -0: PASS
fle.d, quiet NaN first: PASS
fle.d, quiet NaN second: PASS
fle.d, quiet NaN both: PASS
fle.d, signaling NaN first: PASS
fle.d, signaling NaN second: PASS
fle.d, signaling NaN both: PASS
fclass.d, -infinity: PASS
fclass.d, -normal: PASS
fclass.d, -subnormal: PASS
fclass.d, -0.0: PASS
fclass.d, 0.0: PASS
fclass.d, subnormal: PASS
fclass.d, normal: PASS
fclass.d, infinity: PASS
fclass.d, signaling NaN: PASS
fclass.s, quiet NaN: PASS
fcvt.w.d, truncate positive: PASS
fcvt.w.d, truncate negative: PASS
fcvt.w.d, 0.0: PASS
fcvt.w.d, -0.0: PASS
fcvt.w.d, overflow: PASS
fcvt.w.d, underflow: PASS
fcvt.w.d, infinity: PASS
fcvt.w.d, -infinity: PASS
fcvt.w.d, quiet NaN: PASS
fcvt.w.d, quiet -NaN: PASS
fcvt.w.d, signaling NaN: PASS
fcvt.wu.d, truncate positive: PASS
fcvt.wu.d, truncate negative: PASS
fcvt.wu.d, 0.0: PASS
fcvt.wu.d, -0.0: PASS
fcvt.wu.d, overflow: PASS
fcvt.wu.d, underflow: PASS
fcvt.wu.d, infinity: PASS
fcvt.wu.d, -infinity: PASS
fcvt.wu.d, quiet NaN: PASS
fcvt.wu.d, quiet -NaN: PASS
fcvt.wu.d, signaling NaN: PASS
fcvt.d.w, 0: PASS
fcvt.d.w, negative: PASS
fcvt.d.w, truncate: PASS
fcvt.d.wu, 0: PASS
fcvt.d.wu: PASS
fcvt.d.wu, truncate: PASS
fcvt.l.d, truncate positive: PASS
fcvt.l.d, truncate negative: PASS
fcvt.l.d, 0.0: PASS
fcvt.l.d, -0.0: PASS
fcvt.l.d, 32-bit overflow: PASS
fcvt.l.d, overflow: PASS
fcvt.l.d, underflow: PASS
fcvt.l.d, infinity: PASS
fcvt.l.d, -infinity: PASS
fcvt.l.d, quiet NaN: PASS
fcvt.l.d, quiet -NaN: PASS
fcvt.l.d, signaling NaN: PASS
fcvt.lu.d, truncate positive: PASS
fcvt.lu.d, truncate negative: PASS
fcvt.lu.d, 0.0: PASS
fcvt.lu.d, -0.0: PASS
fcvt.lu.d, 32-bit overflow: PASS
fcvt.lu.d, overflow: PASS
fcvt.lu.d, underflow: PASS
fcvt.lu.d, infinity: PASS
fcvt.lu.d, -infinity: PASS
fcvt.lu.d, quiet NaN: PASS
fcvt.lu.d, quiet -NaN: PASS
fcvt.lu.d, signaling NaN: PASS
fmv.x.d, positive: PASS
fmv.x.d, negative: PASS
fmv.x.d, 0.0: PASS
fmv.x.d, -0.0: PASS
fcvt.d.l, 0: PASS
fcvt.d.l, negative: PASS
fcvt.d.l, 32-bit truncate: PASS
fcvt.d.lu, 0: PASS
fcvt.d.lu: PASS
fcvt.d.lu, 32-bit truncate: PASS
fmv.d.x: PASS

View File

@@ -1,214 +0,0 @@
gem5 Simulator System. http://gem5.org
gem5 is copyrighted software; use the --copyright option for details.
Global frequency set at 1000000000000 ticks per second
**** REAL SIMULATION ****
clear fsflags: PASS
flw: PASS
fsw: PASS
fmadd.s: PASS
fmadd.s, quiet NaN: PASS
fmadd.s, signaling NaN: PASS
fmadd.s, infinity: PASS
fmadd.s, -infinity: PASS
fmsub.s: PASS
fmsub.s, quiet NaN: PASS
fmsub.s, signaling NaN: PASS
fmsub.s, infinity: PASS
fmsub.s, -infinity: PASS
fmsub.s, subtract infinity: PASS
fnmsub.s: PASS
fnmsub.s, quiet NaN: PASS
fnmsub.s, signaling NaN: PASS
fnmsub.s, infinity: PASS
fnmsub.s, -infinity: PASS
fnmsub.s, subtract infinity: PASS
fnmadd.s: PASS
fnmadd.s, quiet NaN: PASS
fnmadd.s, signaling NaN: PASS
fnmadd.s, infinity: PASS
fnmadd.s, -infinity: PASS
fadd.s: PASS
fadd.s, quiet NaN: PASS
fadd.s, signaling NaN: PASS
fadd.s, infinity: PASS
fadd.s, -infinity: PASS
fsub.s: PASS
fsub.s, quiet NaN: PASS
fsub.s, signaling NaN: PASS
fsub.s, infinity: PASS
fsub.s, -infinity: PASS
fsub.s, subtract infinity: PASS
fmul.s: PASS
fmul.s, quiet NaN: PASS
fmul.s, signaling NaN: PASS
fmul.s, infinity: PASS
fmul.s, -infinity: PASS
fmul.s, 0*infinity: PASS
fmul.s, overflow: PASS
fmul.s, underflow: PASS
fdiv.s: PASS
fdiv.s, quiet NaN: PASS
fdiv.s, signaling NaN: PASS
fdiv.s/0: PASS
fdiv.s/infinity: PASS
fdiv.s, infinity/infinity: PASS
fdiv.s, 0/0: PASS
fdiv.s, infinity/0: PASS
fdiv.s, 0/infinity: PASS
fdiv.s, underflow: PASS
fdiv.s, overflow: PASS
fsqrt.s: PASS
fsqrt.s, NaN: PASS
fsqrt.s, quiet NaN: PASS
fsqrt.s, signaling NaN: PASS
fsqrt.s, infinity: PASS
fsgnj.s, ++: PASS
fsgnj.s, +-: PASS
fsgnj.s, -+: PASS
fsgnj.s, --: PASS
fsgnj.s, quiet NaN: PASS
fsgnj.s, signaling NaN: PASS
fsgnj.s, inject NaN: PASS
fsgnj.s, inject -NaN: PASS
fsgnjn.s, ++: PASS
fsgnjn.s, +-: PASS
fsgnjn.s, -+: PASS
fsgnjn.s, --: PASS
fsgnjn.s, quiet NaN: PASS
fsgnjn.s, signaling NaN: PASS
fsgnjn.s, inject NaN: PASS
fsgnjn.s, inject NaN: PASS
fsgnjx.s, ++: PASS
fsgnjx.s, +-: PASS
fsgnjx.s, -+: PASS
fsgnjx.s, --: PASS
fsgnjx.s, quiet NaN: PASS
fsgnjx.s, signaling NaN: PASS
fsgnjx.s, inject NaN: PASS
fsgnjx.s, inject -NaN: PASS
fmin.s: PASS
fmin.s, -infinity: PASS
fmin.s, infinity: PASS
fmin.s, quiet NaN first: PASS
fmin.s, quiet NaN second: PASS
fmin.s, quiet NaN both: PASS
fmin.s, signaling NaN first: PASS
fmin.s, signaling NaN second: PASS
fmin.s, signaling NaN both: PASS
fmax.s: PASS
fmax.s, -infinity: PASS
fmax.s, infinity: PASS
fmax.s, quiet NaN first: PASS
fmax.s, quiet NaN second: PASS
fmax.s, quiet NaN both: PASS
fmax.s, signaling NaN first: PASS
fmax.s, signaling NaN second: PASS
fmax.s, signaling NaN both: PASS
fcvt.w.s, truncate positive: PASS
fcvt.w.s, truncate negative: PASS
fcvt.w.s, 0.0: PASS
fcvt.w.s, -0.0: PASS
fcvt.w.s, overflow: PASS
fcvt.w.s, underflow: PASS
fcvt.w.s, infinity: PASS
fcvt.w.s, -infinity: PASS
fcvt.w.s, quiet NaN: PASS
fcvt.w.s, quiet -NaN: PASS
fcvt.w.s, signaling NaN: PASS
fcvt.wu.s, truncate positive: PASS
fcvt.wu.s, truncate negative: PASS
fcvt.wu.s, 0.0: PASS
fcvt.wu.s, -0.0: PASS
fcvt.wu.s, overflow: PASS
fcvt.wu.s, underflow: PASS
fcvt.wu.s, infinity: PASS
fcvt.wu.s, -infinity: PASS
fcvt.wu.s, quiet NaN: PASS
fcvt.wu.s, quiet -NaN: PASS
fcvt.wu.s, signaling NaN: PASS
fmv.x.s, positive: PASS
fmv.x.s, negative: PASS
fmv.x.s, 0.0: PASS
fmv.x.s, -0.0: PASS
feq.s, equal: PASS
feq.s, not equal: PASS
feq.s, 0 == -0: PASS
feq.s, quiet NaN first: PASS
feq.s, quiet NaN second: PASS
feq.s, quiet NaN both: PASS
feq.s, signaling NaN first: PASS
feq.s, signaling NaN second: PASS
feq.s, signaling NaN both: PASS
flt.s, equal: PASS
flt.s, less: PASS
flt.s, greater: PASS
flt.s, quiet NaN first: PASS
flt.s, quiet NaN second: PASS
flt.s, quiet NaN both: PASS
flt.s, signaling NaN first: PASS
flt.s, signaling NaN second: PASS
flt.s, signaling NaN both: PASS
fle.s, equal: PASS
fle.s, less: PASS
fle.s, greater: PASS
fle.s, 0 == -0: PASS
fle.s, quiet NaN first: PASS
fle.s, quiet NaN second: PASS
fle.s, quiet NaN both: PASS
fle.s, signaling NaN first: PASS
fle.s, signaling NaN second: PASS
fle.s, signaling NaN both: PASS
fclass.s, -infinity: PASS
fclass.s, -normal: PASS
fclass.s, -subnormal: PASS
fclass.s, -0.0: PASS
fclass.s, 0.0: PASS
fclass.s, subnormal: PASS
fclass.s, normal: PASS
fclass.s, infinity: PASS
fclass.s, signaling NaN: PASS
fclass.s, quiet NaN: PASS
fcvt.s.w, 0: PASS
fcvt.s.w, negative: PASS
fcvt.s.w, truncate: PASS
fcvt.s.wu, 0: PASS
fcvt.s.wu: PASS
fcvt.s.wu, truncate: PASS
fmv.s.x: PASS
fmv.s.x, truncate: PASS
fsrm: PASS
fsflags: PASS
fscsr: PASS
restore initial round mode: PASS
fcvt.l.s, truncate positive: PASS
fcvt.l.s, truncate negative: PASS
fcvt.l.s, 0.0: PASS
fcvt.l.s, -0.0: PASS
fcvt.l.s, 32-bit overflow: PASS
fcvt.l.s, overflow: PASS
fcvt.l.s, underflow: PASS
fcvt.l.s, infinity: PASS
fcvt.l.s, -infinity: PASS
fcvt.l.s, quiet NaN: PASS
fcvt.l.s, quiet -NaN: PASS
fcvt.l.s, signaling NaN: PASS
fcvt.lu.s, truncate positive: PASS
fcvt.lu.s, truncate negative: PASS
fcvt.lu.s, 0.0: PASS
fcvt.lu.s, -0.0: PASS
fcvt.lu.s, 32-bit overflow: PASS
fcvt.lu.s, overflow: PASS
fcvt.lu.s, underflow: PASS
fcvt.lu.s, infinity: PASS
fcvt.lu.s, -infinity: PASS
fcvt.lu.s, quiet NaN: PASS
fcvt.lu.s, quiet -NaN: PASS
fcvt.lu.s, signaling NaN: PASS
fcvt.s.l, 0: PASS
fcvt.s.l, negative: PASS
fcvt.s.l, 32-bit truncate: PASS
fcvt.s.lu, 0: PASS
fcvt.s.lu: PASS
fcvt.s.lu, 32-bit truncate: PASS

View File

@@ -1,164 +0,0 @@
gem5 Simulator System. http://gem5.org
gem5 is copyrighted software; use the --copyright option for details.
Global frequency set at 1000000000000 ticks per second
**** REAL SIMULATION ****
lui: PASS
lui, negative: PASS
auipc: 0x1856C
auipc: PASS
jal: PASS
jalr: PASS
beq, equal: PASS
beq, not equal: PASS
bne, equal: PASS
bne, not equal: PASS
blt, less: PASS
blt, equal: PASS
blt, greater: PASS
bge, less: PASS
bge, equal: PASS
bge, greater: PASS
bltu, greater: PASS
bltu, equal: PASS
bltu, less: PASS
bgeu, greater: PASS
bgeu, equal: PASS
bgeu, less: PASS
lb, positive: PASS
lb, negative: PASS
lh, positive: PASS
lh, negative: PASS
lw, positive: PASS
lw, negative: PASS
lbu: PASS
lhu: PASS
sb: PASS
sh: PASS
sw: PASS
addi: PASS
addi, overflow: PASS
slti, true: PASS
slti, false: PASS
sltiu, false: PASS
sltiu, true: PASS
sltiu, sext: PASS
xori (1): PASS
xori (0): PASS
ori (1): PASS
ori (A): PASS
andi (0): PASS
andi (1): PASS
slli, general: PASS
slli, erase: PASS
srli, general: PASS
srli, erase: PASS
srli, negative: PASS
srai, general: PASS
srai, erase: PASS
srai, negative: PASS
add: PASS
add, overflow: PASS
sub: PASS
sub, "overflow": PASS
sll, general: PASS
sll, erase: PASS
slt, true: PASS
slt, false: PASS
sltu, false: PASS
sltu, true: PASS
xor (1): PASS
xor (0): PASS
srl, general: PASS
srl, erase: PASS
srl, negative: PASS
sra, general: PASS
sra, erase: PASS
sra, negative: PASS
or (1): PASS
or (A): PASS
and (0): PASS
and (-1): PASS
Bytes written: 15
open, write: PASS
access F_OK: PASS
access R_OK: PASS
access W_OK: PASS
access X_OK: PASS
stat:
st_dev = 66305
st_ino = 19684698
st_mode = 33188
st_nlink = 1
st_uid = 1019
st_gid = 1020
st_rdev = 0
st_size = 15
st_blksize = 8192
st_blocks = 8
fstat:
st_dev = 66305
st_ino = 19684698
st_mode = 33188
st_nlink = 1
st_uid = 1019
st_gid = 1020
st_rdev = 0
st_size = 15
st_blksize = 8192
st_blocks = 8
open, stat: PASS
Bytes read: 15
String read: this is a test
open, read, unlink: PASS
times:
tms_utime = 0
tms_stime = 0
tms_cutime = 0
tms_cstime = 0
times: FAIL (expected 1; found 0)
timeval:
tv_sec = 1000000000
tv_usec = 126
gettimeofday: PASS
Cycles: 257794
rdcycle: PASS
Time: 1582249831
rdtime: PASS
Instructions Retired: 215961
rdinstret: PASS
lwu: PASS
ld: PASS
sd: PASS
addiw: PASS
addiw, overflow: PASS
addiw, truncate: PASS
slliw, general: PASS
slliw, erase: PASS
slliw, truncate: PASS
srliw, general: PASS
srliw, erase: PASS
srliw, negative: PASS
srliw, truncate: PASS
sraiw, general: PASS
sraiw, erase: PASS
sraiw, negative: PASS
sraiw, truncate: PASS
addw: PASS
addw, overflow: PASS
addw, truncate: PASS
subw: PASS
subw, "overflow": PASS
subw, truncate: PASS
sllw, general: PASS
sllw, erase: PASS
sllw, truncate: PASS
srlw, general: PASS
srlw, erase: PASS
srlw, negative: PASS
srlw, truncate: PASS
sraw, general: PASS
sraw, erase: PASS
sraw, negative: PASS
sraw, truncate: PASS

View File

@@ -1,43 +0,0 @@
gem5 Simulator System. http://gem5.org
gem5 is copyrighted software; use the --copyright option for details.
Global frequency set at 1000000000000 ticks per second
**** REAL SIMULATION ****
mul: PASS
mul, overflow: PASS
mulh: PASS
mulh, negative: PASS
mulh, all bits set: PASS
mulhsu, all bits set: PASS
mulhsu: PASS
mulhu: PASS
mulhu, all bits set: PASS
div: PASS
div/0: PASS
div, overflow: PASS
divu: PASS
divu/0: PASS
divu, "overflow": PASS
rem: PASS
rem/0: PASS
rem, overflow: PASS
remu: PASS
remu/0: PASS
remu, "overflow": PASS
mulw, truncate: PASS
mulw, overflow: PASS
divw, truncate: PASS
divw/0: PASS
divw, overflow: PASS
divuw, truncate: PASS
divuw/0: PASS
divuw, "overflow": PASS
divuw, sign extend: PASS
remw, truncate: PASS
remw/0: PASS
remw, overflow: PASS
remuw, truncate: PASS
remuw/0: PASS
remuw, "overflow": PASS
remuw, sign extend: PASS

View File

@@ -27,22 +27,18 @@
# Authors: Bobby R. Bruce
'''
Test file for the insttest binary running on the RISCV and SPARC
Test file for the insttest binary running on the SPARC ISA
'''
from testlib import *
test_progs = {
'riscv': ('insttest-rv64a', 'insttest-rv64c', 'insttest-rv64d',
'insttest-rv64f', 'insttest-rv64i', 'insttest-rv64m'),
'sparc': ('insttest',)
}
#o3-timing simple-atomic simple-timing
cpu_types = {
'riscv' : ('AtomicSimpleCPU', 'TimingSimpleCPU', 'DerivO3CPU', 'MinorCPU'),
'sparc' : ('AtomicSimpleCPU', 'TimingSimpleCPU')
}
supported_os = {
'riscv' : ('linux',),
'sparc' : ('linux',)
}

View File

@@ -1,50 +0,0 @@
# Copyright (c) 2016 The University of Virginia
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
CXX=riscv64-unknown-linux-gnu-g++
CFLAGS=-std=gnu++11 -O3 -static -march=rv64gc
TARGETS=rv64i rv64m rv64a rv64f rv64d rv64c
PREFIX=../../bin/riscv/linux
BIN=insttest
all: $(TARGETS)
$(TARGETS):
-mkdir -p $(PREFIX)-$@
$(CXX) $< $(CFLAGS) -o $(PREFIX)-$@/$(BIN)
rv64i: rv64i.cpp
rv64m: rv64m.cpp
rv64a: rv64a.cpp
rv64f: rv64f.cpp
rv64d: rv64d.cpp
rv64c: rv64c.cpp
clean:
-rm $(PREFIX)-*/$(BIN)
.PHONY: all clean

View File

@@ -1,76 +0,0 @@
/*
* Copyright (c) 2016 The University of Virginia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cmath>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <string>
#define IOP(inst, rd, rs1, imm) \
asm volatile(inst " %0,%1,%2" : "=r" (rd) : "r" (rs1), "i" (imm))
#define ROP(inst, rd, rs1, rs2) \
asm volatile(inst " %0,%1,%2" : "=r" (rd) : "r" (rs1), "r" (rs2))
#define FROP(inst, fd, fs1, fs2) \
asm volatile(inst " %0,%1,%2" : "=f" (fd) : "f" (fs1), "f" (fs2))
#define FR4OP(inst, fd, fs1, fs2, fs3) \
asm volatile(inst " %0,%1,%2,%3" \
: "=f" (fd) \
: "f" (fs1), "f" (fs2), "f" (fs3))
template<typename A, typename B> std::ostream&
operator<<(std::ostream& os, const std::pair<A, B>& p)
{
return os << '(' << p.first << ", " << p.second << ')';
}
namespace insttest
{
template<typename T> void
expect(const T& expected, std::function<T()> func,
const std::string& test)
{
using namespace std;
T result = func();
cout << test << ": ";
if (result == expected) {
cout << "PASS" << endl;
} else {
cout << "\033[1;31mFAIL\033[0m (expected " << expected << "; found " <<
result << ")" << endl;
}
}
} // namespace insttest

View File

@@ -1,198 +0,0 @@
/*
* Copyright (c) 2016 The University of Virginia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstdint>
#include <limits>
#include "insttest.h"
#include "rv64a.h"
int main()
{
using namespace std;
using namespace insttest;
// Memory (LR.W, SC.W)
expect<pair<int64_t, int64_t>>({-1, 256}, []{
int32_t mem = -1;
int64_t rs2 = 256;
int64_t rd;
pair<int64_t, uint64_t> result;
do {
rd = A::lr_w(mem);
result = A::sc_w(rs2, mem);
} while (result.second == 1);
return pair<int64_t, uint64_t>(rd, result.first);
}, "lr.w/sc.w");
expect<pair<bool, int64_t>>({true, 200}, []{
int32_t mem = 200;
pair<int64_t, uint64_t> result = A::sc_w(50, mem);
return pair<bool, int64_t>(result.second == 1, mem);
}, "sc.w, no preceding lr.d");
// AMOSWAP.W
expect<pair<int64_t, int64_t>>({65535, 255},
[]{return A::amoswap_w(255, 65535);}, "amoswap.w");
expect<pair<int64_t, int64_t>>({0xFFFFFFFF, -1},
[]{return A::amoswap_w(0xFFFFFFFF, 0xFFFFFFFF);},
"amoswap.w, sign extend");
expect<pair<int64_t, int64_t>>({0x0000000180000000LL, -1},
[]{return A::amoswap_w(0x00000001FFFFFFFFLL,
0x7FFFFFFF80000000LL);},
"amoswap.w, truncate");
// AMOADD.W
expect<pair<int64_t, int64_t>>({256, 255},
[]{return A::amoadd_w(255, 1);}, "amoadd.w");
expect<pair<int64_t, int64_t>>({0, -1},
[]{return A::amoadd_w(0xFFFFFFFF, 1);},
"amoadd.w, truncate/overflow");
expect<pair<int64_t, int64_t>>({0xFFFFFFFF, 0x7FFFFFFF},
[]{return A::amoadd_w(0x7FFFFFFF, 0x80000000);},
"amoadd.w, sign extend");
// AMOXOR.W
expect<pair<uint64_t, uint64_t>>({0xFFFFFFFFAAAAAAAALL, -1},
[]{return A::amoxor_w(-1, 0x5555555555555555LL);},
"amoxor.w, truncate");
expect<pair<uint64_t, uint64_t>>({0x80000000, -1},
[]{return A::amoxor_w(0xFFFFFFFF, 0x7FFFFFFF);},
"amoxor.w, sign extend");
// AMOAND.W
expect<pair<uint64_t, uint64_t>>({0xFFFFFFFF00000000LL, -1},
[]{return A::amoand_w(-1, 0);}, "amoand.w, truncate");
expect<pair<uint64_t, uint64_t>>({0x0000000080000000LL, -1},
[]{return A::amoand_w(0xFFFFFFFF,numeric_limits<int32_t>::min());},
"amoand.w, sign extend");
// AMOOR.W
expect<pair<uint64_t, uint64_t>>({0x00000000FFFFFFFFLL, 0},
[]{return A::amoor_w(0, -1);}, "amoor.w, truncate");
expect<pair<uint64_t, uint64_t>>({0x0000000080000000LL, 0},
[]{return A::amoor_w(0, numeric_limits<int32_t>::min());},
"amoor.w, sign extend");
// AMOMIN.W
expect<pair<int64_t, int64_t>>({0x7FFFFFFF00000001LL, 1},
[]{return A::amomin_w(0x7FFFFFFF00000001LL, 0xFFFFFFFF000000FF);},
"amomin.w, truncate");
expect<pair<int64_t, int64_t>>({0x00000000FFFFFFFELL, -1},
[]{return A::amomin_w(0xFFFFFFFF, -2);}, "amomin.w, sign extend");
// AMOMAX.W
expect<pair<int64_t, int64_t>>({0x70000000000000FFLL, 1},
[]{return A::amomax_w(0x7000000000000001LL,0x7FFFFFFF000000FFLL);},
"amomax.w, truncate");
expect<pair<int64_t, int64_t>>({-1, numeric_limits<int32_t>::min()},
[]{return A::amomax_w(numeric_limits<int32_t>::min(), -1);},
"amomax.w, sign extend");
// AMOMINU.W
expect<pair<uint64_t, uint64_t>>({0x0FFFFFFF000000FFLL, -1},
[]{return A::amominu_w(0x0FFFFFFFFFFFFFFFLL, 0xFFFFFFFF000000FF);},
"amominu.w, truncate");
expect<pair<uint64_t, uint64_t>>({0x0000000080000000LL, -1},
[]{return A::amominu_w(0x00000000FFFFFFFFLL, 0x80000000);},
"amominu.w, sign extend");
// AMOMAXU.W
expect<pair<uint64_t, uint64_t>>({-1, 0},
[]{return A::amomaxu_w(0xFFFFFFFF00000000LL,
0x00000000FFFFFFFFLL);},
"amomaxu.w, truncate");
expect<pair<uint64_t, uint64_t>>(
{0xFFFFFFFF, numeric_limits<int32_t>::min()},
[]{return A::amomaxu_w(0x80000000, 0xFFFFFFFF);},
"amomaxu.w, sign extend");
// Memory (LR.D, SC.D)
expect<pair<int64_t, int64_t>>({-1, 256}, []{
int64_t mem = -1;
int64_t rs2 = 256;
int64_t rd;
pair<int64_t, uint64_t> result;
do {
rd = A::lr_d(mem);
result = A::sc_d(rs2, mem);
} while (result.second == 1);
return pair<int64_t, uint64_t>(rd, result.first);
}, "lr.d/sc.d");
expect<pair<bool, int64_t>>({true, 200}, []{
int64_t mem = 200;
pair<int64_t, uint64_t> result = A::sc_d(50, mem);
return pair<bool, int64_t>(result.second == 1, mem);
}, "sc.d, no preceding lr.d");
// AMOSWAP.D
expect<pair<int64_t, int64_t>>({1, -1}, []{return A::amoswap_d(-1, 1);},
"amoswap.d");
// AMOADD.D
expect<pair<int64_t, int64_t>>({0x7000000000000000LL,0x0FFFFFFFFFFFFFFFLL},
[]{return A::amoadd_d(0x0FFFFFFFFFFFFFFFLL,0x6000000000000001LL);},
"amoadd.d");
expect<pair<int64_t, int64_t>>({0, 0x7FFFFFFFFFFFFFFFLL},
[]{return A::amoadd_d(0x7FFFFFFFFFFFFFFFLL,0x8000000000000001LL);},
"amoadd.d, overflow");
// AMOXOR.D
expect<pair<int64_t, int64_t>>({-1, 0xAAAAAAAAAAAAAAAALL},
[]{return A::amoxor_d(0xAAAAAAAAAAAAAAAALL,0x5555555555555555LL);},
"amoxor.d (1)");
expect<pair<int64_t, int64_t>>({0, 0xAAAAAAAAAAAAAAAALL},
[]{return A::amoxor_d(0xAAAAAAAAAAAAAAAALL,0xAAAAAAAAAAAAAAAALL);},
"amoxor.d (0)");
// AMOAND.D
expect<pair<int64_t, int64_t>>({0xAAAAAAAAAAAAAAAALL, -1},
[]{return A::amoand_d(-1, 0xAAAAAAAAAAAAAAAALL);}, "amoand.d");
// AMOOR.D
expect<pair<int64_t, int64_t>>({-1, 0xAAAAAAAAAAAAAAAALL},
[]{return A::amoor_d(0xAAAAAAAAAAAAAAAALL, 0x5555555555555555LL);},
"amoor.d");
// AMOMIN.D
expect<pair<int64_t, int64_t>>({-1, -1},
[]{return A::amomin_d(-1, 0);}, "amomin.d");
// AMOMAX.D
expect<pair<int64_t, int64_t>>({0, -1}, []{return A::amomax_d(-1, 0);},
"amomax.d");
// AMOMINU.D
expect<pair<uint64_t, uint64_t>>({0, -1},
[]{return A::amominu_d(-1, 0);}, "amominu.d");
// AMOMAXU.D
expect<pair<uint64_t, uint64_t>>({-1, -1}, []{return A::amomaxu_d(-1, 0);},
"amomaxu.d");
return 0;
}

View File

@@ -1,297 +0,0 @@
/*
* Copyright (c) 2016 The University of Virginia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cstdint>
#include <tuple>
#include "insttest.h"
namespace A
{
inline int64_t
lr_w(int32_t& mem)
{
int64_t r = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("lr.w %0,(%1)" : "=r" (r) : "r" (addr) : "memory");
return r;
}
inline std::pair<int64_t, uint64_t>
sc_w(int64_t rs2, int32_t& mem)
{
uint64_t addr = (uint64_t)&mem;
uint64_t rd = -1;
asm volatile("sc.w %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<int64_t, int64_t>
amoswap_w(int64_t mem, int64_t rs2)
{
int64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amoswap.w %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<int64_t, int64_t>
amoadd_w(int64_t mem, int64_t rs2)
{
int64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amoadd.w %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<uint64_t, uint64_t>
amoxor_w(uint64_t mem, uint64_t rs2)
{
uint64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amoxor.w %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<uint64_t, uint64_t>
amoand_w(uint64_t mem, uint64_t rs2)
{
uint64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amoand.w %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<uint64_t, uint64_t>
amoor_w(uint64_t mem, uint64_t rs2)
{
uint64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amoor.w %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<int64_t, int64_t>
amomin_w(int64_t mem, int64_t rs2)
{
int64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amomin.w %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<int64_t, int64_t>
amomax_w(int64_t mem, int64_t rs2)
{
int64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amomax.w %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<uint64_t, uint64_t>
amominu_w(uint64_t mem, uint64_t rs2)
{
uint64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amominu.w %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<uint64_t, uint64_t>
amomaxu_w(uint64_t mem, uint64_t rs2)
{
uint64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amomaxu.w %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline int64_t
lr_d(int64_t& mem)
{
int64_t r = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("lr.d %0,(%1)" : "=r" (r) : "r" (addr) : "memory");
return r;
}
inline std::pair<int64_t, uint64_t>
sc_d(int64_t rs2, int64_t& mem)
{
uint64_t addr = (uint64_t)&mem;
uint64_t rd = -1;
asm volatile("sc.d %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<int64_t, int64_t>
amoswap_d(int64_t mem, int64_t rs2)
{
int64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amoswap.d %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<int64_t, int64_t>
amoadd_d(int64_t mem, int64_t rs2)
{
int64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amoadd.d %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<uint64_t, uint64_t>
amoxor_d(uint64_t mem, uint64_t rs2)
{
uint64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amoxor.d %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<uint64_t, uint64_t>
amoand_d(uint64_t mem, uint64_t rs2)
{
uint64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amoand.d %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<uint64_t, uint64_t>
amoor_d(uint64_t mem, uint64_t rs2)
{
uint64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amoor.d %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<int64_t, int64_t>
amomin_d(int64_t mem, int64_t rs2)
{
int64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amomin.d %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<int64_t, int64_t>
amomax_d(int64_t mem, int64_t rs2)
{
int64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amomax.d %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<uint64_t, uint64_t>
amominu_d(uint64_t mem, uint64_t rs2)
{
uint64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amominu.d %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
inline std::pair<uint64_t, uint64_t>
amomaxu_d(uint64_t mem, uint64_t rs2)
{
uint64_t rd = 0;
uint64_t addr = (uint64_t)&mem;
asm volatile("amomaxu.d %0,%2,(%1)"
: "=r" (rd)
: "r" (addr), "r" (rs2)
: "memory");
return {mem, rd};
}
} // namespace A

View File

@@ -1,254 +0,0 @@
/*
* Copyright (c) 2017 The University of Virginia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <limits>
#include "insttest.h"
#include "rv64c.h"
#include "rv64d.h"
int main()
{
using namespace insttest;
using namespace std;
// C.LWSP
expect<bool>(true, []{
uint64_t lw = 0, lwsp = -1;
int64_t i = 16;
asm volatile("lw %0,%2(sp);"
"c.lwsp %1,%2(sp);"
: "=r" (lw), "=r" (lwsp)
: "i" (i));
return lw == lwsp;
}, "c.lwsp");
// C.LDSP
expect<bool>(true, []{
uint64_t ld = 0, ldsp = -1;
int64_t i = 8;
asm volatile("ld %0,%2(sp);"
"c.ldsp %1,%2(sp);"
: "=r" (ld), "=r" (ldsp)
: "i" (i));
return ld == ldsp;
}, "c.ldsp");
// C.FLDSP
expect<bool>(true, []{
double fld = 0.0, fldsp = -1.0;
int64_t i = 32;
asm volatile("fld %0,%2(sp);"
"c.fldsp %1,%2(sp);"
: "=f" (fld), "=f" (fldsp)
: "i" (i));
return D::bits(fld) == D::bits(fldsp);
}, "c.fldsp");
// C.SWSP
expect<bool>(true, []{
int64_t value = -1, result = 0;
asm volatile("addi sp,sp,-8;"
"c.swsp %1,8(sp);"
"lw %0,8(sp);"
"addi sp,sp,8;"
: "=r" (result)
: "r" (value)
: "memory");
return value == result;
}, "c.swsp");
// C.SDSP
expect<bool>(true, []{
int64_t value = -1, result = 0;
asm volatile("addi sp,sp,-8;"
"c.sdsp %1,8(sp);"
"ld %0,8(sp);"
"addi sp,sp,8;"
: "=r" (result)
: "r" (value)
: "memory");
return value == result;
}, "c.sdsp");
// C.FSDSP
expect<bool>(true, []{
double value = 0.1, result = numeric_limits<double>::signaling_NaN();
asm volatile("addi sp,sp,-8;"
"c.fsdsp %1,8(sp);"
"fld %0,8(sp);"
"addi sp,sp,8;"
: "=f" (result)
: "f" (value)
: "memory");
return value == result;
}, "c.fsdsp");
// C.LW, C.LD, C.FLD
expect<int64_t>(458752,
[]{return C::c_load<int32_t, int64_t>(0x00070000);},
"c.lw, positive");
expect<int64_t>(numeric_limits<int32_t>::min(),
[]{return C::c_load<int32_t, int64_t>(0x80000000);},
"c.lw, negative");
expect<int64_t>(30064771072,
[]{return C::c_load<int64_t, int64_t>(30064771072);}, "c.ld");
expect<double>(3.1415926, []{return C::c_load<double, double>(3.1415926);},
"c.fld");
// C.SW, C.SD, C.FSD
expect<uint32_t>(0xFFFFFFFF, []{return C::c_store<int32_t>(-1);}, "c.sw");
expect<uint64_t>(-1, []{return C::c_store<int64_t>(-1);}, "c.sd");
expect<double>(1.61803398875,
[]{return C::c_store<double>(1.61803398875);}, "c.fsd");
// C.J, C.JR, C.JALR
expect<bool>(true, []{return C::c_j();}, "c.j");
expect<bool>(true, []{return C::c_jr();}, "c.jr");
expect<bool>(true, []{return C::c_jalr();}, "c.jalr");
// C.BEQZ
expect<bool>(true, []{return C::c_beqz(0);}, "c.beqz, zero");
expect<bool>(false, []{return C::c_beqz(7);}, "c.beqz, not zero");
// C.BNEZ
expect<bool>(true, []{return C::c_bnez(15);}, "c.bnez, not zero");
expect<bool>(false, []{return C::c_bnez(0);}, "c.bnez, zero");
// C.LI
expect<int64_t>(1, []{return C::c_li(1);}, "c.li");
expect<int64_t>(-1, []{return C::c_li(-1);}, "c.li, sign extend");
// C.LUI
expect<int64_t>(4096, []{return C::c_lui(1);}, "c.lui");
// Note that sign extension can't be tested here because apparently the
// compiler doesn't allow the 6th (sign) bit of the immediate to be 1
// C.ADDI
expect<int64_t>(15, []{return C::c_addi(7, 8);}, "c.addi");
// C.ADDIW
expect<int64_t>(15, []{return C::c_addiw(8, 7);}, "c.addiw");
expect<int64_t>(1, []{return C::c_addiw(0xFFFFFFFF, 2);},
"c.addiw, overflow");
expect<int64_t>(1, []{return C::c_addiw(0x100000001, 0);},
"c.addiw, truncate");
// C.ADDI16SP
expect<bool>(true, []{
uint64_t sp = 0, rd = 0;
const int16_t i = 4;
asm volatile("mv %0,sp;"
"c.addi16sp sp,%2;"
"mv %1,sp;"
"mv sp,%0;"
: "+r" (sp), "=r" (rd)
: "i" (i*16));
return rd == sp + i*16;
}, "c.addi16sp");
// C.ADDI4SPN
expect<bool>(true, []{
uint64_t sp = 0, rd = 0;
const int16_t i = 3;
asm volatile("mv %0,sp;"
"c.addi4spn %1,sp,%2;"
: "=r" (sp), "=r" (rd)
: "i" (i*4));
return rd == sp + i*4;
}, "c.addi4spn");
// C.SLLI
expect<uint64_t>(16, []{return C::c_slli(1, 4);}, "c.slli");
expect<uint64_t>(0, []{return C::c_slli(8, 61);}, "c.slli, overflow");
// C.SRLI
expect<uint64_t>(4, []{return C::c_srli(128, 5);}, "c.srli");
expect<uint64_t>(0, []{return C::c_srli(128, 8);}, "c.srli, overflow");
expect<uint64_t>(1, []{return C::c_srli(-1, 63);}, "c.srli, -1");
// C.SRAI
expect<uint64_t>(4, []{return C::c_srai(128, 5);}, "c.srai");
expect<uint64_t>(0, []{return C::c_srai(128, 8);}, "c.srai, overflow");
expect<uint64_t>(-1, []{return C::c_srai(-2, 63);}, "c.srai, -1");
// C.ANDI
expect<uint64_t>(0, []{return C::c_andi(-1, 0);}, "c.andi (0)");
expect<uint64_t>(0x1234567812345678ULL,
[]{return C::c_andi(0x1234567812345678ULL, -1);}, "c.andi (1)");
// C.MV
expect<int64_t>(1024, []{return C::c_mv(1024);}, "c.mv");
// C.ADD
expect<int64_t>(15, []{return C::c_add(10, 5);}, "c.add");
// C.AND
expect<uint64_t>(0, []{return C::c_and(-1, 0);}, "c.and (0)");
expect<uint64_t>(0x1234567812345678ULL,
[]{return C::c_and(0x1234567812345678ULL, -1);}, "c.and (-1)");
// C.OR
expect<uint64_t>(-1,
[]{return C::c_or(0xAAAAAAAAAAAAAAAAULL,
0x5555555555555555ULL);},
"c.or (1)");
expect<uint64_t>(0xAAAAAAAAAAAAAAAAULL,
[]{return C::c_or(0xAAAAAAAAAAAAAAAAULL,
0xAAAAAAAAAAAAAAAAULL);},
"c.or (A)");
// C.XOR
expect<uint64_t>(-1,
[]{return C::c_xor(0xAAAAAAAAAAAAAAAAULL,
0x5555555555555555ULL);},
"c.xor (1)");
expect<uint64_t>(0,
[]{return C::c_xor(0xAAAAAAAAAAAAAAAAULL,
0xAAAAAAAAAAAAAAAAULL);},
"c.xor (0)");
// C.SUB
expect<int64_t>(65535, []{return C::c_sub(65536, 1);}, "c.sub");
// C.ADDW
expect<int64_t>(1073742078, []{return C::c_addw(0x3FFFFFFF, 255);},
"c.addw");
expect<int64_t>(-1, []{return C::c_addw(0x7FFFFFFF, 0x80000000);},
"c.addw, overflow");
expect<int64_t>(65536, []{return C::c_addw(0xFFFFFFFF0000FFFFLL, 1);},
"c.addw, truncate");
// C.SUBW
expect<int64_t>(65535, []{return C::c_subw(65536, 1);}, "c.subw");
expect<int64_t>(-1, []{return C::c_subw(0x7FFFFFFF, 0x80000000);},
"c.subw, \"overflow\"");
expect<int64_t>(0,
[]{return C::c_subw(0xAAAAAAAAFFFFFFFFULL,0x55555555FFFFFFFFULL);},
"c.subw, truncate");
}

View File

@@ -1,266 +0,0 @@
/*
* Copyright (c) 2017 The University of Virginia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cstdint>
#include <type_traits>
#include "insttest.h"
#define CIOP(op, r, imm) asm volatile(op " %0,%1" : "+r" (r) : "i" (imm));
#define CROP(op, rd, rs) asm volatile(op " %0,%1" : "+r" (rd) : "r" (rs))
namespace C
{
inline int64_t
c_li(const int8_t imm)
{
int64_t rd = 0;
CIOP("c.li", rd, imm);
return rd;
}
inline int64_t
c_lui(const int8_t imm)
{
int64_t rd = 0;
CIOP("c.lui", rd, imm);
return rd;
}
inline int64_t
c_addi(int64_t r, const int8_t imm)
{
CIOP("c.addi", r, imm);
return r;
}
inline int64_t
c_addiw(int64_t r, const int8_t imm)
{
CIOP("c.addiw", r, imm);
return r;
}
inline uint64_t
c_addi4spn(const int16_t imm)
{
uint64_t rd = 0;
asm volatile("c.addi4spn %0,sp,%1" : "=r" (rd) : "i" (imm));
return rd;
}
inline uint64_t
c_slli(uint64_t r, uint8_t shamt)
{
CIOP("c.slli", r, shamt);
return r;
}
inline uint64_t
c_srli(uint64_t r, uint8_t shamt)
{
CIOP("c.srli", r, shamt);
return r;
}
inline int64_t
c_srai(int64_t r, uint8_t shamt)
{
CIOP("c.srai", r, shamt);
return r;
}
inline uint64_t
c_andi(uint64_t r, uint8_t imm)
{
CIOP("c.andi", r, imm);
return r;
}
inline int64_t
c_mv(int64_t rs)
{
int64_t rd = 0;
CROP("c.mv", rd, rs);
return rd;
}
inline int64_t
c_add(int64_t rd, int64_t rs)
{
CROP("c.add", rd, rs);
return rd;
}
inline uint64_t
c_and(int64_t rd, int64_t rs)
{
CROP("c.and", rd, rs);
return rd;
}
inline uint64_t
c_or(int64_t rd, int64_t rs)
{
CROP("c.or", rd, rs);
return rd;
}
inline uint64_t
c_xor(int64_t rd, int64_t rs)
{
CROP("c.xor", rd, rs);
return rd;
}
inline int64_t
c_sub(int64_t rd, int64_t rs)
{
CROP("c.sub", rd, rs);
return rd;
}
inline int64_t
c_addw(int64_t rd, int64_t rs)
{
CROP("c.addw", rd, rs);
return rd;
}
inline int64_t
c_subw(int64_t rd, int64_t rs)
{
CROP("c.subw", rd, rs);
return rd;
}
template<typename M, typename R> inline R
c_load(M m)
{
R r = 0;
switch (sizeof(M))
{
case 4:
asm volatile("c.lw %0,0(%1)" : "=r" (r) : "r" (&m) : "memory");
break;
case 8:
if (std::is_floating_point<M>::value)
asm volatile("c.fld %0,0(%1)" : "=f" (r) : "r" (&m) : "memory");
else
asm volatile("c.ld %0,0(%1)" : "=r" (r) : "r" (&m) : "memory");
break;
}
return r;
}
template<typename M> inline M
c_store(const M& rs)
{
M mem = 0;
switch (sizeof(M))
{
case 4:
asm volatile("c.sw %0,0(%1)" : : "r" (rs), "r" (&mem) : "memory");
break;
case 8:
if (std::is_floating_point<M>::value)
asm volatile("c.fsd %0,0(%1)" : : "f" (rs), "r" (&mem) : "memory");
else
asm volatile("c.sd %0,0(%1)" : : "r" (rs), "r" (&mem) : "memory");
break;
}
return mem;
}
inline bool
c_j()
{
asm volatile goto("c.j %l[jallabel]" : : : : jallabel);
return false;
jallabel:
return true;
}
inline bool
c_jr()
{
uint64_t a = 0;
asm volatile("auipc %0,0;"
"c.addi %0,12;"
"c.jr %0;"
"addi %0,zero,0;"
"addi %0,%0,0;"
: "+r" (a));
return a > 0;
}
inline bool
c_jalr()
{
int64_t a = 0;
asm volatile("auipc %0,0;"
"c.addi %0,12;"
"c.jalr %0;"
"addi %0,zero,0;"
"sub %0,ra,%0;"
: "+r" (a)
:
: "ra");
return a == -4;
}
inline bool
c_beqz(int64_t a)
{
asm volatile goto("c.beqz %0,%l[beqlabel]"
:
: "r" (a)
:
: beqlabel);
return false;
beqlabel:
return true;
}
inline bool
c_bnez(int64_t a)
{
asm volatile goto("c.bnez %0,%l[beqlabel]"
:
: "r" (a)
:
: beqlabel);
return false;
beqlabel:
return true;
}
} // namespace C

View File

@@ -1,706 +0,0 @@
/*
* Copyright (c) 2016 The University of Virginia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstdint>
#include <limits>
#include "insttest.h"
#include "rv64d.h"
#include "rv64f.h"
int main()
{
using namespace std;
using namespace insttest;
// Memory (FLD, FSD)
expect<double>(3.1415926, []{return D::load(3.1415926);}, "fld");
expect<double>(1.61803398875, []{return D::store(1.61803398875);}, "fsd");
// FMADD.D
expect<double>(D::number(0x4019FD5AED13B1CEULL),
[]{return D::fmadd_d(3.1415926, 1.61803398875,1.41421356237);},
"fmadd.d");
expect<bool>(true, []{
double fd = D::fmadd_d(numeric_limits<double>::quiet_NaN(), 3.14,
1.816);
return D::isquietnan(fd);
}, "fmadd.d, quiet NaN");
expect<bool>(true, []{
double fd = D::fmadd_d(3.14,
numeric_limits<double>::signaling_NaN(), 1.816);
return D::isquietnan(fd);
}, "fmadd.d, signaling NaN");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fmadd_d(3.14, numeric_limits<double>::infinity(),1.414);},
"fmadd.d, infinity");
expect<double>(-numeric_limits<double>::infinity(),
[]{return D::fmadd_d(3.14,-numeric_limits<double>::infinity(),1.414);},
"fmadd.d, -infinity");
// FMSUB.D
expect<double>(D::number(0x400d5A1773A85E43ULL),
[]{return D::fmsub_d(3.1415926, 1.61803398875, 1.41421356237);},
"fmsub.d");
expect<bool>(true, []{
double fd = D::fmsub_d(3.14, numeric_limits<double>::quiet_NaN(),
1.414);
return D::isquietnan(fd);
}, "fmsub.d, quiet NaN");
expect<bool>(true, []{
double fd = D::fmsub_d(3.14, 1.816,
numeric_limits<double>::signaling_NaN());
return D::isquietnan(fd);
}, "fmsub.d, signaling NaN");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fmsub_d(numeric_limits<double>::infinity(), 1.816,
1.414);},
"fmsub.d, infinity");
expect<double>(-numeric_limits<double>::infinity(),
[]{return D::fmsub_d(3.14, -numeric_limits<double>::infinity(),
1.414);},
"fmsub.d, -infinity");
expect<double>(-numeric_limits<double>::infinity(),
[]{return D::fmsub_d(3.14, 1.816,
numeric_limits<double>::infinity());},
"fmsub.d, subtract infinity");
// FNMSUB.D
expect<double>(D::number(0xC00D5A1773A85E43ULL),
[]{return D::fnmsub_d(3.1415926, 1.61803398875, 1.41421356237);},
"fnmsub.d");
expect<bool>(true, []{
double fd = D::fnmsub_d(3.14, 1.816,
numeric_limits<double>::quiet_NaN());
return D::isquietnan(fd);
}, "fnmsub.d, quiet NaN");
expect<bool>(true, []{
double fd = D::fnmsub_d(numeric_limits<double>::signaling_NaN(),
1.816, 1.414);
return D::isquietnan(fd);
}, "fnmsub.d, signaling NaN");
expect<double>(-numeric_limits<double>::infinity(),
[]{return D::fnmsub_d(numeric_limits<double>::infinity(), 1.816,
1.414);},
"fnmsub.d, infinity");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fnmsub_d(3.14, -numeric_limits<double>::infinity(),
1.414);},
"fnmsub.d, -infinity");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fnmsub_d(3.14, 1.816,
numeric_limits<double>::infinity());},
"fnmsub.d, subtract infinity");
// FNMADD.D
expect<double>(D::number(0xC019FD5AED13B1CEULL),
[]{return D::fnmadd_d(3.1415926, 1.61803398875, 1.41421356237);},
"fnmadd.d");
expect<bool>(true, []{
double fd = D::fnmadd_d(numeric_limits<double>::quiet_NaN(), 3.14,
1.816);
return D::isquietnan(fd);
}, "fnmadd.d, quiet NaN");
expect<bool>(true, []{
double fd = D::fnmadd_d(3.14,
numeric_limits<double>::signaling_NaN(), 1.816);
return D::isquietnan(fd);
}, "fnmadd.d, signaling NaN");
expect<double>(-numeric_limits<double>::infinity(),
[]{return D::fnmadd_d(3.14, numeric_limits<double>::infinity(),
1.414);},
"fnmadd.d, infinity");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fnmadd_d(3.14, -numeric_limits<double>::infinity(),
1.414);},
"fnmadd.d, -infinity");
// FADD.D
expect<double>(D::number(0x4012392540292D7CULL),
[]{return D::fadd_d(3.1415926, 1.41421356237);}, "fadd.d");
expect<bool>(true, []{
double fd = D::fadd_d(numeric_limits<double>::quiet_NaN(), 1.414);
return D::isquietnan(fd);
}, "fadd.d, quiet NaN");
expect<bool>(true, []{
double fd = D::fadd_d(3.14,
numeric_limits<double>::signaling_NaN());
return D::isquietnan(fd);
}, "fadd.d, signaling NaN");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fadd_d(3.14, numeric_limits<double>::infinity());},
"fadd.d, infinity");
expect<double>(-numeric_limits<double>::infinity(),
[]{return D::fadd_d(-numeric_limits<double>::infinity(), 1.816);},
"fadd.d, -infinity");
// FSUB.D
expect<double>(D::number(0xBFFBA35833AB7AAEULL),
[]{return D::fsub_d(1.4142135623, 3.1415926);}, "fsub.d");
expect<bool>(true, []{
double fd = D::fsub_d(numeric_limits<double>::quiet_NaN(), 1.414);
return D::isquietnan(fd);
}, "fsub.d, quiet NaN");
expect<bool>(true, []{
double fd = D::fsub_d(3.14,
numeric_limits<double>::signaling_NaN());
return D::isquietnan(fd);
}, "fsub.d, signaling NaN");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fsub_d(numeric_limits<double>::infinity(), 3.14);},
"fsub.d, infinity");
expect<double>(-numeric_limits<double>::infinity(),
[]{return D::fsub_d(-numeric_limits<double>::infinity(), 3.14);},
"fsub.d, -infinity");
expect<double>(-numeric_limits<double>::infinity(),
[]{return D::fsub_d(1.414, numeric_limits<double>::infinity());},
"fsub.d, subtract infinity");
// FMUL.D
expect<double>(D::number(0x40024E53B708ED9AULL),
[]{return D::fmul_d(1.61803398875, 1.4142135623);}, "fmul.d");
expect<bool>(true, []{
double fd = D::fmul_d(numeric_limits<double>::quiet_NaN(), 1.414);
return D::isquietnan(fd);
}, "fmul.d, quiet NaN");
expect<bool>(true, []{
double fd = D::fmul_d(1.816,
numeric_limits<double>::signaling_NaN());
return D::isquietnan(fd);
}, "fmul.d, signaling NaN");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fmul_d(numeric_limits<double>::infinity(), 2.718);},
"fmul.d, infinity");
expect<double>(-numeric_limits<double>::infinity(),
[]{return D::fmul_d(2.5966, -numeric_limits<double>::infinity());},
"fmul.d, -infinity");
expect<bool>(true, []{
double fd = D::fmul_d(0.0, numeric_limits<double>::infinity());
return D::isquietnan(fd);
}, "fmul.d, 0*infinity");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fmul_d(numeric_limits<double>::max(), 2.0);},
"fmul.d, overflow");
expect<double>(0.0,
[]{return D::fmul_d(numeric_limits<double>::min(),
numeric_limits<double>::min());},
"fmul.d, underflow");
// FDIV.D
expect<double>(2.5, []{return D::fdiv_d(10.0, 4.0);}, "fdiv.d");
expect<bool>(true, []{
double fd = D::fdiv_d(numeric_limits<double>::quiet_NaN(), 4.0);
return D::isquietnan(fd);
}, "fdiv.d, quiet NaN");
expect<bool>(true, []{
double fd = D::fdiv_d(10.0,
numeric_limits<double>::signaling_NaN());
return D::isquietnan(fd);
}, "fdiv.d, signaling NaN");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fdiv_d(10.0, 0.0);}, "fdiv.d/0");
expect<double>(0.0,
[]{return D::fdiv_d(10.0, numeric_limits<double>::infinity());},
"fdiv.d/infinity");
expect<bool>(true, []{
double fd = D::fdiv_d(numeric_limits<double>::infinity(),
numeric_limits<double>::infinity());
return D::isquietnan(fd);
}, "fdiv.d, infinity/infinity");
expect<bool>(true, []{
double fd = D::fdiv_d(0.0, 0.0);
return D::isquietnan(fd);
}, "fdiv.d, 0/0");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fdiv_d(numeric_limits<double>::infinity(), 0.0);},
"fdiv.d, infinity/0");
expect<double>(0.0,
[]{return D::fdiv_d(0.0, numeric_limits<double>::infinity());},
"fdiv.d, 0/infinity");
expect<double>(0.0,
[]{return D::fdiv_d(numeric_limits<double>::min(),
numeric_limits<double>::max());},
"fdiv.d, underflow");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fdiv_d(numeric_limits<double>::max(),
numeric_limits<double>::min());},
"fdiv.d, overflow");
// FSQRT.D
expect<double>(1e154, []{return D::fsqrt_d(1e308);}, "fsqrt.d");
expect<bool>(true, []{
double fd = D::fsqrt_d(-1.0);
return D::isquietnan(fd);
}, "fsqrt.d, NaN");
expect<bool>(true, []{
double fd = D::fsqrt_d(numeric_limits<double>::quiet_NaN());
return D::isquietnan(fd);
}, "fsqrt.d, quiet NaN");
expect<bool>(true, []{
double fd = D::fsqrt_d(numeric_limits<double>::signaling_NaN());
return D::isquietnan(fd);
}, "fsqrt.d, signaling NaN");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fsqrt_d(numeric_limits<double>::infinity());},
"fsqrt.d, infinity");
// FSGNJ.D
expect<double>(1.0, []{return D::fsgnj_d(1.0, 25.0);}, "fsgnj.d, ++");
expect<double>(-1.0, []{return D::fsgnj_d(1.0, -25.0);}, "fsgnj.d, +-");
expect<double>(1.0, []{return D::fsgnj_d(-1.0, 25.0);}, "fsgnj.d, -+");
expect<double>(-1.0, []{return D::fsgnj_d(-1.0, -25.0);}, "fsgnj.d, --");
expect<bool>(true, []{
double fd = D::fsgnj_d(numeric_limits<double>::quiet_NaN(), -4.0);
return D::isquietnan(fd);
}, "fsgnj.d, quiet NaN");
expect<bool>(true, []{
double fd = D::fsgnj_d(numeric_limits<double>::signaling_NaN(),
-4.0);
return D::issignalingnan(fd);
}, "fsgnj.d, signaling NaN");
expect<double>(4.0,
[]{return D::fsgnj_d(4.0, numeric_limits<double>::quiet_NaN());},
"fsgnj.d, inject NaN");
expect<double>(-4.0,
[]{return D::fsgnj_d(4.0, -numeric_limits<double>::quiet_NaN());},
"fsgnj.d, inject -NaN");
// FSGNJN.D
expect<double>(-1.0, []{return D::fsgnjn_d(1.0, 25.0);}, "fsgnjn.d, ++");
expect<double>(1.0, []{return D::fsgnjn_d(1.0, -25.0);}, "fsgnjn.d, +-");
expect<double>(-1.0, []{return D::fsgnjn_d(-1.0, 25.0);}, "fsgnjn.d, -+");
expect<double>(1.0, []{return D::fsgnjn_d(-1.0, -25.0);}, "fsgnjn.d, --");
expect<bool>(true, []{
double fd = D::fsgnjn_d(numeric_limits<double>::quiet_NaN(), -4.0);
return D::isquietnan(fd);
}, "fsgnjn.d, quiet NaN");
expect<bool>(true, []{
double fd = D::fsgnjn_d(numeric_limits<double>::signaling_NaN(),
-4.0);
return D::issignalingnan(fd);
}, "fsgnjn.d, signaling NaN");
expect<double>(-4.0,
[]{return D::fsgnjn_d(4.0, numeric_limits<double>::quiet_NaN());},
"fsgnjn.d, inject NaN");
expect<double>(4.0,
[]{return D::fsgnjn_d(4.0, -numeric_limits<double>::quiet_NaN());},
"fsgnjn.d, inject NaN");
// FSGNJX.D
expect<double>(1.0, []{return D::fsgnjx_d(1.0, 25.0);}, "fsgnjx.d, ++");
expect<double>(-1.0, []{return D::fsgnjx_d(1.0, -25.0);}, "fsgnjx.d, +-");
expect<double>(-1.0, []{return D::fsgnjx_d(-1.0, 25.0);}, "fsgnjx.d, -+");
expect<double>(1.0, []{return D::fsgnjx_d(-1.0, -25.0);}, "fsgnjx.d, --");
expect<bool>(true, []{
double fd = D::fsgnjx_d(numeric_limits<double>::quiet_NaN(), -4.0);
return D::isquietnan(fd);
}, "fsgnjx.d, quiet NaN");
expect<bool>(true, []{
double fd = D::fsgnjx_d(numeric_limits<double>::signaling_NaN(),
-4.0);
return D::issignalingnan(fd);
}, "fsgnjx.d, signaling NaN");
expect<double>(4.0,
[]{return D::fsgnjx_d(4.0, numeric_limits<double>::quiet_NaN());},
"fsgnjx.d, inject NaN");
expect<double>(-4.0,
[]{return D::fsgnjx_d(4.0, -numeric_limits<double>::quiet_NaN());},
"fsgnjx.d, inject NaN");
// FMIN.D
expect<double>(2.718, []{return D::fmin_d(3.14, 2.718);}, "fmin.d");
expect<double>(-numeric_limits<double>::infinity(),
[]{return D::fmin_d(-numeric_limits<double>::infinity(),
numeric_limits<double>::min());},
"fmin.d, -infinity");
expect<double>(numeric_limits<double>::max(),
[]{return D::fmin_d(numeric_limits<double>::infinity(),
numeric_limits<double>::max());},
"fmin.d, infinity");
expect<double>(-1.414,
[]{return D::fmin_d(numeric_limits<double>::quiet_NaN(), -1.414);},
"fmin.d, quiet NaN first");
expect<double>(2.718,
[]{return D::fmin_d(2.718, numeric_limits<double>::quiet_NaN());},
"fmin.d, quiet NaN second");
expect<bool>(true, []{
double fd = D::fmin_d(numeric_limits<double>::quiet_NaN(),
numeric_limits<double>::quiet_NaN());
return D::isquietnan(fd);
}, "fmin.d, quiet NaN both");
expect<double>(3.14,
[]{return D::fmin_d(numeric_limits<double>::signaling_NaN(),
3.14);},
"fmin.d, signaling NaN first");
expect<double>(1.816,
[]{return D::fmin_d(1.816,
numeric_limits<double>::signaling_NaN());},
"fmin.d, signaling NaN second");
expect<bool>(true, []{
double fd = D::fmin_d(numeric_limits<double>::signaling_NaN(),
numeric_limits<double>::signaling_NaN());
return D::issignalingnan(fd);
}, "fmin.d, signaling NaN both");
// FMAX.D
expect<double>(3.14, []{return D::fmax_d(3.14, 2.718);}, "fmax.d");
expect<double>(numeric_limits<double>::min(),
[]{return D::fmax_d(-numeric_limits<double>::infinity(),
numeric_limits<double>::min());},
"fmax.d, -infinity");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fmax_d(numeric_limits<double>::infinity(),
numeric_limits<double>::max());},
"fmax.d, infinity");
expect<double>(-1.414,
[]{return D::fmax_d(numeric_limits<double>::quiet_NaN(), -1.414);},
"fmax.d, quiet NaN first");
expect<double>(2.718,
[]{return D::fmax_d(2.718, numeric_limits<double>::quiet_NaN());},
"fmax.d, quiet NaN second");
expect<bool>(true, []{
double fd = D::fmax_d(numeric_limits<double>::quiet_NaN(),
numeric_limits<double>::quiet_NaN());
return D::isquietnan(fd);
}, "fmax.d, quiet NaN both");
expect<double>(3.14,
[]{return D::fmax_d(numeric_limits<double>::signaling_NaN(),
3.14);},
"fmax.d, signaling NaN first");
expect<double>(1.816,
[]{return D::fmax_d(1.816,
numeric_limits<double>::signaling_NaN());},
"fmax.d, signaling NaN second");
expect<bool>(true, []{
double fd = D::fmax_d(numeric_limits<double>::signaling_NaN(),
numeric_limits<double>::signaling_NaN());
return D::issignalingnan(fd);
}, "fmax.d, signaling NaN both");
// FCVT.S.D
expect<float>(4.0, []{return D::fcvt_s_d(4.0);}, "fcvt.s.d");
expect<bool>(true, []{
float fd = D::fcvt_s_d(numeric_limits<double>::quiet_NaN());
return F::isquietnan(fd);
}, "fcvt.s.d, quiet NaN");
expect<bool>(true, []{
float fd = D::fcvt_s_d(numeric_limits<double>::signaling_NaN());
return F::isquietnan(fd);
}, "fcvt.s.d, signaling NaN");
expect<float>(numeric_limits<float>::infinity(),
[]{return D::fcvt_s_d(numeric_limits<double>::infinity());},
"fcvt.s.d, infinity");
expect<float>(numeric_limits<float>::infinity(),
[]{return D::fcvt_s_d(numeric_limits<double>::max());},
"fcvt.s.d, overflow");
expect<float>(0.0, []{return D::fcvt_s_d(numeric_limits<double>::min());},
"fcvt.s.d, underflow");
// FCVT.D.S
expect<double>(D::number(0x4005BE76C0000000),
[]{return D::fcvt_d_s(2.718);}, "fcvt.d.s");
expect<bool>(true, []{
double fd = D::fcvt_d_s(numeric_limits<float>::quiet_NaN());
return D::isquietnan(fd);
}, "fcvt.d.s, quiet NaN");
expect<bool>(true, []{
double fd = D::fcvt_d_s(numeric_limits<float>::signaling_NaN());
return D::isquietnan(fd);
}, "fcvt.d.s, signaling NaN");
expect<double>(numeric_limits<double>::infinity(),
[]{return D::fcvt_d_s(numeric_limits<float>::infinity());},
"fcvt.d.s, infinity");
// FEQ.D
expect<bool>(true, []{return D::feq_d(1.414, 1.414);}, "feq.d, equal");
expect<bool>(false,[]{return D::feq_d(2.718, 1.816);}, "feq.d, not equal");
expect<bool>(true, []{return D::feq_d(0.0, -0.0);}, "feq.d, 0 == -0");
expect<bool>(false,
[]{return D::feq_d(numeric_limits<double>::quiet_NaN(), -1.0);},
"feq.d, quiet NaN first");
expect<bool>(false,
[]{return D::feq_d(2.0, numeric_limits<double>::quiet_NaN());},
"feq.d, quiet NaN second");
expect<bool>(false,
[]{return D::feq_d(numeric_limits<double>::quiet_NaN(),
numeric_limits<double>::quiet_NaN());},
"feq.d, quiet NaN both");
expect<bool>(false,
[]{return D::feq_d(numeric_limits<double>::signaling_NaN(),-1.0);},
"feq.d, signaling NaN first");
expect<bool>(false,
[]{return D::feq_d(2.0, numeric_limits<double>::signaling_NaN());},
"feq.d, signaling NaN second");
expect<bool>(false,
[]{return D::feq_d(numeric_limits<double>::signaling_NaN(),
numeric_limits<double>::signaling_NaN());},
"feq.d, signaling NaN both");
// FLT.D
expect<bool>(false, []{return D::flt_d(1.414, 1.414);}, "flt.d, equal");
expect<bool>(true, []{return D::flt_d(1.816, 2.718);}, "flt.d, less");
expect<bool>(false, []{return D::flt_d(2.718, 1.816);}, "flt.d, greater");
expect<bool>(false,
[]{return D::flt_d(numeric_limits<double>::quiet_NaN(), -1.0);},
"flt.d, quiet NaN first");
expect<bool>(false,
[]{return D::flt_d(2.0, numeric_limits<double>::quiet_NaN());},
"flt.d, quiet NaN second");
expect<bool>(false,
[]{return D::flt_d(numeric_limits<double>::quiet_NaN(),
numeric_limits<double>::quiet_NaN());},
"flt.d, quiet NaN both");
expect<bool>(false,
[]{return D::flt_d(numeric_limits<double>::signaling_NaN(),-1.0);},
"flt.d, signaling NaN first");
expect<bool>(false,
[]{return D::flt_d(2.0, numeric_limits<double>::signaling_NaN());},
"flt.d, signaling NaN second");
expect<bool>(false,
[]{return D::flt_d(numeric_limits<double>::signaling_NaN(),
numeric_limits<double>::signaling_NaN());},
"flt.d, signaling NaN both");
// FLE.D
expect<bool>(true, []{return D::fle_d(1.414, 1.414);}, "fle.d, equal");
expect<bool>(true, []{return D::fle_d(1.816, 2.718);}, "fle.d, less");
expect<bool>(false, []{return D::fle_d(2.718, 1.816);}, "fle.d, greater");
expect<bool>(true, []{return D::fle_d(0.0, -0.0);}, "fle.d, 0 == -0");
expect<bool>(false,
[]{return D::fle_d(numeric_limits<double>::quiet_NaN(), -1.0);},
"fle.d, quiet NaN first");
expect<bool>(false,
[]{return D::fle_d(2.0, numeric_limits<double>::quiet_NaN());},
"fle.d, quiet NaN second");
expect<bool>(false,
[]{return D::fle_d(numeric_limits<double>::quiet_NaN(),
numeric_limits<double>::quiet_NaN());},
"fle.d, quiet NaN both");
expect<bool>(false,
[]{return D::fle_d(numeric_limits<double>::signaling_NaN(),-1.0);},
"fle.d, signaling NaN first");
expect<bool>(false,
[]{return D::fle_d(2.0, numeric_limits<double>::signaling_NaN());},
"fle.d, signaling NaN second");
expect<bool>(false,
[]{return D::fle_d(numeric_limits<double>::signaling_NaN(),
numeric_limits<double>::signaling_NaN());},
"fle.d, signaling NaN both");
// FCLASS.D
expect<uint64_t>(0x1,
[]{return D::fclass_d(-numeric_limits<double>::infinity());},
"fclass.d, -infinity");
expect<uint64_t>(0x2,
[]{return D::fclass_d(-3.14);}, "fclass.d, -normal");
expect<uint64_t>(0x4,
[]{return D::fclass_d(D::number(0x800FFFFFFFFFFFFFULL));},
"fclass.d, -subnormal");
expect<uint64_t>(0x8, []{return D::fclass_d(-0.0);}, "fclass.d, -0.0");
expect<uint64_t>(0x10, []{return D::fclass_d(0.0);}, "fclass.d, 0.0");
expect<uint64_t>(0x20,
[]{return D::fclass_d(D::number(0x000FFFFFFFFFFFFFULL));},
"fclass.d, subnormal");
expect<uint64_t>(0x40, []{return D::fclass_d(1.816);}, "fclass.d, normal");
expect<uint64_t>(0x80,
[]{return D::fclass_d(numeric_limits<double>::infinity());},
"fclass.d, infinity");
expect<uint64_t>(0x100,
[]{return D::fclass_d(numeric_limits<double>::signaling_NaN());},
"fclass.d, signaling NaN");
expect<uint64_t>(0x200,
[]{return D::fclass_d(numeric_limits<double>::quiet_NaN());},
"fclass.s, quiet NaN");
// FCVT.W.D
expect<int64_t>(256, []{return D::fcvt_w_d(256.3);},
"fcvt.w.d, truncate positive");
expect<int64_t>(-256, []{return D::fcvt_w_d(-256.2);},
"fcvt.w.d, truncate negative");
expect<int64_t>(0, []{return D::fcvt_w_d(0.0);}, "fcvt.w.d, 0.0");
expect<int64_t>(0, []{return D::fcvt_w_d(-0.0);}, "fcvt.w.d, -0.0");
expect<int64_t>(numeric_limits<int32_t>::max(),
[]{return D::fcvt_w_d(numeric_limits<double>::max());},
"fcvt.w.d, overflow");
expect<int64_t>(0, []{return D::fcvt_w_d(numeric_limits<double>::min());},
"fcvt.w.d, underflow");
expect<int64_t>(numeric_limits<int32_t>::max(),
[]{return D::fcvt_w_d(numeric_limits<double>::infinity());},
"fcvt.w.d, infinity");
expect<int64_t>(numeric_limits<int32_t>::min(),
[]{return D::fcvt_w_d(-numeric_limits<double>::infinity());},
"fcvt.w.d, -infinity");
expect<int64_t>(numeric_limits<int32_t>::max(),
[]{return D::fcvt_w_d(numeric_limits<double>::quiet_NaN());},
"fcvt.w.d, quiet NaN");
expect<int64_t>(numeric_limits<int32_t>::max(),
[]{return D::fcvt_w_d(-numeric_limits<double>::quiet_NaN());},
"fcvt.w.d, quiet -NaN");
expect<int64_t>(numeric_limits<int32_t>::max(),
[]{return D::fcvt_w_d(numeric_limits<double>::signaling_NaN());},
"fcvt.w.d, signaling NaN");
// FCVT.WU.D
expect<uint64_t>(256, []{return D::fcvt_wu_d(256.3);},
"fcvt.wu.d, truncate positive");
expect<uint64_t>(0, []{return D::fcvt_wu_d(-256.2);},
"fcvt.wu.d, truncate negative");
expect<uint64_t>(0, []{return D::fcvt_wu_d(0.0);}, "fcvt.wu.d, 0.0");
expect<uint64_t>(0, []{return D::fcvt_wu_d(-0.0);}, "fcvt.wu.d, -0.0");
expect<uint64_t>(numeric_limits<uint64_t>::max(),
[]{return D::fcvt_wu_d(numeric_limits<double>::max());},
"fcvt.wu.d, overflow");
expect<uint64_t>(0,[]{return D::fcvt_wu_d(numeric_limits<double>::min());},
"fcvt.wu.d, underflow");
expect<uint64_t>(numeric_limits<uint64_t>::max(),
[]{return D::fcvt_wu_d(numeric_limits<double>::infinity());},
"fcvt.wu.d, infinity");
expect<uint64_t>(0,
[]{return D::fcvt_wu_d(-numeric_limits<double>::infinity());},
"fcvt.wu.d, -infinity");
expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL,
[]{return D::fcvt_wu_d(numeric_limits<double>::quiet_NaN());},
"fcvt.wu.d, quiet NaN");
expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL,
[]{return D::fcvt_wu_d(-numeric_limits<double>::quiet_NaN());},
"fcvt.wu.d, quiet -NaN");
expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL,
[]{return D::fcvt_wu_d(numeric_limits<double>::signaling_NaN());},
"fcvt.wu.d, signaling NaN");
// FCVT.D.W
expect<double>(0.0, []{return D::fcvt_d_w(0);}, "fcvt.d.w, 0");
expect<double>(-2147483648.0,
[]{return D::fcvt_d_w(numeric_limits<int32_t>::min());},
"fcvt.d.w, negative");
expect<double>(255.0, []{return D::fcvt_d_w(0xFFFFFFFF000000FFLL);},
"fcvt.d.w, truncate");
// FCVT.D.WU
expect<double>(0.0, []{return D::fcvt_d_wu(0);}, "fcvt.d.wu, 0");
expect<double>(2147483648.0,
[]{return D::fcvt_d_wu(numeric_limits<int32_t>::min());},
"fcvt.d.wu");
expect<double>(255.0,
[]{return D::fcvt_d_wu(0xFFFFFFFF000000FFLL);},
"fcvt.d.wu, truncate");
// FCVT.L.D
expect<int64_t>(256, []{return D::fcvt_l_d(256.3);},
"fcvt.l.d, truncate positive");
expect<int64_t>(-256, []{return D::fcvt_l_d(-256.2);},
"fcvt.l.d, truncate negative");
expect<int64_t>(0, []{return D::fcvt_l_d(0.0);}, "fcvt.l.d, 0.0");
expect<int64_t>(0, []{return D::fcvt_l_d(-0.0);}, "fcvt.l.d, -0.0");
expect<int64_t>(-8589934592LL, []{return D::fcvt_l_d(-8589934592.0);},
"fcvt.l.d, 32-bit overflow");
expect<int64_t>(numeric_limits<int64_t>::max(),
[]{return D::fcvt_l_d(numeric_limits<double>::max());},
"fcvt.l.d, overflow");
expect<int64_t>(0, []{return D::fcvt_l_d(numeric_limits<double>::min());},
"fcvt.l.d, underflow");
expect<int64_t>(numeric_limits<int64_t>::max(),
[]{return D::fcvt_l_d(numeric_limits<double>::infinity());},
"fcvt.l.d, infinity");
expect<int64_t>(numeric_limits<int64_t>::min(),
[]{return D::fcvt_l_d(-numeric_limits<double>::infinity());},
"fcvt.l.d, -infinity");
expect<int64_t>(numeric_limits<int64_t>::max(),
[]{return D::fcvt_l_d(numeric_limits<double>::quiet_NaN());},
"fcvt.l.d, quiet NaN");
expect<int64_t>(numeric_limits<int64_t>::max(),
[]{return D::fcvt_l_d(-numeric_limits<double>::quiet_NaN());},
"fcvt.l.d, quiet -NaN");
expect<int64_t>(numeric_limits<int64_t>::max(),
[]{return D::fcvt_l_d(numeric_limits<double>::signaling_NaN());},
"fcvt.l.d, signaling NaN");
// FCVT.LU.D
expect<uint64_t>(256, []{return D::fcvt_lu_d(256.3);},
"fcvt.lu.d, truncate positive");
expect<uint64_t>(0, []{return D::fcvt_lu_d(-256.2);},
"fcvt.lu.d, truncate negative");
expect<uint64_t>(0, []{return D::fcvt_lu_d(0.0);}, "fcvt.lu.d, 0.0");
expect<uint64_t>(0, []{return D::fcvt_lu_d(-0.0);}, "fcvt.lu.d, -0.0");
expect<uint64_t>(8589934592LL, []{return D::fcvt_lu_d(8589934592.0);},
"fcvt.lu.d, 32-bit overflow");
expect<uint64_t>(numeric_limits<uint64_t>::max(),
[]{return D::fcvt_lu_d(numeric_limits<double>::max());},
"fcvt.lu.d, overflow");
expect<uint64_t>(0,[]{return D::fcvt_lu_d(numeric_limits<double>::min());},
"fcvt.lu.d, underflow");
expect<uint64_t>(numeric_limits<uint64_t>::max(),
[]{return D::fcvt_lu_d(numeric_limits<double>::infinity());},
"fcvt.lu.d, infinity");
expect<uint64_t>(0,
[]{return D::fcvt_lu_d(-numeric_limits<double>::infinity());},
"fcvt.lu.d, -infinity");
expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL,
[]{return D::fcvt_lu_d(numeric_limits<double>::quiet_NaN());},
"fcvt.lu.d, quiet NaN");
expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL,
[]{return D::fcvt_lu_d(-numeric_limits<double>::quiet_NaN());},
"fcvt.lu.d, quiet -NaN");
expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL,
[]{return D::fcvt_lu_d(numeric_limits<double>::signaling_NaN());},
"fcvt.lu.d, signaling NaN");
// FMV.X.D
expect<uint64_t>(0x40091EB851EB851FULL, []{return D::fmv_x_d(3.14);},
"fmv.x.d, positive");
expect<uint64_t>(0xC0091EB851EB851FULL, []{return D::fmv_x_d(-3.14);},
"fmv.x.d, negative");
expect<uint64_t>(0x0000000000000000ULL, []{return D::fmv_x_d(0.0);},
"fmv.x.d, 0.0");
expect<uint64_t>(0x8000000000000000ULL, []{return D::fmv_x_d(-0.0);},
"fmv.x.d, -0.0");
// FCVT.D.L
expect<double>(0.0, []{return D::fcvt_d_l(0);}, "fcvt.d.l, 0");
expect<double>(D::number(0xC3E0000000000000),
[]{return D::fcvt_d_l(numeric_limits<int64_t>::min());},
"fcvt.d.l, negative");
expect<double>(D::number(0xC1EFFFFFE0200000),
[]{return D::fcvt_d_l(0xFFFFFFFF000000FFLL);},
"fcvt.d.l, 32-bit truncate");
// FCVT.D.LU
expect<double>(0.0, []{return D::fcvt_d_lu(0);}, "fcvt.d.lu, 0");
expect<double>(D::number(0x43E0000000000000),
[]{return D::fcvt_d_lu(numeric_limits<int64_t>::min());},
"fcvt.d.lu");
expect<double>(D::number(0x43EFFFFFFFE00000),
[]{return D::fcvt_d_lu(0xFFFFFFFF000000FFLL);},
"fcvt.d.lu, 32-bit truncate");
// FMV.D.X
expect<double>(-numeric_limits<float>::infinity(),
[]{return D::fmv_d_x(0xFFF0000000000000ULL);}, "fmv.d.x");
return 0;
}

View File

@@ -1,321 +0,0 @@
/*
* Copyright (c) 2016 The University of Virginia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cstdint>
#include <limits>
#include "insttest.h"
namespace D
{
constexpr inline uint64_t
bits(double d)
{
return reinterpret_cast<uint64_t&>(d);
}
constexpr inline double
number(uint64_t b)
{
return reinterpret_cast<double&>(b);
}
inline bool
isquietnan(double f)
{
return std::isnan(f) && (bits(f)&0x0008000000000000ULL) != 0;
}
inline bool
issignalingnan(double f)
{
return std::isnan(f) && (bits(f)&0x0008000000000000ULL) == 0;
}
inline double
load(double mem)
{
double fd = std::numeric_limits<double>::signaling_NaN();
asm volatile("fld %0,%1"
: "=f" (fd)
: "m" (mem));
return fd;
}
inline double
store(double fs)
{
double mem = std::numeric_limits<double>::signaling_NaN();
asm volatile("fsd %1,%0" : "=m" (mem) : "f" (fs));
return mem;
}
inline double
fmadd_d(double fs1, double fs2, double fs3)
{
double fd = std::numeric_limits<double>::signaling_NaN();
FR4OP("fmadd.d", fd, fs1, fs2, fs3);
return fd;
}
inline double
fmsub_d(double fs1, double fs2, double fs3)
{
double fd = std::numeric_limits<double>::signaling_NaN();
FR4OP("fmsub.d", fd, fs1, fs2, fs3);
return fd;
}
inline double
fnmsub_d(double fs1, double fs2, double fs3)
{
double fd = std::numeric_limits<double>::signaling_NaN();
FR4OP("fnmsub.d", fd, fs1, fs2, fs3);
return fd;
}
inline double
fnmadd_d(double fs1, double fs2, double fs3)
{
double fd = std::numeric_limits<double>::signaling_NaN();
FR4OP("fnmadd.d", fd, fs1, fs2, fs3);
return fd;
}
inline double
fadd_d(double fs1, double fs2)
{
double fd = std::numeric_limits<double>::signaling_NaN();
FROP("fadd.d", fd, fs1, fs2);
return fd;
}
inline double
fsub_d(double fs1, double fs2)
{
double fd = std::numeric_limits<double>::signaling_NaN();
FROP("fsub.d", fd, fs1, fs2);
return fd;
}
inline double
fmul_d(double fs1, double fs2)
{
double fd = std::numeric_limits<double>::signaling_NaN();
FROP("fmul.d", fd, fs1, fs2);
return fd;
}
inline double
fdiv_d(double fs1, double fs2)
{
double fd = std::numeric_limits<double>::signaling_NaN();
FROP("fdiv.d", fd, fs1, fs2);
return fd;
}
inline double
fsqrt_d(double fs1)
{
double fd = std::numeric_limits<double>::signaling_NaN();
asm volatile("fsqrt.d %0,%1" : "=f" (fd) : "f" (fs1));
return fd;
}
inline double
fsgnj_d(double fs1, double fs2)
{
double fd = std::numeric_limits<double>::signaling_NaN();
FROP("fsgnj.d", fd, fs1, fs2);
return fd;
}
inline double
fsgnjn_d(double fs1, double fs2)
{
double fd = std::numeric_limits<double>::signaling_NaN();
FROP("fsgnjn.d", fd, fs1, fs2);
return fd;
}
inline double
fsgnjx_d(double fs1, double fs2)
{
double fd = std::numeric_limits<double>::signaling_NaN();
FROP("fsgnjx.d", fd, fs1, fs2);
return fd;
}
inline double
fmin_d(double fs1, double fs2)
{
double fd = std::numeric_limits<double>::signaling_NaN();
FROP("fmin.d", fd, fs1, fs2);
return fd;
}
inline double
fmax_d(double fs1, double fs2)
{
double fd = std::numeric_limits<double>::signaling_NaN();
FROP("fmax.d", fd, fs1, fs2);
return fd;
}
inline float
fcvt_s_d(double fs1)
{
float fd = std::numeric_limits<float>::signaling_NaN();
asm volatile("fcvt.s.d %0,%1" : "=f" (fd) : "f" (fs1));
return fd;
}
inline double
fcvt_d_s(float fs1)
{
double fd = std::numeric_limits<double>::signaling_NaN();
asm volatile("fcvt.d.s %0,%1" : "=f" (fd) : "f" (fs1));
return fd;
}
inline bool
feq_d(double fs1, double fs2)
{
bool rd = false;
asm volatile("feq.d %0,%1,%2" : "=r" (rd) : "f" (fs1), "f" (fs2));
return rd;
}
inline bool
flt_d(double fs1, double fs2)
{
bool rd = false;
asm volatile("flt.d %0,%1,%2" : "=r" (rd) : "f" (fs1), "f" (fs2));
return rd;
}
inline bool
fle_d(double fs1, double fs2)
{
bool rd = false;
asm volatile("fle.d %0,%1,%2" : "=r" (rd) : "f" (fs1), "f" (fs2));
return rd;
}
inline uint64_t
fclass_d(double fs1)
{
uint64_t rd = -1;
asm volatile("fclass.d %0,%1" : "=r" (rd) : "f" (fs1));
return rd;
}
inline int64_t
fcvt_w_d(double fs1)
{
int64_t rd = 0;
asm volatile("fcvt.w.d %0,%1" : "=r" (rd) : "f" (fs1));
return rd;
}
inline uint64_t
fcvt_wu_d(double fs1)
{
uint64_t rd = 0;
asm volatile("fcvt.wu.d %0,%1" : "=r" (rd) : "f" (fs1));
return rd;
}
inline float
fcvt_d_w(int64_t rs1)
{
double fd = std::numeric_limits<double>::signaling_NaN();
asm volatile("fcvt.d.w %0,%1" : "=f" (fd) : "r" (rs1));
return fd;
}
inline double
fcvt_d_wu(uint64_t rs1)
{
double fd = std::numeric_limits<double>::signaling_NaN();
asm volatile("fcvt.d.wu %0,%1" : "=f" (fd) : "r" (rs1));
return fd;
}
inline int64_t
fcvt_l_d(double fs1)
{
int64_t rd = 0;
asm volatile("fcvt.l.d %0,%1" : "=r" (rd) : "f" (fs1));
return rd;
}
inline uint64_t
fcvt_lu_d(double fs1)
{
uint64_t rd = 0;
asm volatile("fcvt.lu.d %0,%1" : "=r" (rd) : "f" (fs1));
return rd;
}
inline uint64_t
fmv_x_d(double fs1)
{
uint64_t rd = 0;
asm volatile("fmv.x.d %0,%1" : "=r" (rd) : "f" (fs1));
return rd;
}
inline double
fcvt_d_l(int64_t rs1)
{
double fd = std::numeric_limits<double>::signaling_NaN();
asm volatile("fcvt.d.l %0,%1" : "=f" (fd) : "r" (rs1));
return fd;
}
inline double
fcvt_d_lu(uint64_t rs1)
{
double fd = std::numeric_limits<double>::signaling_NaN();
asm volatile("fcvt.d.lu %0,%1" : "=f" (fd) : "r" (rs1));
return fd;
}
inline double
fmv_d_x(uint64_t rs1)
{
double fd = std::numeric_limits<double>::signaling_NaN();
asm volatile("fmv.d.x %0,%1" : "=f" (fd) : "r" (rs1));
return fd;
}
} // namespace D

View File

@@ -1,692 +0,0 @@
/*
* Copyright (c) 2016 The University of Virginia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstdint>
#include <limits>
#include "insttest.h"
#include "rv64f.h"
int main()
{
using namespace std;
using namespace insttest;
// FLAGS
expect<uint64_t>(0, []{
F::fsflags(0);
return F::frflags();
}, "clear fsflags");
// Memory
expect<float>(3.14, []{return F::load(3.14);}, "flw");
expect<float>(1.816, []{return F::store(1.816);}, "fsw");
// FMADD.S
expect<float>(7.11624, []{return F::fmadd_s(3.14, 1.816, 1.414);},
"fmadd.s");
expect<bool>(true, []{
float fd = F::fmadd_s(numeric_limits<float>::quiet_NaN(), 3.14,
1.816);
return F::isquietnan(fd);
}, "fmadd.s, quiet NaN");
expect<bool>(true, []{
float fd = F::fmadd_s(3.14, numeric_limits<float>::signaling_NaN(),
1.816);
return F::isquietnan(fd);
}, "fmadd.s, signaling NaN");
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fmadd_s(3.14, numeric_limits<float>::infinity(),
1.414);},
"fmadd.s, infinity");
expect<float>(-numeric_limits<float>::infinity(),
[]{return F::fmadd_s(3.14, -numeric_limits<float>::infinity(),
1.414);},
"fmadd.s, -infinity");
// FMSUB.S
expect<float>(4.28824, []{return F::fmsub_s(3.14, 1.816, 1.414);},
"fmsub.s");
expect<bool>(true, []{
float fd = F::fmsub_s(3.14, numeric_limits<float>::quiet_NaN(),
1.816);
return F::isquietnan(fd);
}, "fmsub.s, quiet NaN");
expect<bool>(true, []{
float fd = F::fmsub_s(3.14, 1.816,
numeric_limits<float>::signaling_NaN());
return F::isquietnan(fd);
}, "fmsub.s, signaling NaN");
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fmsub_s(numeric_limits<float>::infinity(), 1.816,
1.414);},
"fmsub.s, infinity");
expect<float>(-numeric_limits<float>::infinity(),
[]{return F::fmsub_s(3.14, -numeric_limits<float>::infinity(),
1.414);},
"fmsub.s, -infinity");
expect<float>(-numeric_limits<float>::infinity(),
[]{return F::fmsub_s(3.14, 1.816,
numeric_limits<float>::infinity());},
"fmsub.s, subtract infinity");
// FNMSUB.S
expect<float>(-4.28824, []{return F::fnmsub_s(3.14, 1.816, 1.414);},
"fnmsub.s");
expect<bool>(true, []{
float fd = F::fnmsub_s(3.14, 1.816,
numeric_limits<float>::quiet_NaN());
return F::isquietnan(fd);
}, "fnmsub.s, quiet NaN");
expect<bool>(true, []{
float fd = F::fnmsub_s(numeric_limits<float>::signaling_NaN(),
1.816, 1.414);
return F::isquietnan(fd);
}, "fnmsub.s, signaling NaN");
expect<float>(-numeric_limits<float>::infinity(),
[]{return F::fnmsub_s(numeric_limits<float>::infinity(),
1.816, 1.414);},
"fnmsub.s, infinity");
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fnmsub_s(3.14, -numeric_limits<float>::infinity(),
1.414);},
"fnmsub.s, -infinity");
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fnmsub_s(3.14, 1.816,
numeric_limits<float>::infinity());},
"fnmsub.s, subtract infinity");
// FNMADD.S
expect<float>(-7.11624, []{return F::fnmadd_s(3.14, 1.816, 1.414);},
"fnmadd.s");
expect<bool>(true, []{
float fd = F::fnmadd_s(numeric_limits<float>::quiet_NaN(), 3.14,
1.816);
return F::isquietnan(fd);
}, "fnmadd.s, quiet NaN");
expect<bool>(true, []{
float fd = F::fnmadd_s(3.14,numeric_limits<float>::signaling_NaN(),
1.816);
return F::isquietnan(fd);
}, "fnmadd.s, signaling NaN");
expect<float>(-numeric_limits<float>::infinity(),
[]{return F::fnmadd_s(3.14, numeric_limits<float>::infinity(),
1.414);},
"fnmadd.s, infinity");
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fnmadd_s(3.14, -numeric_limits<float>::infinity(),
1.414);},
"fnmadd.s, -infinity");
// FADD.S
expect<float>(4.554, []{return F::fadd_s(3.14, 1.414);}, "fadd.s");
expect<bool>(true, []{
float fd = F::fadd_s(numeric_limits<float>::quiet_NaN(), 1.414);
return F::isquietnan(fd);
}, "fadd.s, quiet NaN");
expect<bool>(true, []{
float fd = F::fadd_s(3.14, numeric_limits<float>::signaling_NaN());
return F::isquietnan(fd);
}, "fadd.s, signaling NaN");
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fadd_s(3.14, numeric_limits<float>::infinity());},
"fadd.s, infinity");
expect<float>(-numeric_limits<float>::infinity(),
[]{return F::fadd_s(-numeric_limits<float>::infinity(), 1.816);},
"fadd.s, -infinity");
// FSUB.S
expect<float>(F::number(0xbfdced92), []{return F::fsub_s(1.414, 3.14);},
"fsub.s");
expect<bool>(true, []{
float fd = F::fsub_s(numeric_limits<float>::quiet_NaN(), 1.414);
return F::isquietnan(fd);
}, "fsub.s, quiet NaN");
expect<bool>(true, []{
float fd = F::fsub_s(3.14, numeric_limits<float>::signaling_NaN());
return F::isquietnan(fd);
}, "fsub.s, signaling NaN");
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fsub_s(numeric_limits<float>::infinity(), 3.14);},
"fsub.s, infinity");
expect<float>(-numeric_limits<float>::infinity(),
[]{return F::fsub_s(-numeric_limits<float>::infinity(), 3.14);},
"fsub.s, -infinity");
expect<float>(-numeric_limits<float>::infinity(),
[]{return F::fsub_s(1.414, numeric_limits<float>::infinity());},
"fsub.s, subtract infinity");
// FMUL.S
expect<float>(F::number(0x4024573b), []{return F::fmul_s(1.816, 1.414);},
"fmul.s");
expect<bool>(true, []{
float fd = F::fmul_s(numeric_limits<float>::quiet_NaN(), 1.414);
return F::isquietnan(fd);
}, "fmul.s, quiet NaN");
expect<bool>(true, []{
float fd = F::fmul_s(1.816,
numeric_limits<float>::signaling_NaN());
return F::isquietnan(fd);
}, "fmul.s, signaling NaN");
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fmul_s(numeric_limits<float>::infinity(), 2.718);},
"fmul.s, infinity");
expect<float>(-numeric_limits<float>::infinity(),
[]{return F::fmul_s(2.5966, -numeric_limits<float>::infinity());},
"fmul.s, -infinity");
expect<bool>(true, []{
float fd = F::fmul_s(0.0, numeric_limits<float>::infinity());
return F::isquietnan(fd);
}, "fmul.s, 0*infinity");
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fmul_s(numeric_limits<float>::max(), 2.0);},
"fmul.s, overflow");
expect<float>(0.0,
[]{return F::fmul_s(numeric_limits<float>::min(),
numeric_limits<float>::min());},
"fmul.s, underflow");
// FDIV.S
expect<float>(2.5, []{return F::fdiv_s(10.0, 4.0);}, "fdiv.s");
expect<bool>(true, []{
float fd = F::fdiv_s(numeric_limits<float>::quiet_NaN(), 4.0);
return F::isquietnan(fd);
}, "fdiv.s, quiet NaN");
expect<bool>(true, []{
float fd = F::fdiv_s(10.0, numeric_limits<float>::signaling_NaN());
return F::isquietnan(fd);
}, "fdiv.s, signaling NaN");
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fdiv_s(10.0, 0.0);}, "fdiv.s/0");
expect<float>(0.0,
[]{return F::fdiv_s(10.0, numeric_limits<float>::infinity());},
"fdiv.s/infinity");
expect<bool>(true, []{
float fd = F::fdiv_s(numeric_limits<float>::infinity(),
numeric_limits<float>::infinity());
return F::isquietnan(fd);
}, "fdiv.s, infinity/infinity");
expect<bool>(true, []{
float fd = F::fdiv_s(0.0, 0.0);
return F::isquietnan(fd);
}, "fdiv.s, 0/0");
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fdiv_s(numeric_limits<float>::infinity(), 0.0);},
"fdiv.s, infinity/0");
expect<float>(0.0,
[]{return F::fdiv_s(0.0, numeric_limits<float>::infinity());},
"fdiv.s, 0/infinity");
expect<float>(0.0,
[]{return F::fdiv_s(numeric_limits<float>::min(),
numeric_limits<float>::max());},
"fdiv.s, underflow");
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fdiv_s(numeric_limits<float>::max(),
numeric_limits<float>::min());},
"fdiv.s, overflow");
// FSQRT.S
expect<float>(0.3, []{return F::fsqrt_s(0.09);}, "fsqrt.s");
expect<bool>(true, []{
float fd = F::fsqrt_s(-1.0);
return F::isquietnan(fd);
}, "fsqrt.s, NaN");
expect<bool>(true, []{
float fd = F::fsqrt_s(numeric_limits<float>::quiet_NaN());
return F::isquietnan(fd);
}, "fsqrt.s, quiet NaN");
expect<bool>(true, []{
float fd = F::fsqrt_s(numeric_limits<float>::signaling_NaN());
return F::isquietnan(fd);
}, "fsqrt.s, signaling NaN");
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fsqrt_s(numeric_limits<float>::infinity());},
"fsqrt.s, infinity");
// FSGNJ.S
expect<float>(1.0, []{return F::fsgnj_s(1.0, 25.0);}, "fsgnj.s, ++");
expect<float>(-1.0, []{return F::fsgnj_s(1.0, -25.0);}, "fsgnj.s, +-");
expect<float>(1.0, []{return F::fsgnj_s(-1.0, 25.0);}, "fsgnj.s, -+");
expect<float>(-1.0, []{return F::fsgnj_s(-1.0, -25.0);}, "fsgnj.s, --");
expect<bool>(true, []{
float fd = F::fsgnj_s(numeric_limits<float>::quiet_NaN(), -4.0);
return F::isquietnan(fd);
}, "fsgnj.s, quiet NaN");
expect<bool>(true, []{
float fd = F::fsgnj_s(numeric_limits<float>::signaling_NaN(),
-4.0);
return F::issignalingnan(fd);
}, "fsgnj.s, signaling NaN");
expect<float>(4.0, []{return F::fsgnj_s(4.0,
numeric_limits<float>::quiet_NaN());}, "fsgnj.s, inject NaN");
expect<float>(-4.0,
[]{return F::fsgnj_s(4.0, -numeric_limits<float>::quiet_NaN());},
"fsgnj.s, inject -NaN");
// FSGNJN.S
expect<float>(-1.0, []{return F::fsgnjn_s(1.0, 25.0);}, "fsgnjn.s, ++");
expect<float>(1.0, []{return F::fsgnjn_s(1.0, -25.0);}, "fsgnjn.s, +-");
expect<float>(-1.0, []{return F::fsgnjn_s(-1.0, 25.0);}, "fsgnjn.s, -+");
expect<float>(1.0, []{return F::fsgnjn_s(-1.0, -25.0);}, "fsgnjn.s, --");
expect<bool>(true, []{
float fd = F::fsgnjn_s(numeric_limits<float>::quiet_NaN(), -4.0);
return F::isquietnan(fd);
}, "fsgnjn.s, quiet NaN");
expect<bool>(true, []{
float fd = F::fsgnjn_s(numeric_limits<float>::signaling_NaN(),
-4.0);
return F::issignalingnan(fd);
}, "fsgnjn.s, signaling NaN");
expect<float>(-4.0,
[]{return F::fsgnjn_s(4.0, numeric_limits<float>::quiet_NaN());},
"fsgnjn.s, inject NaN");
expect<float>(4.0,
[]{return F::fsgnjn_s(4.0, -numeric_limits<float>::quiet_NaN());},
"fsgnjn.s, inject NaN");
// FSGNJX.S
expect<float>(1.0, []{return F::fsgnjx_s(1.0, 25.0);}, "fsgnjx.s, ++");
expect<float>(-1.0, []{return F::fsgnjx_s(1.0, -25.0);}, "fsgnjx.s, +-");
expect<float>(-1.0, []{return F::fsgnjx_s(-1.0, 25.0);}, "fsgnjx.s, -+");
expect<float>(1.0, []{return F::fsgnjx_s(-1.0, -25.0);}, "fsgnjx.s, --");
expect<bool>(true, []{
float fd = F::fsgnjx_s(numeric_limits<float>::quiet_NaN(), -4.0);
return F::isquietnan(fd);
}, "fsgnjx.s, quiet NaN");
expect<bool>(true, []{
float fd = F::fsgnjx_s(numeric_limits<float>::signaling_NaN(),
-4.0);
return F::issignalingnan(fd);
}, "fsgnjx.s, signaling NaN");
expect<float>(4.0,
[]{return F::fsgnjx_s(4.0, numeric_limits<float>::quiet_NaN());},
"fsgnjx.s, inject NaN");
expect<float>(-4.0,
[]{return F::fsgnjx_s(4.0, -numeric_limits<float>::quiet_NaN());},
"fsgnjx.s, inject -NaN");
// FMIN.S
expect<float>(2.718, []{return F::fmin_s(3.14, 2.718);}, "fmin.s");
expect<float>(-numeric_limits<float>::infinity(),
[]{return F::fmin_s(-numeric_limits<float>::infinity(),
numeric_limits<float>::min());},
"fmin.s, -infinity");
expect<float>(numeric_limits<float>::max(),
[]{return F::fmin_s(numeric_limits<float>::infinity(),
numeric_limits<float>::max());},
"fmin.s, infinity");
expect<float>(-1.414,
[]{return F::fmin_s(numeric_limits<float>::quiet_NaN(), -1.414);},
"fmin.s, quiet NaN first");
expect<float>(2.718,
[]{return F::fmin_s(2.718, numeric_limits<float>::quiet_NaN());},
"fmin.s, quiet NaN second");
expect<bool>(true, []{
float fd = F::fmin_s(numeric_limits<float>::quiet_NaN(),
numeric_limits<float>::quiet_NaN());
return F::isquietnan(fd);
}, "fmin.s, quiet NaN both");
expect<float>(3.14,
[]{return F::fmin_s(numeric_limits<float>::signaling_NaN(),
3.14);},
"fmin.s, signaling NaN first");
expect<float>(1.816,
[]{return F::fmin_s(1.816,
numeric_limits<float>::signaling_NaN());},
"fmin.s, signaling NaN second");
expect<bool>(true, []{
float fd = F::fmin_s(numeric_limits<float>::signaling_NaN(),
numeric_limits<float>::signaling_NaN());
return F::issignalingnan(fd);
}, "fmin.s, signaling NaN both");
// FMAX.S
expect<float>(3.14, []{return F::fmax_s(3.14, 2.718);}, "fmax.s");
expect<float>(numeric_limits<float>::min(),
[]{return F::fmax_s(-numeric_limits<float>::infinity(),
numeric_limits<float>::min());},
"fmax.s, -infinity");
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fmax_s(numeric_limits<float>::infinity(),
numeric_limits<float>::max());},
"fmax.s, infinity");
expect<float>(-1.414,
[]{return F::fmax_s(numeric_limits<float>::quiet_NaN(), -1.414);},
"fmax.s, quiet NaN first");
expect<float>(2.718,
[]{return F::fmax_s(2.718, numeric_limits<float>::quiet_NaN());},
"fmax.s, quiet NaN second");
expect<bool>(true, []{
float fd = F::fmax_s(numeric_limits<float>::quiet_NaN(),
numeric_limits<float>::quiet_NaN());
return F::isquietnan(fd);
}, "fmax.s, quiet NaN both");
expect<float>(3.14,
[]{return F::fmax_s(numeric_limits<float>::signaling_NaN(),
3.14);},
"fmax.s, signaling NaN first");
expect<float>(1.816, []{return F::fmax_s(1.816,
numeric_limits<float>::signaling_NaN());},
"fmax.s, signaling NaN second");
expect<bool>(true, []{
float fd = F::fmax_s(numeric_limits<float>::signaling_NaN(),
numeric_limits<float>::signaling_NaN());
return F::issignalingnan(fd);
}, "fmax.s, signaling NaN both");
// FCVT.W.S
expect<int64_t>(256, []{return F::fcvt_w_s(256.3);},
"fcvt.w.s, truncate positive");
expect<int64_t>(-256, []{return F::fcvt_w_s(-256.2);},
"fcvt.w.s, truncate negative");
expect<int64_t>(0, []{return F::fcvt_w_s(0.0);}, "fcvt.w.s, 0.0");
expect<int64_t>(0, []{return F::fcvt_w_s(-0.0);}, "fcvt.w.s, -0.0");
expect<int64_t>(numeric_limits<int32_t>::max(),
[]{return F::fcvt_w_s(numeric_limits<float>::max());},
"fcvt.w.s, overflow");
expect<int64_t>(0, []{return F::fcvt_w_s(numeric_limits<float>::min());},
"fcvt.w.s, underflow");
expect<int64_t>(numeric_limits<int32_t>::max(),
[]{return F::fcvt_w_s(numeric_limits<float>::infinity());},
"fcvt.w.s, infinity");
expect<int64_t>(numeric_limits<int32_t>::min(),
[]{return F::fcvt_w_s(-numeric_limits<float>::infinity());},
"fcvt.w.s, -infinity");
expect<int64_t>(numeric_limits<int32_t>::max(),
[]{return F::fcvt_w_s(numeric_limits<float>::quiet_NaN());},
"fcvt.w.s, quiet NaN");
expect<int64_t>(numeric_limits<int32_t>::max(),
[]{return F::fcvt_w_s(-numeric_limits<float>::quiet_NaN());},
"fcvt.w.s, quiet -NaN");
expect<int64_t>(numeric_limits<int32_t>::max(),
[]{return F::fcvt_w_s(numeric_limits<float>::signaling_NaN());},
"fcvt.w.s, signaling NaN");
// FCVT.WU.S
expect<uint64_t>(256, []{return F::fcvt_wu_s(256.3);},
"fcvt.wu.s, truncate positive");
expect<uint64_t>(0, []{return F::fcvt_wu_s(-256.2);},
"fcvt.wu.s, truncate negative");
expect<uint64_t>(0, []{return F::fcvt_wu_s(0.0);}, "fcvt.wu.s, 0.0");
expect<uint64_t>(0, []{return F::fcvt_wu_s(-0.0);}, "fcvt.wu.s, -0.0");
expect<uint64_t>(numeric_limits<uint64_t>::max(),
[]{return F::fcvt_wu_s(numeric_limits<float>::max());},
"fcvt.wu.s, overflow");
expect<uint64_t>(0, []{return F::fcvt_wu_s(numeric_limits<float>::min());},
"fcvt.wu.s, underflow");
expect<uint64_t>(numeric_limits<uint64_t>::max(),
[]{return F::fcvt_wu_s(numeric_limits<float>::infinity());},
"fcvt.wu.s, infinity");
expect<uint64_t>(0,
[]{return F::fcvt_wu_s(-numeric_limits<float>::infinity());},
"fcvt.wu.s, -infinity");
expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL,
[]{return F::fcvt_wu_s(numeric_limits<float>::quiet_NaN());},
"fcvt.wu.s, quiet NaN");
expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL,
[]{return F::fcvt_wu_s(-numeric_limits<float>::quiet_NaN());},
"fcvt.wu.s, quiet -NaN");
expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL,
[]{return F::fcvt_wu_s(numeric_limits<float>::signaling_NaN());},
"fcvt.wu.s, signaling NaN");
// FMV.X.S
expect<uint64_t>(0x000000004048F5C3ULL, []{return F::fmv_x_s(3.14);},
"fmv.x.s, positive");
expect<uint64_t>(0xFFFFFFFFC048F5C3ULL, []{return F::fmv_x_s(-3.14);},
"fmv.x.s, negative");
expect<uint64_t>(0x0000000000000000ULL, []{return F::fmv_x_s(0.0);},
"fmv.x.s, 0.0");
expect<uint64_t>(0xFFFFFFFF80000000ULL, []{return F::fmv_x_s(-0.0);},
"fmv.x.s, -0.0");
// FEQ.S
expect<bool>(true, []{return F::feq_s(1.414, 1.414);}, "feq.s, equal");
expect<bool>(false, []{return F::feq_s(2.718, 1.816);},
"feq.s, not equal");
expect<bool>(true, []{return F::feq_s(0.0, -0.0);}, "feq.s, 0 == -0");
expect<bool>(false,
[]{return F::feq_s(numeric_limits<float>::quiet_NaN(), -1.0);},
"feq.s, quiet NaN first");
expect<bool>(false,
[]{return F::feq_s(2.0, numeric_limits<float>::quiet_NaN());},
"feq.s, quiet NaN second");
expect<bool>(false,
[]{return F::feq_s(numeric_limits<float>::quiet_NaN(),
numeric_limits<float>::quiet_NaN());},
"feq.s, quiet NaN both");
expect<bool>(false,
[]{return F::feq_s(numeric_limits<float>::signaling_NaN(), -1.0);},
"feq.s, signaling NaN first");
expect<bool>(false,
[]{return F::feq_s(2.0, numeric_limits<float>::signaling_NaN());},
"feq.s, signaling NaN second");
expect<bool>(false,
[]{return F::feq_s(numeric_limits<float>::signaling_NaN(),
numeric_limits<float>::signaling_NaN());},
"feq.s, signaling NaN both");
// FLT.S
expect<bool>(false, []{return F::flt_s(1.414, 1.414);}, "flt.s, equal");
expect<bool>(true, []{return F::flt_s(1.816, 2.718);}, "flt.s, less");
expect<bool>(false, []{return F::flt_s(2.718, 1.816);}, "flt.s, greater");
expect<bool>(false,
[]{return F::flt_s(numeric_limits<float>::quiet_NaN(), -1.0);},
"flt.s, quiet NaN first");
expect<bool>(false,
[]{return F::flt_s(2.0, numeric_limits<float>::quiet_NaN());},
"flt.s, quiet NaN second");
expect<bool>(false,
[]{return F::flt_s(numeric_limits<float>::quiet_NaN(),
numeric_limits<float>::quiet_NaN());},
"flt.s, quiet NaN both");
expect<bool>(false,
[]{return F::flt_s(numeric_limits<float>::signaling_NaN(), -1.0);},
"flt.s, signaling NaN first");
expect<bool>(false,
[]{return F::flt_s(2.0, numeric_limits<float>::signaling_NaN());},
"flt.s, signaling NaN second");
expect<bool>(false,
[]{return F::flt_s(numeric_limits<float>::signaling_NaN(),
numeric_limits<float>::signaling_NaN());},
"flt.s, signaling NaN both");
// FLE.S
expect<bool>(true, []{return F::fle_s(1.414, 1.414);}, "fle.s, equal");
expect<bool>(true, []{return F::fle_s(1.816, 2.718);}, "fle.s, less");
expect<bool>(false, []{return F::fle_s(2.718, 1.816);}, "fle.s, greater");
expect<bool>(true, []{return F::fle_s(0.0, -0.0);}, "fle.s, 0 == -0");
expect<bool>(false,
[]{return F::fle_s(numeric_limits<float>::quiet_NaN(), -1.0);},
"fle.s, quiet NaN first");
expect<bool>(false,
[]{return F::fle_s(2.0, numeric_limits<float>::quiet_NaN());},
"fle.s, quiet NaN second");
expect<bool>(false,
[]{return F::fle_s(numeric_limits<float>::quiet_NaN(),
numeric_limits<float>::quiet_NaN());},
"fle.s, quiet NaN both");
expect<bool>(false,
[]{return F::fle_s(numeric_limits<float>::signaling_NaN(), -1.0);},
"fle.s, signaling NaN first");
expect<bool>(false,
[]{return F::fle_s(2.0, numeric_limits<float>::signaling_NaN());},
"fle.s, signaling NaN second");
expect<bool>(false,
[]{return F::fle_s(numeric_limits<float>::signaling_NaN(),
numeric_limits<float>::signaling_NaN());},
"fle.s, signaling NaN both");
// FCLASS.S
expect<uint64_t>(0x1,
[]{return F::fclass_s(-numeric_limits<float>::infinity());},
"fclass.s, -infinity");
expect<uint64_t>(0x2, []{return F::fclass_s(-3.14);}, "fclass.s, -normal");
expect<uint64_t>(0x4, []{return F::fclass_s(F::number(0x807FFFFF));},
"fclass.s, -subnormal");
expect<uint64_t>(0x8, []{return F::fclass_s(-0.0);}, "fclass.s, -0.0");
expect<uint64_t>(0x10, []{return F::fclass_s(0.0);}, "fclass.s, 0.0");
expect<uint64_t>(0x20, []{return F::fclass_s(F::number(0x007FFFFF));},
"fclass.s, subnormal");
expect<uint64_t>(0x40, []{return F::fclass_s(1.816);}, "fclass.s, normal");
expect<uint64_t>(0x80,
[]{return F::fclass_s(numeric_limits<float>::infinity());},
"fclass.s, infinity");
expect<uint64_t>(0x100,
[]{return F::fclass_s(numeric_limits<float>::signaling_NaN());},
"fclass.s, signaling NaN");
expect<uint64_t>(0x200,
[]{return F::fclass_s(numeric_limits<float>::quiet_NaN());},
"fclass.s, quiet NaN");
// FCVT.S.W
expect<float>(0.0, []{return F::fcvt_s_w(0);}, "fcvt.s.w, 0");
expect<float>(-2147483648.0,
[]{return F::fcvt_s_w(numeric_limits<int32_t>::min());},
"fcvt.s.w, negative");
expect<float>(255.0, []{return F::fcvt_s_w(0xFFFFFFFF000000FFLL);},
"fcvt.s.w, truncate");
// FCVT.S.WU
expect<float>(0.0, []{return F::fcvt_s_wu(0);}, "fcvt.s.wu, 0");
expect<float>(2147483648.0,
[]{return F::fcvt_s_wu(numeric_limits<int32_t>::min());},
"fcvt.s.wu");
expect<float>(255.0, []{return F::fcvt_s_wu(0xFFFFFFFF000000FFLL);},
"fcvt.s.wu, truncate");
// FMV.S.X
expect<float>(numeric_limits<float>::infinity(),
[]{return F::fmv_s_x(0x7F800000);}, "fmv.s.x");
expect<float>(-0.0, []{return F::fmv_s_x(0xFFFFFFFF80000000ULL);},
"fmv.s.x, truncate");
// FCSR functions
int rm = F::frrm();
expect<uint64_t>(0x7, []{ // FSRM
F::fsrm(-1);
return F::frrm();
}, "fsrm");
expect<uint64_t>(0x1F, []{ // FSFLAGS
F::fsflags(0);
F::fsflags(-1);
return F::frflags();
}, "fsflags");
expect<uint64_t>(0xFF, []{ // FSCSR
F::fsflags(0);
F::fsrm(0);
F::fscsr(-1);
return F::frcsr();
}, "fscsr");
expect<int>(rm << 5, [=]{
F::fscsr(0);
F::fsrm(rm);
return F::frcsr();
}, "restore initial round mode");
F::fsflags(0);
// FCVT.L.S
expect<int64_t>(256, []{return F::fcvt_l_s(256.3);},
"fcvt.l.s, truncate positive");
expect<int64_t>(-256, []{return F::fcvt_l_s(-256.2);},
"fcvt.l.s, truncate negative");
expect<int64_t>(0, []{return F::fcvt_l_s(0.0);}, "fcvt.l.s, 0.0");
expect<int64_t>(0, []{return F::fcvt_l_s(-0.0);}, "fcvt.l.s, -0.0");
expect<int64_t>(-8589934592LL, []{return F::fcvt_l_s(-8589934592.0);},
"fcvt.l.s, 32-bit overflow");
expect<int64_t>(numeric_limits<int64_t>::max(),
[]{return F::fcvt_l_s(numeric_limits<float>::max());},
"fcvt.l.s, overflow");
expect<int64_t>(0, []{return F::fcvt_l_s(numeric_limits<float>::min());},
"fcvt.l.s, underflow");
expect<int64_t>(numeric_limits<int64_t>::max(),
[]{return F::fcvt_l_s(numeric_limits<float>::infinity());},
"fcvt.l.s, infinity");
expect<int64_t>(numeric_limits<int64_t>::min(),
[]{return F::fcvt_l_s(-numeric_limits<float>::infinity());},
"fcvt.l.s, -infinity");
expect<int64_t>(numeric_limits<int64_t>::max(),
[]{return F::fcvt_l_s(numeric_limits<float>::quiet_NaN());},
"fcvt.l.s, quiet NaN");
expect<int64_t>(numeric_limits<int64_t>::max(),
[]{return F::fcvt_l_s(-numeric_limits<float>::quiet_NaN());},
"fcvt.l.s, quiet -NaN");
expect<int64_t>(numeric_limits<int64_t>::max(),
[]{return F::fcvt_l_s(numeric_limits<float>::signaling_NaN());},
"fcvt.l.s, signaling NaN");
// FCVT.LU.S
expect<uint64_t>(256, []{return F::fcvt_lu_s(256.3);},
"fcvt.lu.s, truncate positive");
expect<uint64_t>(0, []{return F::fcvt_lu_s(-256.2);},
"fcvt.lu.s, truncate negative");
expect<uint64_t>(0, []{return F::fcvt_lu_s(0.0);}, "fcvt.lu.s, 0.0");
expect<uint64_t>(0, []{return F::fcvt_lu_s(-0.0);}, "fcvt.lu.s, -0.0");
expect<uint64_t>(8589934592LL,
[]{return F::fcvt_lu_s(8589934592.0);},
"fcvt.lu.s, 32-bit overflow");
expect<uint64_t>(numeric_limits<uint64_t>::max(),
[]{return F::fcvt_lu_s(numeric_limits<float>::max());},
"fcvt.lu.s, overflow");
expect<uint64_t>(0, []{return F::fcvt_lu_s(numeric_limits<float>::min());},
"fcvt.lu.s, underflow");
expect<uint64_t>(numeric_limits<uint64_t>::max(),
[]{return F::fcvt_lu_s(numeric_limits<float>::infinity());},
"fcvt.lu.s, infinity");
expect<uint64_t>(0,
[]{return F::fcvt_lu_s(-numeric_limits<float>::infinity());},
"fcvt.lu.s, -infinity");
expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL,
[]{return F::fcvt_lu_s(numeric_limits<float>::quiet_NaN());},
"fcvt.lu.s, quiet NaN");
expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL,
[]{return F::fcvt_lu_s(-numeric_limits<float>::quiet_NaN());},
"fcvt.lu.s, quiet -NaN");
expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL,
[]{return F::fcvt_lu_s(numeric_limits<float>::signaling_NaN());},
"fcvt.lu.s, signaling NaN");
// FCVT.S.L
expect<float>(0.0, []{return F::fcvt_s_l(0);}, "fcvt.s.l, 0");
expect<float>(-9.223372e18,
[]{return F::fcvt_s_l(numeric_limits<int64_t>::min());},
"fcvt.s.l, negative");
expect<float>(-4.29496704e9, []{return F::fcvt_s_l(0xFFFFFFFF000000FFLL);},
"fcvt.s.l, 32-bit truncate");
// FCVT.S.LU
expect<float>(0.0, []{return F::fcvt_s_lu(0);}, "fcvt.s.lu, 0");
expect<float>(9.223372e18,
[]{return F::fcvt_s_lu(numeric_limits<int64_t>::min());},
"fcvt.s.lu");
expect<float>(1.8446744e19, []{return F::fcvt_s_lu(0xFFFFFFFF000000FFLL);},
"fcvt.s.lu, 32-bit truncate");
return 0;
}

View File

@@ -1,355 +0,0 @@
/*
* Copyright (c) 2016 The University of Virginia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cstdint>
#include <limits>
#include "insttest.h"
namespace F
{
constexpr inline uint32_t
bits(float f)
{
return reinterpret_cast<uint32_t&>(f);
}
constexpr inline float
number(uint32_t b)
{
return reinterpret_cast<float&>(b);
}
inline bool
isquietnan(float f)
{
return std::isnan(f) && (bits(f)&0x00400000) != 0;
}
inline bool
issignalingnan(float f)
{
return std::isnan(f) && (bits(f)&0x00400000) == 0;
}
inline float
load(float mem)
{
float fd = std::numeric_limits<float>::signaling_NaN();
asm volatile("flw %0,%1"
: "=f" (fd)
: "m" (mem));
return fd;
}
inline float
store(float fs)
{
float mem = std::numeric_limits<float>::signaling_NaN();
asm volatile("fsw %1,%0" : "=m" (mem) : "f" (fs));
return mem;
}
inline uint64_t
frflags()
{
uint64_t rd = -1;
asm volatile("frflags %0" : "=r" (rd));
return rd;
}
inline uint64_t
fsflags(uint64_t rs1)
{
uint64_t rd = -1;
asm volatile("fsflags %0,%1" : "=r" (rd) : "r" (rs1));
return rd;
}
inline float
fmadd_s(float fs1, float fs2, float fs3)
{
float fd = std::numeric_limits<float>::signaling_NaN();
FR4OP("fmadd.s", fd, fs1, fs2, fs3);
return fd;
}
inline float
fmsub_s(float fs1, float fs2, float fs3)
{
float fd = std::numeric_limits<float>::signaling_NaN();
FR4OP("fmsub.s", fd, fs1, fs2, fs3);
return fd;
}
inline float
fnmsub_s(float fs1, float fs2, float fs3)
{
float fd = std::numeric_limits<float>::signaling_NaN();
FR4OP("fnmsub.s", fd, fs1, fs2, fs3);
return fd;
}
inline float
fnmadd_s(float fs1, float fs2, float fs3)
{
float fd = std::numeric_limits<float>::signaling_NaN();
FR4OP("fnmadd.s", fd, fs1, fs2, fs3);
return fd;
}
inline float
fadd_s(float fs1, float fs2)
{
float fd = std::numeric_limits<float>::signaling_NaN();
FROP("fadd.s", fd, fs1, fs2);
return fd;
}
inline float
fsub_s(float fs1, float fs2)
{
float fd = std::numeric_limits<float>::signaling_NaN();
FROP("fsub.s", fd, fs1, fs2);
return fd;
}
inline float
fmul_s(float fs1, float fs2)
{
float fd = std::numeric_limits<float>::signaling_NaN();
FROP("fmul.s", fd, fs1, fs2);
return fd;
}
inline float
fdiv_s(float fs1, float fs2)
{
float fd = 0.0;
FROP("fdiv.s", fd, fs1, fs2);
return fd;
}
inline float
fsqrt_s(float fs1)
{
float fd = std::numeric_limits<float>::infinity();
asm volatile("fsqrt.s %0,%1" : "=f" (fd) : "f" (fs1));
return fd;
}
inline float
fsgnj_s(float fs1, float fs2)
{
float fd = std::numeric_limits<float>::signaling_NaN();
FROP("fsgnj.s", fd, fs1, fs2);
return fd;
}
inline float
fsgnjn_s(float fs1, float fs2)
{
float fd = std::numeric_limits<float>::signaling_NaN();
FROP("fsgnjn.s", fd, fs1, fs2);
return fd;
}
inline float
fsgnjx_s(float fs1, float fs2)
{
float fd = std::numeric_limits<float>::signaling_NaN();
FROP("fsgnjx.s", fd, fs1, fs2);
return fd;
}
inline float
fmin_s(float fs1, float fs2)
{
float fd = std::numeric_limits<float>::signaling_NaN();
FROP("fmin.s", fd, fs1, fs2);
return fd;
}
inline float
fmax_s(float fs1, float fs2)
{
float fd = std::numeric_limits<float>::signaling_NaN();
FROP("fmax.s", fd, fs1, fs2);
return fd;
}
inline int64_t
fcvt_w_s(float fs1)
{
int64_t rd = 0;
asm volatile("fcvt.w.s %0,%1" : "=r" (rd) : "f" (fs1));
return rd;
}
inline uint64_t
fcvt_wu_s(float fs1)
{
uint64_t rd = 0;
asm volatile("fcvt.wu.s %0,%1" : "=r" (rd) : "f" (fs1));
return rd;
}
inline uint64_t
fmv_x_s(float fs1)
{
uint64_t rd = 0;
asm volatile("fmv.x.s %0,%1" : "=r" (rd) : "f" (fs1));
return rd;
}
inline bool
feq_s(float fs1, float fs2)
{
bool rd = false;
asm volatile("feq.s %0,%1,%2" : "=r" (rd) : "f" (fs1), "f" (fs2));
return rd;
}
inline bool
flt_s(float fs1, float fs2)
{
bool rd = false;
asm volatile("flt.s %0,%1,%2" : "=r" (rd) : "f" (fs1), "f" (fs2));
return rd;
}
inline bool
fle_s(float fs1, float fs2)
{
bool rd = false;
asm volatile("fle.s %0,%1,%2" : "=r" (rd) : "f" (fs1), "f" (fs2));
return rd;
}
inline uint64_t
fclass_s(float fs1)
{
uint64_t rd = -1;
asm volatile("fclass.s %0,%1" : "=r" (rd) : "f" (fs1));
return rd;
}
inline float
fcvt_s_w(int64_t rs1)
{
float fd = std::numeric_limits<float>::signaling_NaN();
asm volatile("fcvt.s.w %0,%1" : "=f" (fd) : "r" (rs1));
return fd;
}
inline float
fcvt_s_wu(uint64_t rs1)
{
float fd = std::numeric_limits<float>::signaling_NaN();
asm volatile("fcvt.s.wu %0,%1" : "=f" (fd) : "r" (rs1));
return fd;
}
inline float
fmv_s_x(uint64_t rs1)
{
float fd = std::numeric_limits<float>::signaling_NaN();
asm volatile("fmv.s.x %0,%1" : "=f" (fd) : "r" (rs1));
return fd;
}
inline uint64_t
frcsr()
{
uint64_t rd = -1;
asm volatile("frcsr %0" : "=r" (rd));
return rd;
}
inline uint64_t
frrm()
{
uint64_t rd = -1;
asm volatile("frrm %0" : "=r" (rd));
return rd;
}
inline uint64_t
fscsr(uint64_t rs1)
{
uint64_t rd = -1;
asm volatile("fscsr %0,%1" : "=r" (rd) : "r" (rs1));
return rd;
}
inline uint64_t
fsrm(uint64_t rs1)
{
uint64_t rd = -1;
asm volatile("fsrm %0,%1" : "=r" (rd) : "r" (rs1));
return rd;
}
inline int64_t
fcvt_l_s(float fs1)
{
int64_t rd = 0;
asm volatile("fcvt.l.s %0,%1" : "=r" (rd) : "f" (fs1));
return rd;
}
inline uint64_t
fcvt_lu_s(float fs1)
{
int64_t rd = 0;
asm volatile("fcvt.lu.s %0,%1" : "=r" (rd) : "f" (fs1));
return rd;
}
inline float
fcvt_s_l(int64_t rs1)
{
float fd = std::numeric_limits<float>::signaling_NaN();
asm volatile("fcvt.s.l %0,%1" : "=f" (fd) : "r" (rs1));
return fd;
}
inline float
fcvt_s_lu(uint64_t rs1)
{
float fd = std::numeric_limits<float>::signaling_NaN();
asm volatile("fcvt.s.lu %0,%1" : "=f" (fd) : "r" (rs1));
return fd;
}
} // namespace F

View File

@@ -1,431 +0,0 @@
/*
* Copyright (c) 2016 The University of Virginia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstdint>
#include <cstring>
#include <iostream>
#include <limits>
#include "insttest.h"
#include "rv64i.h"
int main()
{
using namespace std;
using namespace insttest;
// LUI
expect<int64_t>(4096, []{return I::lui(1);}, "lui");
expect<int64_t>(numeric_limits<int32_t>::min(),
[]{return I::lui(0x80000);}, "lui, negative");
// AUIPC
expect<bool>(true, []{return I::auipc(3);}, "auipc");
// Jump (JAL, JALR)
expect<bool>(true, []{return I::jal();}, "jal");
expect<bool>(true, []{return I::jalr();}, "jalr");
// BEQ
expect<bool>(true, []{return I::beq(5, 5);}, "beq, equal");
expect<bool>(false, []{return I::beq(numeric_limits<int64_t>::max(),
numeric_limits<int64_t>::min());}, "beq, not equal");
// BNE
expect<bool>(false, []{return I::bne(5, 5);}, "bne, equal");
expect<bool>(true, []{return I::bne(numeric_limits<int64_t>::max(),
numeric_limits<int64_t>::min());}, "bne, not equal");
// BLT
expect<bool>(true, []{return I::blt(numeric_limits<int64_t>::min(),
numeric_limits<int64_t>::max());}, "blt, less");
expect<bool>(false, []{return I::blt(numeric_limits<int64_t>::min(),
numeric_limits<int64_t>::min());}, "blt, equal");
expect<bool>(false, []{return I::blt(numeric_limits<int64_t>::max(),
numeric_limits<int64_t>::min());}, "blt, greater");
// BGE
expect<bool>(false, []{return I::bge(numeric_limits<int64_t>::min(),
numeric_limits<int64_t>::max());}, "bge, less");
expect<bool>(true, []{return I::bge(numeric_limits<int64_t>::min(),
numeric_limits<int64_t>::min());}, "bge, equal");
expect<bool>(true, []{return I::bge(numeric_limits<int64_t>::max(),
numeric_limits<int64_t>::min());}, "bge, greater");
// BLTU
expect<bool>(true, []{return I::blt(numeric_limits<int64_t>::min(),
numeric_limits<int64_t>::max());}, "bltu, greater");
expect<bool>(false, []{return I::blt(numeric_limits<int64_t>::min(),
numeric_limits<int64_t>::min());}, "bltu, equal");
expect<bool>(false, []{return I::blt(numeric_limits<int64_t>::max(),
numeric_limits<int64_t>::min());}, "bltu, less");
// BGEU
expect<bool>(false, []{return I::bge(numeric_limits<int64_t>::min(),
numeric_limits<int64_t>::max());}, "bgeu, greater");
expect<bool>(true, []{return I::bge(numeric_limits<int64_t>::min(),
numeric_limits<int64_t>::min());}, "bgeu, equal");
expect<bool>(true, []{return I::bge(numeric_limits<int64_t>::max(),
numeric_limits<int64_t>::min());}, "bgeu, less");
// Load (LB, LH, LW, LBU, LHU)
expect<int64_t>(7, []{return I::load<int8_t, int64_t>(0x07);},
"lb, positive");
expect<int64_t>(numeric_limits<int8_t>::min(),
[]{return I::load<int8_t, int64_t>(0x80);}, "lb, negative");
expect<int64_t>(1792, []{return I::load<int16_t, int64_t>(0x0700);},
"lh, positive");
expect<int64_t>(numeric_limits<int16_t>::min(),
[]{return I::load<int16_t, int64_t>(0x8000);}, "lh, negative");
expect<int64_t>(458752, []{return I::load<int32_t, int64_t>(0x00070000);},
"lw, positive");
expect<int64_t>(numeric_limits<int32_t>::min(),
[]{return I::load<int32_t, int64_t>(0x80000000);},
"lw, negative");
expect<uint64_t>(128, []{return I::load<uint8_t, uint64_t>(0x80);}, "lbu");
expect<uint64_t>(32768, []{return I::load<uint16_t, uint64_t>(0x8000);},
"lhu");
// Store (SB, SH, SW)
expect<uint8_t>(0xFF, []{return I::store<int8_t>(-1);}, "sb");
expect<uint16_t>(0xFFFF, []{return I::store<int16_t>(-1);}, "sh");
expect<uint32_t>(0xFFFFFFFF, []{return I::store<int32_t>(-1);}, "sw");
// ADDI
expect<int64_t>(1073742078, []{return I::addi(0x3FFFFFFF, 255);},
"addi");
expect<int64_t>(1, []{return I::addi(-1, 2);}, "addi, overflow");
// SLTI
expect<bool>(true, []{return I::slti(-1, 0);}, "slti, true");
expect<bool>(false, []{return I::slti(0, -1);}, "slti, false");
// SLTIU
expect<bool>(false, []{return I::sltiu(-1, 0);}, "sltiu, false");
expect<bool>(true, []{return I::sltiu(0, -1);}, "sltiu, true");
expect<bool>(true, []{return I::sltiu(0xFFFF, -1);}, "sltiu, sext");
// XORI
expect<uint64_t>(0xFF, []{return I::xori(0xAA, 0x55);}, "xori (1)");
expect<uint64_t>(0, []{return I::xori(0xAA, 0xAA);}, "xori (0)");
// ORI
expect<uint64_t>(0xFF, []{return I::ori(0xAA, 0x55);}, "ori (1)");
expect<uint64_t>(0xAA, []{return I::ori(0xAA, 0xAA);}, "ori (A)");
// ANDI
expect<uint64_t>(0, []{return I::andi(-1, 0);}, "andi (0)");
expect<uint64_t>(0x1234567812345678ULL,
[]{return I::andi(0x1234567812345678ULL, -1);}, "andi (1)");
// SLLI
expect<int64_t>(65280, []{return I::slli(255, 8);}, "slli, general");
expect<int64_t>(numeric_limits<int64_t>::min(),
[]{return I::slli(255, 63);}, "slli, erase");
// SRLI
expect<int64_t>(255, []{return I::srli(65280, 8);}, "srli, general");
expect<int64_t>(0, []{return I::srli(255, 8);}, "srli, erase");
expect<int64_t>(1, []{return I::srli(numeric_limits<int64_t>::min(), 63);},
"srli, negative");
// SRAI
expect<int64_t>(255, []{return I::srai(65280, 8);}, "srai, general");
expect<int64_t>(0, []{return I::srai(255, 8);}, "srai, erase");
expect<int64_t>(-1,
[]{return I::srai(numeric_limits<int64_t>::min(), 63);},
"srai, negative");
// ADD
expect<int64_t>(1073742078, []{return I::add(0x3FFFFFFF, 255);}, "add");
expect<int64_t>(-1,
[]{return I::add(0x7FFFFFFFFFFFFFFFLL, 0x8000000000000000LL);},
"add, overflow");
// SUB
expect<int64_t>(65535, []{return I::sub(65536, 1);}, "sub");
expect<int64_t>(-1,
[]{return I::sub(0x7FFFFFFFFFFFFFFFLL, 0x8000000000000000LL);},
"sub, \"overflow\"");
// SLL
expect<int64_t>(65280, []{return I::sll(255, 8);}, "sll, general");
expect<int64_t>(numeric_limits<int64_t>::min(),
[]{return I::sll(255, 63);}, "sll, erase");
// SLT
expect<bool>(true, []{return I::slt(-1, 0);}, "slt, true");
expect<bool>(false, []{return I::slt(0, -1);}, "slt, false");
// SLTU
expect<bool>(false, []{return I::sltu(-1, 0);}, "sltu, false");
expect<bool>(true, []{return I::sltu(0, -1);}, "sltu, true");
// XOR
expect<uint64_t>(-1,
[]{return I::xor_inst(0xAAAAAAAAAAAAAAAAULL,
0x5555555555555555ULL);},
"xor (1)");
expect<uint64_t>(0,
[]{return I::xor_inst(0xAAAAAAAAAAAAAAAAULL,
0xAAAAAAAAAAAAAAAAULL);},
"xor (0)");
// SRL
expect<uint64_t>(255, []{return I::srl(65280, 8);}, "srl, general");
expect<uint64_t>(0, []{return I::srl(255, 8);}, "srl, erase");
expect<uint64_t>(1, []{return I::srl(numeric_limits<int64_t>::min(), 63);},
"srl, negative");
// SRA
expect<int64_t>(255, []{return I::sra(65280, 8);}, "sra, general");
expect<int64_t>(0, []{return I::sra(255, 8);}, "sra, erase");
expect<int64_t>(-1, []{return I::sra(numeric_limits<int64_t>::min(), 63);},
"sra, negative");
// OR
expect<uint64_t>(-1,
[]{return I::or_inst(0xAAAAAAAAAAAAAAAAULL,
0x5555555555555555ULL);},
"or (1)");
expect<uint64_t>(0xAAAAAAAAAAAAAAAAULL,
[]{return I::or_inst(0xAAAAAAAAAAAAAAAAULL,
0xAAAAAAAAAAAAAAAAULL);},
"or (A)");
// AND
expect<uint64_t>(0, []{return I::and_inst(-1, 0);}, "and (0)");
expect<uint64_t>(0x1234567812345678ULL,
[]{return I::and_inst(0x1234567812345678ULL, -1);}, "and (-1)");
// FENCE/FENCE.I
asm volatile("fence" : : );
asm volatile("fence.i" : : );
// ECALL
char fname[] = "test.txt";
char teststr[] = "this is a test";
expect<bool>(true, [=]{
int fd = open(fname, O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (fd < 0) {
return false;
}
size_t n = write(fd, teststr, sizeof(teststr));
cout << "Bytes written: " << n << endl;
return close(fd) >= 0 && n > 0;
}, "open, write");
expect<int>(0, [=]{return access(fname, F_OK);}, "access F_OK");
expect<int>(0, [=]{return access(fname, R_OK);}, "access R_OK");
expect<int>(0, [=]{return access(fname, W_OK);}, "access W_OK");
// gem5's implementation of access is incorrect; it should return
// -1 on failure, not -errno. Account for this using an inequality.
expect<bool>(true, [=]{return access(fname, X_OK) != 0;}, "access X_OK");
expect<bool>(true, [=]{
struct stat stat_buf, fstat_buf;
int s = stat(fname, &stat_buf);
if (s < 0) {
return false;
} else {
cout << "stat:" << endl;
cout << "\tst_dev =\t" << stat_buf.st_dev << endl;
cout << "\tst_ino =\t" << stat_buf.st_ino << endl;
cout << "\tst_mode =\t" << stat_buf.st_mode << endl;
cout << "\tst_nlink =\t" << stat_buf.st_nlink << endl;
cout << "\tst_uid =\t" << stat_buf.st_uid << endl;
cout << "\tst_gid =\t" << stat_buf.st_gid << endl;
cout << "\tst_rdev =\t" << stat_buf.st_rdev << endl;
cout << "\tst_size =\t" << stat_buf.st_size << endl;
cout << "\tst_blksize =\t" << stat_buf.st_blksize << endl;
cout << "\tst_blocks =\t" << stat_buf.st_blocks << endl;
}
int fd = open(fname, O_RDONLY);
if (fd < 0) {
return false;
}
int f = fstat(fd, &fstat_buf);
if (f >= 0) {
cout << "fstat:" << endl;
cout << "\tst_dev =\t" << fstat_buf.st_dev << endl;
cout << "\tst_ino =\t" << fstat_buf.st_ino << endl;
cout << "\tst_mode =\t" << fstat_buf.st_mode << endl;
cout << "\tst_nlink =\t" << fstat_buf.st_nlink << endl;
cout << "\tst_uid =\t" << fstat_buf.st_uid << endl;
cout << "\tst_gid =\t" << fstat_buf.st_gid << endl;
cout << "\tst_rdev =\t" << fstat_buf.st_rdev << endl;
cout << "\tst_size =\t" << fstat_buf.st_size << endl;
cout << "\tst_blksize =\t" << fstat_buf.st_blksize << endl;
cout << "\tst_blocks =\t" << fstat_buf.st_blocks << endl;
}
return close(fd) >= 0 && f >= 0;
}, "open, stat");
expect<bool>(true, [=]{
int fd = open(fname, O_RDONLY);
if (fd < 0) {
return false;
}
char in[128];
size_t n = read(fd, in, sizeof(in));
cout << "Bytes read: " << n << endl;
cout << "String read: " << in << endl;
int cl = close(fd);
int un = unlink(fname);
return n > 0 && cl >= 0 && un >= 0 && strcmp(teststr, in) == 0;
}, "open, read, unlink");
expect<bool>(true, []{
struct tms buf;
clock_t t = times(&buf);
cout << "times:" << endl;
cout << "\ttms_utime =\t" << buf.tms_utime << endl;
cout << "\ttms_stime =\t" << buf.tms_stime << endl;
cout << "\ttms_cutime =\t" << buf.tms_cutime << endl;
cout << "\ttms_cstime =\t" << buf.tms_cstime << endl;
return t > 0;
}, "times");
expect<int>(0, []{
struct timeval time;
int res = gettimeofday(&time, nullptr);
cout << "timeval:" << endl;
cout << "\ttv_sec =\t" << time.tv_sec << endl;
cout << "\ttv_usec =\t" << time.tv_usec << endl;
return res;
}, "gettimeofday");
// EBREAK not tested because it only makes sense in FS mode or when
// using gdb
// ERET not tested because it only makes sense in FS mode and will cause
// a panic when used in SE mode
// CSRs (RDCYCLE, RDTIME, RDINSTRET)
expect<bool>(true, []{
uint64_t cycles = 0;
asm("rdcycle %0" : "=r" (cycles));
cout << "Cycles: " << cycles << endl;
return cycles > 0;
}, "rdcycle");
expect<bool>(true, []{
uint64_t time = 0;
asm("rdtime %0" : "=r" (time));
cout << "Time: " << time << endl;
return time > 0;
}, "rdtime");
expect<bool>(true, []{
uint64_t instret = 0;
asm("rdinstret %0" : "=r" (instret));
cout << "Instructions Retired: " << instret << endl;
return instret > 0;
}, "rdinstret");
// 64-bit memory (LWU, LD, SD)
expect<int64_t>(0xFFFFFFFF, []{return I::load<uint32_t, uint64_t>(-1);},
"lwu");
expect<int64_t>(30064771072,
[]{return I::load<int64_t, int64_t>(30064771072);}, "ld");
expect<uint64_t>(-1, []{return I::store<int64_t>(-1);}, "sd");
// ADDIW
expect<int64_t>(268435710, []{return I::addiw(0x0FFFFFFF, 255);}, "addiw");
expect<int64_t>(-2147481602, []{return I::addiw(0x7FFFFFFF, 0x7FF);},
"addiw, overflow");
expect<int64_t>(0, []{return I::addiw(0x7FFFFFFFFFFFFFFFLL, 1);},
"addiw, truncate");
// SLLIW
expect<int64_t>(65280, []{return I::slliw(255, 8);}, "slliw, general");
expect<int64_t>(numeric_limits<int32_t>::min(),
[]{return I::slliw(255, 31);}, "slliw, erase");
expect<int64_t>(numeric_limits<int32_t>::min(),
[]{return I::slliw(0xFFFFFFFF00800000LL, 8);}, "slliw, truncate");
// SRLIW
expect<int64_t>(255, []{return I::srliw(65280, 8);}, "srliw, general");
expect<int64_t>(0, []{return I::srliw(255, 8);}, "srliw, erase");
expect<int64_t>(1,
[]{return I::srliw(numeric_limits<int32_t>::min(), 31);},
"srliw, negative");
expect<int64_t>(1, []{return I::srliw(0xFFFFFFFF80000000LL, 31);},
"srliw, truncate");
// SRAIW
expect<int64_t>(255, []{return I::sraiw(65280, 8);}, "sraiw, general");
expect<int64_t>(0, []{return I::sraiw(255, 8);}, "sraiw, erase");
expect<int64_t>(-1,
[]{return I::sraiw(numeric_limits<int32_t>::min(), 31);},
"sraiw, negative");
expect<int64_t>(-1, []{return I::sraiw(0x0000000180000000LL, 31);},
"sraiw, truncate");
// ADDW
expect<int64_t>(1073742078, []{return I::addw(0x3FFFFFFF, 255);}, "addw");
expect<int64_t>(-1, []{return I::addw(0x7FFFFFFF, 0x80000000);},
"addw, overflow");
expect<int64_t>(65536, []{return I::addw(0xFFFFFFFF0000FFFFLL, 1);},
"addw, truncate");
// SUBW
expect<int64_t>(65535, []{return I::subw(65536, 1);}, "subw");
expect<int64_t>(-1, []{return I::subw(0x7FFFFFFF, 0x80000000);},
"subw, \"overflow\"");
expect<int64_t>(0,
[]{return I::subw(0xAAAAAAAAFFFFFFFFULL, 0x55555555FFFFFFFFULL);},
"subw, truncate");
// SLLW
expect<int64_t>(65280, []{return I::sllw(255, 8);}, "sllw, general");
expect<int64_t>(numeric_limits<int32_t>::min(),
[]{return I::sllw(255, 31);}, "sllw, erase");
expect<int64_t>(numeric_limits<int32_t>::min(),
[]{return I::sllw(0xFFFFFFFF00008000LL, 16);}, "sllw, truncate");
// SRLW
expect<uint64_t>(255, []{return I::srlw(65280, 8);}, "srlw, general");
expect<uint64_t>(0, []{return I::srlw(255, 8);}, "srlw, erase");
expect<uint64_t>(1,
[]{return I::srlw(numeric_limits<int32_t>::min(), 31);},
"srlw, negative");
expect<uint64_t>(1, []{return I::srlw(0x0000000180000000LL, 31);},
"srlw, truncate");
// SRAW
expect<int64_t>(255, []{return I::sraw(65280, 8);}, "sraw, general");
expect<int64_t>(0, []{return I::sraw(255, 8);}, "sraw, erase");
expect<int64_t>(-1,
[]{return I::sraw(numeric_limits<int32_t>::min(), 31);},
"sraw, negative");
expect<int64_t>(1, []{return I::sraw(0xFFFFFFFF40000000LL, 30);},
"sraw, truncate");
return 0;
}

View File

@@ -1,438 +0,0 @@
/*
* Copyright (c) 2016 The University of Virginia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cstdint>
#include <iostream>
#include "insttest.h"
namespace I
{
inline uint64_t
lui(const uint32_t imm)
{
int64_t rd = -1;
asm volatile("lui %0,%1" : "=r" (rd) : "i" (imm));
return rd;
}
inline bool
auipc(const uint64_t imm)
{
int64_t rd = -1;
asm volatile("auipc %0,%1" : "=r" (rd) : "i" (imm));
std::cout << "auipc: 0x" << std::hex << std::uppercase << rd <<
std::nouppercase << std::dec << std::endl;
return rd >= imm;
}
inline bool
jal()
{
asm volatile goto("jal zero,%l[jallabel]" : : : : jallabel);
return false;
jallabel:
return true;
}
inline bool
jalr()
{
int a = 0;
asm volatile("auipc %0,0;"
"jalr t0,%0,12;"
"addi %0,zero,0;"
"sub %0,t0,%0;"
: "+r" (a)
:
: "t0");
return a == 8;
}
inline bool
beq(int64_t a, int64_t b)
{
asm volatile goto("beq %0,%1,%l[beqlabel]"
:
: "r" (a), "r" (b)
:
: beqlabel);
return false;
beqlabel:
return true;
}
inline bool
bne(int64_t a, int64_t b)
{
asm volatile goto("bne %0,%1,%l[bnelabel]"
:
: "r" (a), "r" (b)
:
: bnelabel);
return false;
bnelabel:
return true;
}
inline bool
blt(int64_t a, int64_t b)
{
asm volatile goto("blt %0,%1,%l[bltlabel]"
:
: "r" (a), "r" (b)
:
: bltlabel);
return false;
bltlabel:
return true;
}
inline bool
bge(int64_t a, int64_t b)
{
asm volatile goto("bge %0,%1,%l[bgelabel]"
:
: "r" (a), "r" (b)
:
: bgelabel);
return false;
bgelabel:
return true;
}
inline bool
bltu(uint64_t a, uint64_t b)
{
asm volatile goto("bltu %0,%1,%l[bltulabel]"
:
: "r" (a), "r" (b)
:
: bltulabel);
return false;
bltulabel:
return true;
}
inline bool
bgeu(uint64_t a, uint64_t b)
{
asm volatile goto("bgeu %0,%1,%l[bgeulabel]"
:
: "r" (a), "r" (b)
:
: bgeulabel);
return false;
bgeulabel:
return true;
}
template<typename M, typename R> inline R
load(const M& b)
{
R a = 0;
switch(sizeof(M))
{
case 1:
if (std::is_signed<M>::value) {
asm volatile("lb %0,%1" : "=r" (a) : "m" (b));
} else {
asm volatile("lbu %0,%1" : "=r" (a) : "m" (b));
}
break;
case 2:
if (std::is_signed<M>::value) {
asm volatile("lh %0,%1" : "=r" (a) : "m" (b));
} else {
asm volatile("lhu %0,%1" : "=r" (a) : "m" (b));
}
break;
case 4:
if (std::is_signed<M>::value) {
asm volatile("lw %0,%1" : "=r" (a) : "m" (b));
} else {
asm volatile("lwu %0,%1" : "=r" (a) : "m" (b));
}
break;
case 8:
asm volatile("ld %0,%1" : "=r" (a) : "m" (b));
break;
}
return a;
}
template<typename M> inline M
store(const M& rs2)
{
M mem = 0;
switch (sizeof(M))
{
case 1:
asm volatile("sb %1,%0" : "=m" (mem) : "r" (rs2));
break;
case 2:
asm volatile("sh %1,%0" : "=m" (mem) : "r" (rs2));
break;
case 4:
asm volatile("sw %1,%0" : "=m" (mem) : "r" (rs2));
break;
case 8:
asm volatile("sd %1,%0" : "=m" (mem) : "r" (rs2));
break;
}
return mem;
}
inline int64_t
addi(int64_t rs1, const int16_t imm)
{
int64_t rd = 0;
IOP("addi", rd, rs1, imm);
return rd;
}
inline bool
slti(int64_t rs1, const int16_t imm)
{
bool rd = false;
IOP("slti", rd, rs1, imm);
return rd;
}
inline bool
sltiu(uint64_t rs1, const uint16_t imm)
{
bool rd = false;
IOP("sltiu", rd, rs1, imm);
return rd;
}
inline uint64_t
xori(uint64_t rs1, const uint16_t imm)
{
uint64_t rd = 0;
IOP("xori", rd, rs1, imm);
return rd;
}
inline uint64_t
ori(uint64_t rs1, const uint16_t imm)
{
uint64_t rd = 0;
IOP("ori", rd, rs1, imm);
return rd;
}
inline uint64_t
andi(uint64_t rs1, const uint16_t imm)
{
uint64_t rd = 0;
IOP("andi", rd, rs1, imm);
return rd;
}
inline int64_t
slli(int64_t rs1, const uint16_t imm)
{
int64_t rd = 0;
IOP("slli", rd, rs1, imm);
return rd;
}
inline uint64_t
srli(uint64_t rs1, const uint16_t imm)
{
uint64_t rd = 0;
IOP("srli", rd, rs1, imm);
return rd;
}
inline int64_t
srai(int64_t rs1, const uint16_t imm)
{
int64_t rd = 0;
IOP("srai", rd, rs1, imm);
return rd;
}
inline int64_t
add(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("add", rd, rs1, rs2);
return rd;
}
inline int64_t
sub(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("sub", rd, rs1, rs2);
return rd;
}
inline int64_t
sll(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("sll", rd, rs1, rs2);
return rd;
}
inline bool
slt(int64_t rs1, int64_t rs2)
{
bool rd = false;
ROP("slt", rd, rs1, rs2);
return rd;
}
inline bool
sltu(uint64_t rs1, uint64_t rs2)
{
bool rd = false;
ROP("sltu", rd, rs1, rs2);
return rd;
}
inline uint64_t
xor_inst(uint64_t rs1, uint64_t rs2)
{
uint64_t rd = 0;
ROP("xor", rd, rs1, rs2);
return rd;
}
inline uint64_t
srl(uint64_t rs1, uint64_t rs2)
{
uint64_t rd = 0;
ROP("srl", rd, rs1, rs2);
return rd;
}
inline int64_t
sra(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("sra", rd, rs1, rs2);
return rd;
}
inline uint64_t
or_inst(uint64_t rs1, uint64_t rs2)
{
uint64_t rd = 0;
ROP("or", rd, rs1, rs2);
return rd;
}
inline uint64_t
and_inst(uint64_t rs1, uint64_t rs2)
{
uint64_t rd = 0;
ROP("and", rd, rs1, rs2);
return rd;
}
inline int64_t
addiw(int64_t rs1, const int16_t imm)
{
int64_t rd = 0;
IOP("addiw", rd, rs1, imm);
return rd;
}
inline int64_t
slliw(int64_t rs1, const uint16_t imm)
{
int64_t rd = 0;
IOP("slliw", rd, rs1, imm);
return rd;
}
inline uint64_t
srliw(uint64_t rs1, const uint16_t imm)
{
uint64_t rd = 0;
IOP("srliw", rd, rs1, imm);
return rd;
}
inline int64_t
sraiw(int64_t rs1, const uint16_t imm)
{
int64_t rd = 0;
IOP("sraiw", rd, rs1, imm);
return rd;
}
inline int64_t
addw(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("addw", rd, rs1, rs2);
return rd;
}
inline int64_t
subw(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("subw", rd, rs1, rs2);
return rd;
}
inline int64_t
sllw(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("sllw", rd, rs1, rs2);
return rd;
}
inline uint64_t
srlw(uint64_t rs1, uint64_t rs2)
{
uint64_t rd = 0;
ROP("srlw", rd, rs1, rs2);
return rd;
}
inline int64_t
sraw(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("sraw", rd, rs1, rs2);
return rd;
}
} // namespace I

View File

@@ -1,141 +0,0 @@
/*
* Copyright (c) 2016 The University of Virginia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstdint>
#include <limits>
#include "insttest.h"
#include "rv64m.h"
int main()
{
using namespace std;
using namespace insttest;
// MUL
expect<int64_t>(39285, []{return M::mul(873, 45);}, "mul");
expect<int64_t>(0, []{return M::mul(0x4000000000000000LL, 4);},
"mul, overflow");
// MULH
expect<int64_t>(1, []{return M::mulh(0x4000000000000000LL, 4);}, "mulh");
expect<int64_t>(-1, []{return M::mulh(numeric_limits<int64_t>::min(), 2);},
"mulh, negative");
expect<int64_t>(0, []{return M::mulh(-1, -1);}, "mulh, all bits set");
// MULHSU
expect<int64_t>(-1, []{return M::mulhsu(-1, -1);}, "mulhsu, all bits set");
expect<int64_t>(-1,
[]{return M::mulhsu(numeric_limits<int64_t>::min(), 2);},\
"mulhsu");
// MULHU
expect<uint64_t>(1, []{return M::mulhu(0x8000000000000000ULL, 2);},
"mulhu");
expect<uint64_t>(0xFFFFFFFFFFFFFFFEULL, []{return M::mulhu(-1, -1);},
"mulhu, all bits set");
// DIV
expect<int64_t>(-7, []{return M::div(-59, 8);}, "div");
expect<int64_t>(-1, []{return M::div(255, 0);}, "div/0");
expect<int64_t>(numeric_limits<int64_t>::min(),
[]{return M::div(numeric_limits<int64_t>::min(), -1);},
"div, overflow");
// DIVU
expect<uint64_t>(2305843009213693944LL, []{return M::divu(-59, 8);},
"divu");
expect<uint64_t>(numeric_limits<uint64_t>::max(),
[]{return M::divu(255, 0);}, "divu/0");
expect<uint64_t>(0,
[]{return M::divu(numeric_limits<uint64_t>::min(), -1);},
"divu, \"overflow\"");
// REM
expect<int64_t>(-3, []{return M::rem(-59, 8);}, "rem");
expect<int64_t>(255, []{return M::rem(255, 0);}, "rem/0");
expect<int64_t>(0, []{return M::rem(numeric_limits<int64_t>::min(), -1);},
"rem, overflow");
// REMU
expect<uint64_t>(5, []{return M::remu(-59, 8);}, "remu");
expect<uint64_t>(255, []{return M::remu(255, 0);}, "remu/0");
expect<uint64_t>(0x8000000000000000ULL,
[]{return M::remu(0x8000000000000000ULL, -1);},
"remu, \"overflow\"");
// MULW
expect<int64_t>(-100,
[]{return M::mulw(0x7FFFFFFF00000005LL, 0x80000000FFFFFFECLL);},
"mulw, truncate");
expect<int64_t>(0, []{return M::mulw(0x40000000, 4);}, "mulw, overflow");
// DIVW
expect<int64_t>(-7,
[]{return M::divw(0x7FFFFFFFFFFFFFC5LL, 0xFFFFFFFF00000008LL);},
"divw, truncate");
expect<int64_t>(-1, []{return M::divw(65535, 0);}, "divw/0");
expect<int64_t>(numeric_limits<int32_t>::min(),
[]{return M::divw(numeric_limits<int32_t>::min(), -1);},
"divw, overflow");
// DIVUW
expect<int64_t>(536870904,
[]{return M::divuw(0x7FFFFFFFFFFFFFC5LL, 0xFFFFFFFF00000008LL);},
"divuw, truncate");
expect<int64_t>(numeric_limits<uint64_t>::max(),
[]{return M::divuw(65535, 0);}, "divuw/0");
expect<int64_t>(0,
[]{return M::divuw(numeric_limits<int32_t>::min(), -1);},
"divuw, \"overflow\"");
expect<int64_t>(-1,
[]{return M::divuw(numeric_limits<uint32_t>::max(), 1);},
"divuw, sign extend");
// REMW
expect<int64_t>(-3,
[]{return M::remw(0x7FFFFFFFFFFFFFC5LL, 0xFFFFFFFF00000008LL);},
"remw, truncate");
expect<int64_t>(65535, []{return M::remw(65535, 0);}, "remw/0");
expect<int64_t>(0, []{return M::remw(numeric_limits<int32_t>::min(), -1);},
"remw, overflow");
// REMUW
expect<int64_t>(5,
[]{return M::remuw(0x7FFFFFFFFFFFFFC5LL, 0xFFFFFFFF00000008LL);},
"remuw, truncate");
expect<int64_t>(65535, []{return M::remuw(65535, 0);}, "remuw/0");
expect<int64_t>(numeric_limits<int32_t>::min(),
[]{return M::remuw(numeric_limits<int32_t>::min(), -1);},
"remuw, \"overflow\"");
expect<int64_t>(0xFFFFFFFF80000000,
[]{return M::remuw(0x80000000, 0xFFFFFFFF);},
"remuw, sign extend");
return 0;
}

View File

@@ -1,142 +0,0 @@
/*
* Copyright (c) 2016 The University of Virginia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cstdint>
#include "insttest.h"
namespace M
{
inline int64_t
mul(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("mul", rd, rs1, rs2);
return rd;
}
inline int64_t
mulh(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("mulh", rd, rs1, rs2);
return rd;
}
inline int64_t
mulhsu(int64_t rs1, uint64_t rs2)
{
int64_t rd = 0;
ROP("mulhsu", rd, rs1, rs2);
return rd;
}
inline uint64_t
mulhu(uint64_t rs1, uint64_t rs2)
{
uint64_t rd = 0;
ROP("mulhu", rd, rs1, rs2);
return rd;
}
inline int64_t
div(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("div", rd, rs1, rs2);
return rd;
}
inline uint64_t
divu(uint64_t rs1, uint64_t rs2)
{
uint64_t rd = 0;
ROP("divu", rd, rs1, rs2);
return rd;
}
inline int64_t
rem(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("rem", rd, rs1, rs2);
return rd;
}
inline uint64_t
remu(uint64_t rs1, uint64_t rs2)
{
uint64_t rd = 0;
ROP("remu", rd, rs1, rs2);
return rd;
}
inline int64_t
mulw(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("mulw", rd, rs1, rs2);
return rd;
}
inline int64_t
divw(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("divw", rd, rs1, rs2);
return rd;
}
inline uint64_t
divuw(uint64_t rs1, uint64_t rs2)
{
uint64_t rd = 0;
ROP("divuw", rd, rs1, rs2);
return rd;
}
inline int64_t
remw(int64_t rs1, int64_t rs2)
{
int64_t rd = 0;
ROP("remw", rd, rs1, rs2);
return rd;
}
inline uint64_t
remuw(uint64_t rs1, uint64_t rs2)
{
uint64_t rd = 0;
ROP("remuw", rd, rs1, rs2);
return rd;
}
} // namespace M