-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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: \e[1;31mFAIL\e[0m (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
+++ /dev/null
-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
# 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',)
}
+++ /dev/null
-# 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
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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");
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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