diff --git a/src/codegen/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h
index bc6293c0b..08b9ee5f2 100644
--- a/src/codegen/codegen_ops_x86-64.h
+++ b/src/codegen/codegen_ops_x86-64.h
@@ -4434,7 +4434,7 @@ FP_COMPARE_REG(int dst, int src)
addbyte((uint8_t) cpu_state_offset(npxs) + 1);
addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/
addbyte(0xe1);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
if (src) {
addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/
@@ -4467,7 +4467,7 @@ FP_COMPARE_REG(int dst, int src)
addbyte(0x9f); /*LAHF*/
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR CL, AH*/
addbyte(0xe1);
addbyte(0x88); /*MOV [npxs+1], CL*/
@@ -4493,7 +4493,7 @@ FP_COMPARE_MEM(void)
addbyte((uint8_t) cpu_state_offset(ST));
addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/
addbyte(0xe1);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0x66); /*COMISD XMM0, XMM1*/
addbyte(0x0f);
addbyte(0x2f);
@@ -4501,7 +4501,7 @@ FP_COMPARE_MEM(void)
addbyte(0x9f); /*LAHF*/
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR CL, AH*/
addbyte(0xe1);
addbyte(0x88); /*MOV [npxs+1], CL*/
diff --git a/src/codegen/codegen_ops_x86.h b/src/codegen/codegen_ops_x86.h
index 410ce8e17..c48324c2a 100644
--- a/src/codegen/codegen_ops_x86.h
+++ b/src/codegen/codegen_ops_x86.h
@@ -2911,7 +2911,7 @@ FP_COMPARE_S(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xd8); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -2919,7 +2919,7 @@ FP_COMPARE_S(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -2943,7 +2943,7 @@ FP_COMPARE_S(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xd8); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -2951,7 +2951,7 @@ FP_COMPARE_S(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -2980,7 +2980,7 @@ FP_COMPARE_D(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xdc); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -2988,7 +2988,7 @@ FP_COMPARE_D(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -3016,7 +3016,7 @@ FP_COMPARE_D(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xdc); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -3024,7 +3024,7 @@ FP_COMPARE_D(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -3050,7 +3050,7 @@ FP_COMPARE_IW(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xde); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -3058,7 +3058,7 @@ FP_COMPARE_IW(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -3082,7 +3082,7 @@ FP_COMPARE_IW(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xde); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -3090,7 +3090,7 @@ FP_COMPARE_IW(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -3115,7 +3115,7 @@ FP_COMPARE_IL(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xda); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -3123,7 +3123,7 @@ FP_COMPARE_IL(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -3147,7 +3147,7 @@ FP_COMPARE_IL(void)
addbyte(0xe2);
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
addbyte(0xe3);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xda); /*FCOMP [ESP]*/
addbyte(0x04 | 0x18);
addbyte(0x24);
@@ -3155,7 +3155,7 @@ FP_COMPARE_IL(void)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR BL, AH*/
addbyte(0xe3);
addbyte(0x88); /*MOV [npxs+1], BL*/
@@ -3250,7 +3250,7 @@ FP_COMPARE_REG(int dst, int src)
addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + dst) & 7]));
addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/
addbyte(0xe1);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
addbyte(0xdc); /*FCOMP ST[src][EBP]*/
addbyte(0x5d);
addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + src) & 7]));
@@ -3258,7 +3258,7 @@ FP_COMPARE_REG(int dst, int src)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR CL, AH*/
addbyte(0xe1);
addbyte(0x88); /*MOV [npxs+1], CL*/
@@ -3286,7 +3286,7 @@ FP_COMPARE_REG(int dst, int src)
addbyte(0xe2);
addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/
addbyte(0xe1);
- addbyte((~(C0 | C2 | C3)) >> 8);
+ addbyte((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)) >> 8);
if (src) {
addbyte(0xdd); /*FLD ST[EBX*8]*/
@@ -3312,7 +3312,7 @@ FP_COMPARE_REG(int dst, int src)
addbyte(0xe0);
addbyte(0x80); /*AND AH, (C0|C2|C3)*/
addbyte(0xe4);
- addbyte((C0 | C2 | C3) >> 8);
+ addbyte((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3) >> 8);
addbyte(0x08); /*OR CL, AH*/
addbyte(0xe1);
addbyte(0x88); /*MOV [npxs+1], CL*/
diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c
index 7514e1f0c..421292c7e 100644
--- a/src/codegen_new/codegen_backend_arm64_uops.c
+++ b/src/codegen_new/codegen_backend_arm64_uops.c
@@ -648,10 +648,10 @@ codegen_FTST(codeblock_t *block, uop_t *uop)
host_arm64_FSUB_D(block, REG_V_TEMP, REG_V_TEMP, REG_V_TEMP);
host_arm64_MOVZ_IMM(block, dest_reg, 0);
host_arm64_FCMP_D(block, src_reg_a, REG_V_TEMP);
- host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3);
- host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0);
+ host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, FPU_SW_C3);
+ host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, FPU_SW_C0);
host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg);
- host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0 | C2 | C3);
+ host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg);
host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg);
} else
@@ -690,10 +690,10 @@ codegen_FCOM(codeblock_t *block, uop_t *uop)
if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) {
host_arm64_MOVZ_IMM(block, dest_reg, 0);
host_arm64_FCMP_D(block, src_reg_a, src_reg_b);
- host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3);
- host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0);
+ host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, FPU_SW_C3);
+ host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, FPU_SW_C0);
host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg);
- host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0 | C2 | C3);
+ host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg);
host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg);
} else
diff --git a/src/codegen_new/codegen_backend_arm_uops.c b/src/codegen_new/codegen_backend_arm_uops.c
index 338d3dd54..04b61255b 100644
--- a/src/codegen_new/codegen_backend_arm_uops.c
+++ b/src/codegen_new/codegen_backend_arm_uops.c
@@ -718,9 +718,9 @@ codegen_FTST(codeblock_t *block, uop_t *uop)
host_arm_VCMP_D(block, src_reg_a, REG_D_TEMP);
host_arm_MOV_IMM(block, dest_reg, 0);
host_arm_VMRS_APSR(block);
- host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3);
- host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0);
- host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0 | C2 | C3);
+ host_arm_ORREQ_IMM(block, dest_reg, dest_reg, FPU_SW_C3);
+ host_arm_ORRCC_IMM(block, dest_reg, dest_reg, FPU_SW_C0);
+ host_arm_ORRVS_IMM(block, dest_reg, dest_reg, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
} else
fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
@@ -758,9 +758,9 @@ codegen_FCOM(codeblock_t *block, uop_t *uop)
host_arm_VCMP_D(block, src_reg_a, src_reg_b);
host_arm_MOV_IMM(block, dest_reg, 0);
host_arm_VMRS_APSR(block);
- host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3);
- host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0);
- host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0 | C2 | C3);
+ host_arm_ORREQ_IMM(block, dest_reg, dest_reg, FPU_SW_C3);
+ host_arm_ORRCC_IMM(block, dest_reg, dest_reg, FPU_SW_C0);
+ host_arm_ORRVS_IMM(block, dest_reg, dest_reg, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
} else
fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c
index fcab0f3ce..1b82f9fca 100644
--- a/src/codegen_new/codegen_backend_x86-64_uops.c
+++ b/src/codegen_new/codegen_backend_x86-64_uops.c
@@ -672,7 +672,7 @@ codegen_FTST(codeblock_t *block, uop_t *uop)
host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX);
host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP);
host_x86_LAHF(block);
- host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3);
+ host_x86_AND16_REG_IMM(block, REG_EAX, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
if (dest_reg != REG_EAX) {
host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX);
host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX);
@@ -720,7 +720,7 @@ codegen_FCOM(codeblock_t *block, uop_t *uop)
host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX);
host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b);
host_x86_LAHF(block);
- host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3);
+ host_x86_AND16_REG_IMM(block, REG_EAX, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
if (dest_reg != REG_EAX) {
host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX);
host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX);
diff --git a/src/codegen_new/codegen_backend_x86_uops.c b/src/codegen_new/codegen_backend_x86_uops.c
index 5ef2d97b8..91f2c7ec3 100644
--- a/src/codegen_new/codegen_backend_x86_uops.c
+++ b/src/codegen_new/codegen_backend_x86_uops.c
@@ -677,7 +677,7 @@ codegen_FTST(codeblock_t *block, uop_t *uop)
host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX);
host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP);
host_x86_LAHF(block);
- host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3);
+ host_x86_AND16_REG_IMM(block, REG_EAX, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
if (dest_reg != REG_EAX) {
host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX);
host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX);
@@ -725,7 +725,7 @@ codegen_FCOM(codeblock_t *block, uop_t *uop)
host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX);
host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b);
host_x86_LAHF(block);
- host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3);
+ host_x86_AND16_REG_IMM(block, REG_EAX, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3);
if (dest_reg != REG_EAX) {
host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX);
host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX);
diff --git a/src/codegen_new/codegen_ops_fpu_arith.c b/src/codegen_new/codegen_ops_fpu_arith.c
index 3ab7be8ac..15a6399e6 100644
--- a/src/codegen_new/codegen_ops_fpu_arith.c
+++ b/src/codegen_new/codegen_ops_fpu_arith.c
@@ -59,7 +59,7 @@ ropFCOM(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint3
uop_FP_ENTER(ir);
uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg));
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3));
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
return op_pc;
@@ -71,7 +71,7 @@ ropFCOMP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fet
uop_FP_ENTER(ir);
uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg));
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3));
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
fpu_POP(block, ir);
@@ -82,7 +82,7 @@ ropFCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fe
{
uop_FP_ENTER(ir);
uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1));
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3));
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
fpu_POP2(block, ir);
@@ -269,7 +269,7 @@ ropFUCOM(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint
uop_FP_ENTER(ir);
uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg));
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3));
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
return op_pc;
@@ -281,7 +281,7 @@ ropFUCOMP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fe
uop_FP_ENTER(ir);
uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg));
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3));
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
fpu_POP(block, ir);
@@ -292,7 +292,7 @@ ropFUCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f
{
uop_FP_ENTER(ir);
uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1));
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3));
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
fpu_POP2(block, ir);
@@ -328,7 +328,7 @@ ropFUCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f
codegen_check_seg_read(block, ir, target_seg); \
load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \
uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \
\
return op_pc + 1; \
@@ -344,7 +344,7 @@ ropFUCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f
codegen_check_seg_read(block, ir, target_seg); \
load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \
uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \
fpu_POP(block, ir); \
\
@@ -460,7 +460,7 @@ ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE)
uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \
uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \
uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \
\
return op_pc + 1; \
@@ -477,7 +477,7 @@ ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE)
uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \
uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \
uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \
fpu_POP(block, ir); \
\
@@ -600,7 +600,7 @@ ropFTST(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint3
{
uop_FP_ENTER(ir);
uop_FTST(ir, IREG_temp0_W, IREG_ST(0));
- uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3));
+ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
return op_pc;
diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt
index bd03a5558..fc5ba975f 100644
--- a/src/cpu/CMakeLists.txt
+++ b/src/cpu/CMakeLists.txt
@@ -34,5 +34,5 @@ if(DYNAREC)
codegen_timing_winchip.c codegen_timing_winchip2.c)
endif()
-add_subdirectory(softfloat)
-target_link_libraries(86Box softfloat)
+add_subdirectory(softfloat3e)
+target_link_libraries(86Box softfloat3e)
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 900d3d7e1..ae5b4692a 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -21,7 +21,7 @@
#ifndef EMU_CPU_H
#define EMU_CPU_H
-#include "softfloat/softfloat.h"
+#include "softfloat3e/softfloat.h"
enum {
FPU_NONE,
@@ -592,8 +592,6 @@ extern uint32_t eip_msr;
extern uint64_t amd_efer;
extern uint64_t star;
-#define FPU_CW_Reserved_Bits (0xe0c0)
-
#define cr0 cpu_state.CR0.l
#define msw cpu_state.CR0.w
extern uint32_t cr2;
diff --git a/src/cpu/softfloat/CMakeLists.txt b/src/cpu/softfloat/CMakeLists.txt
deleted file mode 100644
index 936157185..000000000
--- a/src/cpu/softfloat/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# 86Box A hypervisor and IBM PC system emulator that specializes in
-# running old operating systems and software designed for IBM
-# PC systems and compatibles from 1981 through fairly recent
-# system designs based on the PCI bus.
-#
-# This file is part of the 86Box distribution.
-#
-# CMake build script.
-#
-# Authors: David Hrdlička,
-#
-# Copyright 2020-2021 David Hrdlička.
-#
-
-add_library(softfloat OBJECT f2xm1.cc fpatan.cc fprem.cc fsincos.cc fyl2x.cc softfloat_poly.cc softfloat.cc softfloat16.cc
- softfloat-muladd.cc softfloat-round-pack.cc softfloat-specialize.cc softfloatx80.cc)
diff --git a/src/cpu/softfloat/config.h b/src/cpu/softfloat/config.h
deleted file mode 100644
index 9e39c2d29..000000000
--- a/src/cpu/softfloat/config.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef EMU_SF_CONFIG_H
-#define EMU_SF_CONFIG_H
-
-#include
-
-typedef int8_t flag;
-typedef uint8_t uint8;
-typedef int8_t int8;
-typedef uint16_t uint16;
-typedef int16_t int16;
-typedef uint32_t uint32;
-typedef int32_t int32;
-typedef uint64_t uint64;
-typedef int64_t int64;
-
-/*----------------------------------------------------------------------------
-| Each of the following `typedef's defines a type that holds integers
-| of _exactly_ the number of bits specified. For instance, for most
-| implementation of C, `bits16' and `sbits16' should be `typedef'ed to
-| `unsigned short int' and `signed short int' (or `short int'), respectively.
-*----------------------------------------------------------------------------*/
-typedef uint8_t bits8;
-typedef int8_t sbits8;
-typedef uint16_t bits16;
-typedef int16_t sbits16;
-typedef uint32_t bits32;
-typedef int32_t sbits32;
-typedef uint64_t bits64;
-typedef int64_t sbits64;
-
-typedef uint8_t Bit8u;
-typedef int8_t Bit8s;
-typedef uint16_t Bit16u;
-typedef int16_t Bit16s;
-typedef uint32_t Bit32u;
-typedef int32_t Bit32s;
-typedef uint64_t Bit64u;
-typedef int64_t Bit64s;
-
-/*----------------------------------------------------------------------------
-| The `LIT64' macro takes as its argument a textual integer literal and
-| if necessary ``marks'' the literal as having a 64-bit integer type.
-| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
-| appended with the letters `LL' standing for `long long', which is `gcc's
-| name for the 64-bit integer type. Some compilers may allow `LIT64' to be
-| defined as the identity macro: `#define LIT64( a ) a'.
-*----------------------------------------------------------------------------*/
-#define BX_CONST64(a) a##LL
-#define BX_CPP_INLINE static __inline
-
-#endif /*EMU_SF_CONFIG_H*/
diff --git a/src/cpu/softfloat/softfloat-compare.h b/src/cpu/softfloat/softfloat-compare.h
deleted file mode 100644
index 8b9821460..000000000
--- a/src/cpu/softfloat/softfloat-compare.h
+++ /dev/null
@@ -1,496 +0,0 @@
-/*============================================================================
-This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#ifndef _SOFTFLOAT_COMPARE_H_
-#define _SOFTFLOAT_COMPARE_H_
-
-#include "softfloat.h"
-
-// ======= float32 ======= //
-
-typedef int (*float32_compare_method)(float32, float32, struct float_status_t *status);
-
-// 0x00
-BX_CPP_INLINE int float32_eq_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_equal);
-}
-
-// 0x01
-BX_CPP_INLINE int float32_lt_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_less);
-}
-
-// 0x02
-BX_CPP_INLINE int float32_le_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_equal);
-}
-
-// 0x03
-BX_CPP_INLINE int float32_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_unordered);
-}
-
-// 0x04
-BX_CPP_INLINE int float32_neq_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation != float_relation_equal);
-}
-
-// 0x05
-BX_CPP_INLINE int float32_nlt_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation != float_relation_less);
-}
-
-// 0x06
-BX_CPP_INLINE int float32_nle_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation != float_relation_less) && (relation != float_relation_equal);
-}
-
-// 0x07
-BX_CPP_INLINE int float32_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation != float_relation_unordered);
-}
-
-// 0x08
-BX_CPP_INLINE int float32_eq_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_equal) || (relation == float_relation_unordered);
-}
-
-// 0x09
-BX_CPP_INLINE int float32_nge_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_unordered);
-}
-
-// 0x0a
-BX_CPP_INLINE int float32_ngt_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation != float_relation_greater);
-}
-
-// 0x0b
-BX_CPP_INLINE int float32_false_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- float32_compare_quiet(a, b, status);
- return 0;
-}
-
-// 0x0c
-BX_CPP_INLINE int float32_neq_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation != float_relation_equal) && (relation != float_relation_unordered);
-}
-
-// 0x0d
-BX_CPP_INLINE int float32_ge_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_greater) || (relation == float_relation_equal);
-}
-
-// 0x0e
-BX_CPP_INLINE int float32_gt_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_greater);
-}
-
-// 0x0f
-BX_CPP_INLINE int float32_true_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- float32_compare_quiet(a, b, status);
- return 1;
-}
-
-// 0x10
-BX_CPP_INLINE int float32_eq_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_equal);
-}
-
-// 0x11
-BX_CPP_INLINE int float32_lt_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_less);
-}
-
-// 0x12
-BX_CPP_INLINE int float32_le_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_equal);
-}
-
-// 0x13
-BX_CPP_INLINE int float32_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_unordered);
-}
-
-// 0x14
-BX_CPP_INLINE int float32_neq_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation != float_relation_equal);
-}
-
-// 0x15
-BX_CPP_INLINE int float32_nlt_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation != float_relation_less);
-}
-
-// 0x16
-BX_CPP_INLINE int float32_nle_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation != float_relation_less) && (relation != float_relation_equal);
-}
-
-// 0x17
-BX_CPP_INLINE int float32_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation != float_relation_unordered);
-}
-
-// 0x18
-BX_CPP_INLINE int float32_eq_unordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation == float_relation_equal) || (relation == float_relation_unordered);
-}
-
-// 0x19
-BX_CPP_INLINE int float32_nge_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_unordered);
-}
-
-// 0x1a
-BX_CPP_INLINE int float32_ngt_unordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation != float_relation_greater);
-}
-
-// 0x1b
-BX_CPP_INLINE int float32_false_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- float32_compare_two(a, b, status);
- return 0;
-}
-
-// 0x1c
-BX_CPP_INLINE int float32_neq_ordered_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_two(a, b, status);
- return (relation != float_relation_equal) && (relation != float_relation_unordered);
-}
-
-// 0x1d
-BX_CPP_INLINE int float32_ge_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_greater) || (relation == float_relation_equal);
-}
-
-// 0x1e
-BX_CPP_INLINE int float32_gt_ordered_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- int relation = float32_compare_quiet(a, b, status);
- return (relation == float_relation_greater);
-}
-
-// 0x1f
-BX_CPP_INLINE int float32_true_signalling(float32 a, float32 b, struct float_status_t *status)
-{
- float32_compare_two(a, b, status);
- return 1;
-}
-
-// ======= float64 ======= //
-
-typedef int (*float64_compare_method)(float64, float64, struct float_status_t *status);
-
-// 0x00
-BX_CPP_INLINE int float64_eq_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_equal);
-}
-
-// 0x01
-BX_CPP_INLINE int float64_lt_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_less);
-}
-
-// 0x02
-BX_CPP_INLINE int float64_le_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_equal);
-}
-
-// 0x03
-BX_CPP_INLINE int float64_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_unordered);
-}
-
-// 0x04
-BX_CPP_INLINE int float64_neq_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation != float_relation_equal);
-}
-
-// 0x05
-BX_CPP_INLINE int float64_nlt_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation != float_relation_less);
-}
-
-// 0x06
-BX_CPP_INLINE int float64_nle_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation != float_relation_less) && (relation != float_relation_equal);
-}
-
-// 0x07
-BX_CPP_INLINE int float64_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation != float_relation_unordered);
-}
-
-// 0x08
-BX_CPP_INLINE int float64_eq_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_equal) || (relation == float_relation_unordered);
-}
-
-// 0x09
-BX_CPP_INLINE int float64_nge_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_unordered);
-}
-
-// 0x0a
-BX_CPP_INLINE int float64_ngt_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation != float_relation_greater);
-}
-
-// 0x0b
-BX_CPP_INLINE int float64_false_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- float64_compare_quiet(a, b, status);
- return 0;
-}
-
-// 0x0c
-BX_CPP_INLINE int float64_neq_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation != float_relation_equal) && (relation != float_relation_unordered);
-}
-
-// 0x0d
-BX_CPP_INLINE int float64_ge_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_greater) || (relation == float_relation_equal);
-}
-
-// 0x0e
-BX_CPP_INLINE int float64_gt_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_greater);
-}
-
-// 0x0f
-BX_CPP_INLINE int float64_true_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- float64_compare_quiet(a, b, status);
- return 1;
-}
-
-// 0x10
-BX_CPP_INLINE int float64_eq_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_equal);
-}
-
-// 0x11
-BX_CPP_INLINE int float64_lt_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_less);
-}
-
-// 0x12
-BX_CPP_INLINE int float64_le_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_equal);
-}
-
-// 0x13
-BX_CPP_INLINE int float64_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_unordered);
-}
-
-// 0x14
-BX_CPP_INLINE int float64_neq_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation != float_relation_equal);
-}
-
-// 0x15
-BX_CPP_INLINE int float64_nlt_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation != float_relation_less);
-}
-
-// 0x16
-BX_CPP_INLINE int float64_nle_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation != float_relation_less) && (relation != float_relation_equal);
-}
-
-// 0x17
-BX_CPP_INLINE int float64_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation != float_relation_unordered);
-}
-
-// 0x18
-BX_CPP_INLINE int float64_eq_unordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation == float_relation_equal) || (relation == float_relation_unordered);
-}
-
-// 0x19
-BX_CPP_INLINE int float64_nge_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_less) || (relation == float_relation_unordered);
-}
-
-// 0x1a
-BX_CPP_INLINE int float64_ngt_unordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation != float_relation_greater);
-}
-
-// 0x1b
-BX_CPP_INLINE int float64_false_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- float64_compare_two(a, b, status);
- return 0;
-}
-
-// 0x1c
-BX_CPP_INLINE int float64_neq_ordered_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_two(a, b, status);
- return (relation != float_relation_equal) && (relation != float_relation_unordered);
-}
-
-// 0x1d
-BX_CPP_INLINE int float64_ge_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_greater) || (relation == float_relation_equal);
-}
-
-// 0x1e
-BX_CPP_INLINE int float64_gt_ordered_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- int relation = float64_compare_quiet(a, b, status);
- return (relation == float_relation_greater);
-}
-
-// 0x1f
-BX_CPP_INLINE int float64_true_signalling(float64 a, float64 b, struct float_status_t *status)
-{
- float64_compare_two(a, b, status);
- return 1;
-}
-
-#endif
diff --git a/src/cpu/softfloat/softfloat-macros.h b/src/cpu/softfloat/softfloat-macros.h
deleted file mode 100644
index cb867bf5d..000000000
--- a/src/cpu/softfloat/softfloat-macros.h
+++ /dev/null
@@ -1,686 +0,0 @@
-/*============================================================================
-This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#ifndef _SOFTFLOAT_MACROS_H_
-#define _SOFTFLOAT_MACROS_H_
-
-/*----------------------------------------------------------------------------
-| Shifts `a' right by the number of bits given in `count'. If any nonzero
-| bits are shifted off, they are ``jammed'' into the least significant bit of
-| the result by setting the least significant bit to 1. The value of `count'
-| can be arbitrarily large; in particular, if `count' is greater than 16, the
-| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit16u shift16RightJamming(Bit16u a, int count)
-{
- Bit16u z;
-
- if (count == 0) {
- z = a;
- }
- else if (count < 16) {
- z = (a>>count) | ((a<<((-count) & 15)) != 0);
- }
- else {
- z = (a != 0);
- }
-
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Shifts `a' right by the number of bits given in `count'. If any nonzero
-| bits are shifted off, they are ``jammed'' into the least significant bit of
-| the result by setting the least significant bit to 1. The value of `count'
-| can be arbitrarily large; in particular, if `count' is greater than 32, the
-| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit32u shift32RightJamming(Bit32u a, int count)
-{
- Bit32u z;
-
- if (count == 0) {
- z = a;
- }
- else if (count < 32) {
- z = (a>>count) | ((a<<((-count) & 31)) != 0);
- }
- else {
- z = (a != 0);
- }
-
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Shifts `a' right by the number of bits given in `count'. If any nonzero
-| bits are shifted off, they are ``jammed'' into the least significant bit of
-| the result by setting the least significant bit to 1. The value of `count'
-| can be arbitrarily large; in particular, if `count' is greater than 64, the
-| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit64u shift64RightJamming(Bit64u a, int count)
-{
- Bit64u z;
-
- if (count == 0) {
- z = a;
- }
- else if (count < 64) {
- z = (a>>count) | ((a << ((-count) & 63)) != 0);
- }
- else {
- z = (a != 0);
- }
-
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
-| _plus_ the number of bits given in `count'. The shifted result is at most
-| 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The
-| bits shifted off form a second 64-bit result as follows: The _last_ bit
-| shifted off is the most-significant bit of the extra result, and the other
-| 63 bits of the extra result are all zero if and only if _all_but_the_last_
-| bits shifted off were all zero. This extra result is stored in the location
-| pointed to by `z1Ptr'. The value of `count' can be arbitrarily large.
-| (This routine makes more sense if `a0' and `a1' are considered to form
-| a fixed-point value with binary point between `a0' and `a1'. This fixed-
-| point value is shifted right by the number of bits given in `count', and
-| the integer part of the result is returned at the location pointed to by
-| `z0Ptr'. The fractional part of the result may be slightly corrupted as
-| described above, and is returned at the location pointed to by `z1Ptr'.)
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void shift64ExtraRightJamming(Bit64u a0, Bit64u a1, int count, Bit64u *z0Ptr, Bit64u *z1Ptr)
-{
- Bit64u z0, z1;
- int negCount = (-count) & 63;
-
- if (count == 0) {
- z1 = a1;
- z0 = a0;
- }
- else if (count < 64) {
- z1 = (a0<>count;
- }
- else {
- if (count == 64) {
- z1 = a0 | (a1 != 0);
- }
- else {
- z1 = ((a0 | a1) != 0);
- }
- z0 = 0;
- }
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-/*----------------------------------------------------------------------------
-| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
-| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so
-| any carry out is lost. The result is broken into two 64-bit pieces which
-| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void add128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1, Bit64u *z0Ptr, Bit64u *z1Ptr)
-{
- Bit64u z1 = a1 + b1;
- *z1Ptr = z1;
- *z0Ptr = a0 + b0 + (z1 < a1);
-}
-
-/*----------------------------------------------------------------------------
-| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the
-| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo
-| 2^128, so any borrow out (carry out) is lost. The result is broken into two
-| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
-| `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void
- sub128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1, Bit64u *z0Ptr, Bit64u *z1Ptr)
-{
- *z1Ptr = a1 - b1;
- *z0Ptr = a0 - b0 - (a1 < b1);
-}
-
-/*----------------------------------------------------------------------------
-| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken
-| into two 64-bit pieces which are stored at the locations pointed to by
-| `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void mul64To128(Bit64u a, Bit64u b, Bit64u *z0Ptr, Bit64u *z1Ptr)
-{
- Bit32u aHigh, aLow, bHigh, bLow;
- Bit64u z0, zMiddleA, zMiddleB, z1;
-
- aLow = (Bit32u) a;
- aHigh = (Bit32u)(a>>32);
- bLow = (Bit32u) b;
- bHigh = (Bit32u)(b>>32);
- z1 = ((Bit64u) aLow) * bLow;
- zMiddleA = ((Bit64u) aLow) * bHigh;
- zMiddleB = ((Bit64u) aHigh) * bLow;
- z0 = ((Bit64u) aHigh) * bHigh;
- zMiddleA += zMiddleB;
- z0 += (((Bit64u) (zMiddleA < zMiddleB))<<32) + (zMiddleA>>32);
- zMiddleA <<= 32;
- z1 += zMiddleA;
- z0 += (z1 < zMiddleA);
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-/*----------------------------------------------------------------------------
-| Returns an approximation to the 64-bit integer quotient obtained by dividing
-| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The
-| divisor `b' must be at least 2^63. If q is the exact quotient truncated
-| toward zero, the approximation returned lies between q and q + 2 inclusive.
-| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit
-| unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-#ifdef USE_estimateDiv128To64
-static Bit64u estimateDiv128To64(Bit64u a0, Bit64u a1, Bit64u b)
-{
- Bit64u b0, b1;
- Bit64u rem0, rem1, term0, term1;
- Bit64u z;
-
- if (b <= a0) return BX_CONST64(0xFFFFFFFFFFFFFFFF);
- b0 = b>>32;
- z = (b0<<32 <= a0) ? BX_CONST64(0xFFFFFFFF00000000) : (a0 / b0)<<32;
- mul64To128(b, z, &term0, &term1);
- sub128(a0, a1, term0, term1, &rem0, &rem1);
- while (((Bit64s) rem0) < 0) {
- z -= BX_CONST64(0x100000000);
- b1 = b<<32;
- add128(rem0, rem1, b0, b1, &rem0, &rem1);
- }
- rem0 = (rem0<<32) | (rem1>>32);
- z |= (b0<<32 <= rem0) ? 0xFFFFFFFF : rem0 / b0;
- return z;
-}
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns an approximation to the square root of the 32-bit significand given
-| by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of
-| `aExp' (the least significant bit) is 1, the integer returned approximates
-| 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp'
-| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either
-| case, the approximation returned lies strictly within +/-2 of the exact
-| value.
-*----------------------------------------------------------------------------*/
-
-#ifdef USE_estimateSqrt32
-static Bit32u estimateSqrt32(Bit16s aExp, Bit32u a)
-{
- static const Bit16u sqrtOddAdjustments[] = {
- 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
- 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
- };
- static const Bit16u sqrtEvenAdjustments[] = {
- 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
- 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
- };
- Bit32u z;
-
- int index = (a>>27) & 15;
- if (aExp & 1) {
- z = 0x4000 + (a>>17) - sqrtOddAdjustments[index];
- z = ((a / z)<<14) + (z<<15);
- a >>= 1;
- }
- else {
- z = 0x8000 + (a>>17) - sqrtEvenAdjustments[index];
- z = a / z + z;
- z = (0x20000 <= z) ? 0xFFFF8000 : (z<<15);
- if (z <= a) return (Bit32u) (((Bit32s) a)>>1);
- }
- return ((Bit32u) ((((Bit64u) a)<<31) / z)) + (z>>1);
-}
-#endif
-
-static const int countLeadingZeros8[] = {
- 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-#ifdef FLOAT16
-
-/*----------------------------------------------------------------------------
-| Returns the number of leading 0 bits before the most-significant 1 bit of
-| `a'. If `a' is zero, 16 is returned.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int countLeadingZeros16(Bit16u a)
-{
- int shiftCount = 0;
- if (a < 0x100) {
- shiftCount += 8;
- a <<= 8;
- }
- shiftCount += countLeadingZeros8[a>>8];
- return shiftCount;
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns the number of leading 0 bits before the most-significant 1 bit of
-| `a'. If `a' is zero, 32 is returned.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int countLeadingZeros32(Bit32u a)
-{
- int shiftCount = 0;
- if (a < 0x10000) {
- shiftCount += 16;
- a <<= 16;
- }
- if (a < 0x1000000) {
- shiftCount += 8;
- a <<= 8;
- }
- shiftCount += countLeadingZeros8[a>>24];
- return shiftCount;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the number of leading 0 bits before the most-significant 1 bit of
-| `a'. If `a' is zero, 64 is returned.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int countLeadingZeros64(Bit64u a)
-{
- int shiftCount = 0;
- if (a < BX_CONST64(0x100000000)) {
- shiftCount += 32;
- }
- else {
- a >>= 32;
- }
- shiftCount += countLeadingZeros32((Bit32u)(a));
- return shiftCount;
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
-| number of bits given in `count'. Any bits shifted off are lost. The value
-| of `count' can be arbitrarily large; in particular, if `count' is greater
-| than 128, the result will be 0. The result is broken into two 64-bit pieces
-| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void shift128Right(Bit64u a0, Bit64u a1, int count, Bit64u *z0Ptr, Bit64u *z1Ptr)
-{
- Bit64u z0, z1;
- int negCount = (-count) & 63;
-
- if (count == 0) {
- z1 = a1;
- z0 = a0;
- }
- else if (count < 64) {
- z1 = (a0<>count);
- z0 = a0>>count;
- }
- else {
- z1 = (count < 128) ? (a0>>(count & 63)) : 0;
- z0 = 0;
- }
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-/*----------------------------------------------------------------------------
-| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
-| number of bits given in `count'. If any nonzero bits are shifted off, they
-| are ``jammed'' into the least significant bit of the result by setting the
-| least significant bit to 1. The value of `count' can be arbitrarily large;
-| in particular, if `count' is greater than 128, the result will be either
-| 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or
-| nonzero. The result is broken into two 64-bit pieces which are stored at
-| the locations pointed to by `z0Ptr' and `z1Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void shift128RightJamming(Bit64u a0, Bit64u a1, int count, Bit64u *z0Ptr, Bit64u *z1Ptr)
-{
- Bit64u z0, z1;
- int negCount = (-count) & 63;
-
- if (count == 0) {
- z1 = a1;
- z0 = a0;
- }
- else if (count < 64) {
- z1 = (a0<>count) | ((a1<>count;
- }
- else {
- if (count == 64) {
- z1 = a0 | (a1 != 0);
- }
- else if (count < 128) {
- z1 = (a0>>(count & 63)) | (((a0<>((-count) & 63));
-}
-
-/*----------------------------------------------------------------------------
-| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
-| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is
-| modulo 2^192, so any carry out is lost. The result is broken into three
-| 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
-| `z1Ptr', and `z2Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void add192(
- Bit64u a0,
- Bit64u a1,
- Bit64u a2,
- Bit64u b0,
- Bit64u b1,
- Bit64u b2,
- Bit64u *z0Ptr,
- Bit64u *z1Ptr,
- Bit64u *z2Ptr
-)
-{
- Bit64u z0, z1, z2;
- unsigned carry0, carry1;
-
- z2 = a2 + b2;
- carry1 = (z2 < a2);
- z1 = a1 + b1;
- carry0 = (z1 < a1);
- z0 = a0 + b0;
- z1 += carry1;
- z0 += (z1 < carry1);
- z0 += carry0;
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-/*----------------------------------------------------------------------------
-| Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
-| from the 192-bit value formed by concatenating `a0', `a1', and `a2'.
-| Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The
-| result is broken into three 64-bit pieces which are stored at the locations
-| pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void sub192(
- Bit64u a0,
- Bit64u a1,
- Bit64u a2,
- Bit64u b0,
- Bit64u b1,
- Bit64u b2,
- Bit64u *z0Ptr,
- Bit64u *z1Ptr,
- Bit64u *z2Ptr
-)
-{
- Bit64u z0, z1, z2;
- unsigned borrow0, borrow1;
-
- z2 = a2 - b2;
- borrow1 = (a2 < b2);
- z1 = a1 - b1;
- borrow0 = (a1 < b1);
- z0 = a0 - b0;
- z0 -= (z1 < borrow1);
- z1 -= borrow1;
- z0 -= borrow0;
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
-| is equal to the 128-bit value formed by concatenating `b0' and `b1'.
-| Otherwise, returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int eq128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1)
-{
- return (a0 == b0) && (a1 == b1);
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
-| than or equal to the 128-bit value formed by concatenating `b0' and `b1'.
-| Otherwise, returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int le128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1)
-{
- return (a0 < b0) || ((a0 == b0) && (a1 <= b1));
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
-| than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise,
-| returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int lt128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1)
-{
- return (a0 < b0) || ((a0 == b0) && (a1 < b1));
-}
-
-#endif /* FLOATX80 */
-
-/*----------------------------------------------------------------------------
-| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by
-| `b' to obtain a 192-bit product. The product is broken into three 64-bit
-| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
-| `z2Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void mul128By64To192(
- Bit64u a0,
- Bit64u a1,
- Bit64u b,
- Bit64u *z0Ptr,
- Bit64u *z1Ptr,
- Bit64u *z2Ptr
-)
-{
- Bit64u z0, z1, z2, more1;
-
- mul64To128(a1, b, &z1, &z2);
- mul64To128(a0, b, &z0, &more1);
- add128(z0, more1, 0, z1, &z0, &z1);
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the
-| 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
-| product. The product is broken into four 64-bit pieces which are stored at
-| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void mul128To256(
- Bit64u a0,
- Bit64u a1,
- Bit64u b0,
- Bit64u b1,
- Bit64u *z0Ptr,
- Bit64u *z1Ptr,
- Bit64u *z2Ptr,
- Bit64u *z3Ptr
-)
-{
- Bit64u z0, z1, z2, z3;
- Bit64u more1, more2;
-
- mul64To128(a1, b1, &z2, &z3);
- mul64To128(a1, b0, &z1, &more2);
- add128(z1, more2, 0, z2, &z1, &z2);
- mul64To128(a0, b0, &z0, &more1);
- add128(z0, more1, 0, z1, &z0, &z1);
- mul64To128(a0, b1, &more1, &more2);
- add128(more1, more2, 0, z2, &more1, &z2);
- add128(z0, z1, 0, more1, &z0, &z1);
- *z3Ptr = z3;
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-
-/*----------------------------------------------------------------------------
-| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
-| by 64 _plus_ the number of bits given in `count'. The shifted result is
-| at most 128 nonzero bits; these are broken into two 64-bit pieces which are
-| stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted
-| off form a third 64-bit result as follows: The _last_ bit shifted off is
-| the most-significant bit of the extra result, and the other 63 bits of the
-| extra result are all zero if and only if _all_but_the_last_ bits shifted off
-| were all zero. This extra result is stored in the location pointed to by
-| `z2Ptr'. The value of `count' can be arbitrarily large.
-| (This routine makes more sense if `a0', `a1', and `a2' are considered
-| to form a fixed-point value with binary point between `a1' and `a2'. This
-| fixed-point value is shifted right by the number of bits given in `count',
-| and the integer part of the result is returned at the locations pointed to
-| by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly
-| corrupted as described above, and is returned at the location pointed to by
-| `z2Ptr'.)
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void shift128ExtraRightJamming(
- Bit64u a0,
- Bit64u a1,
- Bit64u a2,
- int count,
- Bit64u *z0Ptr,
- Bit64u *z1Ptr,
- Bit64u *z2Ptr
-)
-{
- Bit64u z0, z1, z2;
- int negCount = (-count) & 63;
-
- if (count == 0) {
- z2 = a2;
- z1 = a1;
- z0 = a0;
- }
- else {
- if (count < 64) {
- z2 = a1<>count);
- z0 = a0>>count;
- }
- else {
- if (count == 64) {
- z2 = a1;
- z1 = a0;
- }
- else {
- a2 |= a1;
- if (count < 128) {
- z2 = a0<>(count & 63);
- }
- else {
- z2 = (count == 128) ? a0 : (a0 != 0);
- z1 = 0;
- }
- }
- z0 = 0;
- }
- z2 |= (a2 != 0);
- }
- *z2Ptr = z2;
- *z1Ptr = z1;
- *z0Ptr = z0;
-}
-
-#endif /* FLOAT128 */
-
-#endif
diff --git a/src/cpu/softfloat/softfloat-muladd.cc b/src/cpu/softfloat/softfloat-muladd.cc
deleted file mode 100644
index 7c9fec70e..000000000
--- a/src/cpu/softfloat/softfloat-muladd.cc
+++ /dev/null
@@ -1,558 +0,0 @@
-/*============================================================================
-This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * This code is based on QEMU patch by Peter Maydell
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#include "softfloat.h"
-#include "softfloat-round-pack.h"
-
-/*----------------------------------------------------------------------------
-| Primitive arithmetic functions, including multi-word arithmetic, and
-| division and square root approximations. (Can be specialized to target
-| if desired).
-*----------------------------------------------------------------------------*/
-#include "softfloat-macros.h"
-
-/*----------------------------------------------------------------------------
-| Functions and definitions to determine: (1) whether tininess for underflow
-| is detected before or after rounding by default, (2) what (if anything)
-| happens when exceptions are raised, (3) how signaling NaNs are distinguished
-| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
-| are propagated from function inputs to output. These details are target-
-| specific.
-*----------------------------------------------------------------------------*/
-#include "softfloat-specialize.h"
-
-/*----------------------------------------------------------------------------
-| Takes three single-precision floating-point values `a', `b' and `c', one of
-| which is a NaN, and returns the appropriate NaN result. If any of `a',
-| `b' or `c' is a signaling NaN, the invalid exception is raised.
-| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case
-| obviously c is a NaN, and whether to propagate c or some other NaN is
-| implementation defined).
-*----------------------------------------------------------------------------*/
-
-static float32 propagateFloat32MulAddNaN(float32 a, float32 b, float32 c, struct float_status_t *status)
-{
- int aIsNaN = float32_is_nan(a);
- int bIsNaN = float32_is_nan(b);
-
- int aIsSignalingNaN = float32_is_signaling_nan(a);
- int bIsSignalingNaN = float32_is_signaling_nan(b);
- int cIsSignalingNaN = float32_is_signaling_nan(c);
-
- a |= 0x00400000;
- b |= 0x00400000;
- c |= 0x00400000;
-
- if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN)
- float_raise(status, float_flag_invalid);
-
- // operate according to float_first_operand_nan mode
- if (aIsSignalingNaN | aIsNaN) {
- return a;
- }
- else {
- return (bIsSignalingNaN | bIsNaN) ? b : c;
- }
-}
-
-/*----------------------------------------------------------------------------
-| Takes three double-precision floating-point values `a', `b' and `c', one of
-| which is a NaN, and returns the appropriate NaN result. If any of `a',
-| `b' or `c' is a signaling NaN, the invalid exception is raised.
-| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case
-| obviously c is a NaN, and whether to propagate c or some other NaN is
-| implementation defined).
-*----------------------------------------------------------------------------*/
-
-static float64 propagateFloat64MulAddNaN(float64 a, float64 b, float64 c, struct float_status_t *status)
-{
- int aIsNaN = float64_is_nan(a);
- int bIsNaN = float64_is_nan(b);
-
- int aIsSignalingNaN = float64_is_signaling_nan(a);
- int bIsSignalingNaN = float64_is_signaling_nan(b);
- int cIsSignalingNaN = float64_is_signaling_nan(c);
-
- a |= BX_CONST64(0x0008000000000000);
- b |= BX_CONST64(0x0008000000000000);
- c |= BX_CONST64(0x0008000000000000);
-
- if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN)
- float_raise(status, float_flag_invalid);
-
- // operate according to float_first_operand_nan mode
- if (aIsSignalingNaN | aIsNaN) {
- return a;
- }
- else {
- return (bIsSignalingNaN | bIsNaN) ? b : c;
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the single-precision floating-point values
-| `a' and `b' then adding 'c', with no intermediate rounding step after the
-| multiplication. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic 754-2008.
-| The flags argument allows the caller to select negation of the
-| addend, the intermediate product, or the final result. (The difference
-| between this and having the caller do a separate negation is that negating
-| externally will flip the sign bit on NaNs.)
-*----------------------------------------------------------------------------*/
-
-float32 float32_muladd(float32 a, float32 b, float32 c, int flags, struct float_status_t *status)
-{
- int aSign, bSign, cSign, zSign;
- Bit16s aExp, bExp, cExp, pExp, zExp;
- Bit32u aSig, bSig, cSig;
- int pInf, pZero, pSign;
- Bit64u pSig64, cSig64, zSig64;
- Bit32u pSig;
- int shiftcount;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
- bSig = extractFloat32Frac(b);
- bExp = extractFloat32Exp(b);
- bSign = extractFloat32Sign(b);
- cSig = extractFloat32Frac(c);
- cExp = extractFloat32Exp(c);
- cSign = extractFloat32Sign(c);
-
- /* It is implementation-defined whether the cases of (0,inf,qnan)
- * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN
- * they return if they do), so we have to hand this information
- * off to the target-specific pick-a-NaN routine.
- */
- if (((aExp == 0xff) && aSig) ||
- ((bExp == 0xff) && bSig) ||
- ((cExp == 0xff) && cSig)) {
- return propagateFloat32MulAddNaN(a, b, c, status);
- }
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- if (cExp == 0) cSig = 0;
- }
-
- int infzero = ((aExp == 0 && aSig == 0 && bExp == 0xff && bSig == 0) ||
- (aExp == 0xff && aSig == 0 && bExp == 0 && bSig == 0));
-
- if (infzero) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
-
- if (flags & float_muladd_negate_c) {
- cSign ^= 1;
- }
-
- /* Work out the sign and type of the product */
- pSign = aSign ^ bSign;
- if (flags & float_muladd_negate_product) {
- pSign ^= 1;
- }
- pInf = (aExp == 0xff) || (bExp == 0xff);
- pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0);
-
- if (cExp == 0xff) {
- if (pInf && (pSign ^ cSign)) {
- /* addition of opposite-signed infinities => InvalidOperation */
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- /* Otherwise generate an infinity of the same sign */
- if ((aSig && aExp == 0) || (bSig && bExp == 0)) {
- float_raise(status, float_flag_denormal);
- }
- return packFloat32(cSign, 0xff, 0);
- }
-
- if (pInf) {
- if ((aSig && aExp == 0) || (bSig && bExp == 0) || (cSig && cExp == 0)) {
- float_raise(status, float_flag_denormal);
- }
- return packFloat32(pSign, 0xff, 0);
- }
-
- if (pZero) {
- if (cExp == 0) {
- if (cSig == 0) {
- /* Adding two exact zeroes */
- if (pSign == cSign) {
- zSign = pSign;
- } else if (get_float_rounding_mode(status) == float_round_down) {
- zSign = 1;
- } else {
- zSign = 0;
- }
- return packFloat32(zSign, 0, 0);
- }
- /* Exact zero plus a denormal */
- float_raise(status, float_flag_denormal);
- if (get_flush_underflow_to_zero(status)) {
- float_raise(status, float_flag_underflow | float_flag_inexact);
- return packFloat32(cSign, 0, 0);
- }
- }
- /* Zero plus something non-zero */
- return packFloat32(cSign, cExp, cSig);
- }
-
- if (aExp == 0) {
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(bSig, &bExp, &bSig);
- }
-
- /* Calculate the actual result a * b + c */
-
- /* Multiply first; this is easy. */
- /* NB: we subtract 0x7e where float32_mul() subtracts 0x7f
- * because we want the true exponent, not the "one-less-than"
- * flavour that roundAndPackFloat32() takes.
- */
- pExp = aExp + bExp - 0x7e;
- aSig = (aSig | 0x00800000) << 7;
- bSig = (bSig | 0x00800000) << 8;
- pSig64 = (Bit64u)aSig * bSig;
- if ((Bit64s)(pSig64 << 1) >= 0) {
- pSig64 <<= 1;
- pExp--;
- }
-
- zSign = pSign;
-
- /* Now pSig64 is the significand of the multiply, with the explicit bit in
- * position 62.
- */
- if (cExp == 0) {
- if (!cSig) {
- /* Throw out the special case of c being an exact zero now */
- pSig = (Bit32u) shift64RightJamming(pSig64, 32);
- return roundAndPackFloat32(zSign, pExp - 1, pSig, status);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(cSig, &cExp, &cSig);
- }
-
- cSig64 = (Bit64u)cSig << 39;
- cSig64 |= BX_CONST64(0x4000000000000000);
- int expDiff = pExp - cExp;
-
- if (pSign == cSign) {
- /* Addition */
- if (expDiff > 0) {
- /* scale c to match p */
- cSig64 = shift64RightJamming(cSig64, expDiff);
- zExp = pExp;
- } else if (expDiff < 0) {
- /* scale p to match c */
- pSig64 = shift64RightJamming(pSig64, -expDiff);
- zExp = cExp;
- } else {
- /* no scaling needed */
- zExp = cExp;
- }
- /* Add significands and make sure explicit bit ends up in posn 62 */
- zSig64 = pSig64 + cSig64;
- if ((Bit64s)zSig64 < 0) {
- zSig64 = shift64RightJamming(zSig64, 1);
- } else {
- zExp--;
- }
- zSig64 = shift64RightJamming(zSig64, 32);
- return roundAndPackFloat32(zSign, zExp, zSig64, status);
- } else {
- /* Subtraction */
- if (expDiff > 0) {
- cSig64 = shift64RightJamming(cSig64, expDiff);
- zSig64 = pSig64 - cSig64;
- zExp = pExp;
- } else if (expDiff < 0) {
- pSig64 = shift64RightJamming(pSig64, -expDiff);
- zSig64 = cSig64 - pSig64;
- zExp = cExp;
- zSign ^= 1;
- } else {
- zExp = pExp;
- if (cSig64 < pSig64) {
- zSig64 = pSig64 - cSig64;
- } else if (pSig64 < cSig64) {
- zSig64 = cSig64 - pSig64;
- zSign ^= 1;
- } else {
- /* Exact zero */
- return packFloat32(get_float_rounding_mode(status) == float_round_down, 0, 0);
- }
- }
- --zExp;
- /* Do the equivalent of normalizeRoundAndPackFloat32() but
- * starting with the significand in a Bit64u.
- */
- shiftcount = countLeadingZeros64(zSig64) - 1;
- zSig64 <<= shiftcount;
- zExp -= shiftcount;
- zSig64 = shift64RightJamming(zSig64, 32);
- return roundAndPackFloat32(zSign, zExp, zSig64, status);
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the double-precision floating-point values
-| `a' and `b' then adding 'c', with no intermediate rounding step after the
-| multiplication. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic 754-2008.
-| The flags argument allows the caller to select negation of the
-| addend, the intermediate product, or the final result. (The difference
-| between this and having the caller do a separate negation is that negating
-| externally will flip the sign bit on NaNs.)
-*----------------------------------------------------------------------------*/
-
-float64 float64_muladd(float64 a, float64 b, float64 c, int flags, struct float_status_t *status)
-{
- int aSign, bSign, cSign, zSign;
- Bit16s aExp, bExp, cExp, pExp, zExp;
- Bit64u aSig, bSig, cSig;
- int pInf, pZero, pSign;
- Bit64u pSig0, pSig1, cSig0, cSig1, zSig0, zSig1;
- int shiftcount;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
- bSig = extractFloat64Frac(b);
- bExp = extractFloat64Exp(b);
- bSign = extractFloat64Sign(b);
- cSig = extractFloat64Frac(c);
- cExp = extractFloat64Exp(c);
- cSign = extractFloat64Sign(c);
-
- /* It is implementation-defined whether the cases of (0,inf,qnan)
- * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN
- * they return if they do), so we have to hand this information
- * off to the target-specific pick-a-NaN routine.
- */
- if (((aExp == 0x7ff) && aSig) ||
- ((bExp == 0x7ff) && bSig) ||
- ((cExp == 0x7ff) && cSig)) {
- return propagateFloat64MulAddNaN(a, b, c, status);
- }
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- if (cExp == 0) cSig = 0;
- }
-
- int infzero = ((aExp == 0 && aSig == 0 && bExp == 0x7ff && bSig == 0) ||
- (aExp == 0x7ff && aSig == 0 && bExp == 0 && bSig == 0));
-
- if (infzero) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
-
- if (flags & float_muladd_negate_c) {
- cSign ^= 1;
- }
-
- /* Work out the sign and type of the product */
- pSign = aSign ^ bSign;
- if (flags & float_muladd_negate_product) {
- pSign ^= 1;
- }
- pInf = (aExp == 0x7ff) || (bExp == 0x7ff);
- pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0);
-
- if (cExp == 0x7ff) {
- if (pInf && (pSign ^ cSign)) {
- /* addition of opposite-signed infinities => InvalidOperation */
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- /* Otherwise generate an infinity of the same sign */
- if ((aSig && aExp == 0) || (bSig && bExp == 0)) {
- float_raise(status, float_flag_denormal);
- }
- return packFloat64(cSign, 0x7ff, 0);
- }
-
- if (pInf) {
- if ((aSig && aExp == 0) || (bSig && bExp == 0) || (cSig && cExp == 0)) {
- float_raise(status, float_flag_denormal);
- }
- return packFloat64(pSign, 0x7ff, 0);
- }
-
- if (pZero) {
- if (cExp == 0) {
- if (cSig == 0) {
- /* Adding two exact zeroes */
- if (pSign == cSign) {
- zSign = pSign;
- } else if (get_float_rounding_mode(status) == float_round_down) {
- zSign = 1;
- } else {
- zSign = 0;
- }
- return packFloat64(zSign, 0, 0);
- }
- /* Exact zero plus a denormal */
- float_raise(status, float_flag_denormal);
- if (get_flush_underflow_to_zero(status)) {
- float_raise(status, float_flag_underflow | float_flag_inexact);
- return packFloat64(cSign, 0, 0);
- }
- }
- /* Zero plus something non-zero */
- return packFloat64(cSign, cExp, cSig);
- }
-
- if (aExp == 0) {
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(bSig, &bExp, &bSig);
- }
-
- /* Calculate the actual result a * b + c */
-
- /* Multiply first; this is easy. */
- /* NB: we subtract 0x3fe where float64_mul() subtracts 0x3ff
- * because we want the true exponent, not the "one-less-than"
- * flavour that roundAndPackFloat64() takes.
- */
- pExp = aExp + bExp - 0x3fe;
- aSig = (aSig | BX_CONST64(0x0010000000000000))<<10;
- bSig = (bSig | BX_CONST64(0x0010000000000000))<<11;
- mul64To128(aSig, bSig, &pSig0, &pSig1);
- if ((Bit64s)(pSig0 << 1) >= 0) {
- shortShift128Left(pSig0, pSig1, 1, &pSig0, &pSig1);
- pExp--;
- }
-
- zSign = pSign;
-
- /* Now [pSig0:pSig1] is the significand of the multiply, with the explicit
- * bit in position 126.
- */
- if (cExp == 0) {
- if (!cSig) {
- /* Throw out the special case of c being an exact zero now */
- shift128RightJamming(pSig0, pSig1, 64, &pSig0, &pSig1);
- return roundAndPackFloat64(zSign, pExp - 1, pSig1, status);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(cSig, &cExp, &cSig);
- }
-
- cSig0 = cSig << 10;
- cSig1 = 0;
- cSig0 |= BX_CONST64(0x4000000000000000);
- int expDiff = pExp - cExp;
-
- if (pSign == cSign) {
- /* Addition */
- if (expDiff > 0) {
- /* scale c to match p */
- shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1);
- zExp = pExp;
- } else if (expDiff < 0) {
- /* scale p to match c */
- shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1);
- zExp = cExp;
- } else {
- /* no scaling needed */
- zExp = cExp;
- }
- /* Add significands and make sure explicit bit ends up in posn 126 */
- add128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1);
- if ((Bit64s)zSig0 < 0) {
- shift128RightJamming(zSig0, zSig1, 1, &zSig0, &zSig1);
- } else {
- zExp--;
- }
- shift128RightJamming(zSig0, zSig1, 64, &zSig0, &zSig1);
- return roundAndPackFloat64(zSign, zExp, zSig1, status);
- } else {
- /* Subtraction */
- if (expDiff > 0) {
- shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1);
- sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1);
- zExp = pExp;
- } else if (expDiff < 0) {
- shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1);
- sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1);
- zExp = cExp;
- zSign ^= 1;
- } else {
- zExp = pExp;
- if (lt128(cSig0, cSig1, pSig0, pSig1)) {
- sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1);
- } else if (lt128(pSig0, pSig1, cSig0, cSig1)) {
- sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1);
- zSign ^= 1;
- } else {
- /* Exact zero */
- return packFloat64(get_float_rounding_mode(status) == float_round_down, 0, 0);
- }
- }
- --zExp;
- /* Do the equivalent of normalizeRoundAndPackFloat64() but
- * starting with the significand in a pair of Bit64u.
- */
- if (zSig0) {
- shiftcount = countLeadingZeros64(zSig0) - 1;
- shortShift128Left(zSig0, zSig1, shiftcount, &zSig0, &zSig1);
- if (zSig1) {
- zSig0 |= 1;
- }
- zExp -= shiftcount;
- } else {
- shiftcount = countLeadingZeros64(zSig1) - 1;
- zSig0 = zSig1 << shiftcount;
- zExp -= (shiftcount + 64);
- }
- return roundAndPackFloat64(zSign, zExp, zSig0, status);
- }
-}
diff --git a/src/cpu/softfloat/softfloat-round-pack.cc b/src/cpu/softfloat/softfloat-round-pack.cc
deleted file mode 100644
index 2b3965840..000000000
--- a/src/cpu/softfloat/softfloat-round-pack.cc
+++ /dev/null
@@ -1,896 +0,0 @@
-/*============================================================================
-This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-#define FLOAT128
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#include "softfloat.h"
-#include "softfloat-round-pack.h"
-
-/*----------------------------------------------------------------------------
-| Primitive arithmetic functions, including multi-word arithmetic, and
-| division and square root approximations. (Can be specialized to target
-| if desired).
-*----------------------------------------------------------------------------*/
-#include "softfloat-macros.h"
-
-/*----------------------------------------------------------------------------
-| Functions and definitions to determine: (1) whether tininess for underflow
-| is detected before or after rounding by default, (2) what (if anything)
-| happens when exceptions are raised, (3) how signaling NaNs are distinguished
-| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
-| are propagated from function inputs to output. These details are target-
-| specific.
-*----------------------------------------------------------------------------*/
-#include "softfloat-specialize.h"
-
-/*----------------------------------------------------------------------------
-| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
-| and 7, and returns the properly rounded 32-bit integer corresponding to the
-| input. If `zSign' is 1, the input is negated before being converted to an
-| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input
-| is simply rounded to an integer, with the inexact exception raised if the
-| input cannot be represented exactly as an integer. However, if the fixed-
-| point input is too large, the invalid exception is raised and the integer
-| indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32s roundAndPackInt32(int zSign, Bit64u exactAbsZ, struct float_status_t *status)
-{
- int roundingMode = get_float_rounding_mode(status);
- int roundNearestEven = (roundingMode == float_round_nearest_even);
- int roundIncrement = 0x40;
- if (! roundNearestEven) {
- if (roundingMode == float_round_to_zero) roundIncrement = 0;
- else {
- roundIncrement = 0x7F;
- if (zSign) {
- if (roundingMode == float_round_up) roundIncrement = 0;
- }
- else {
- if (roundingMode == float_round_down) roundIncrement = 0;
- }
- }
- }
- int roundBits = (int)(exactAbsZ & 0x7F);
- Bit64u absZ = (exactAbsZ + roundIncrement)>>7;
- absZ &= ~(((roundBits ^ 0x40) == 0) & roundNearestEven);
- Bit32s z = (Bit32s) absZ;
- if (zSign) z = -z;
- if ((absZ>>32) || (z && ((z < 0) ^ zSign))) {
- float_raise(status, float_flag_invalid);
- return (Bit32s)(int32_indefinite);
- }
- if (roundBits) {
- float_raise(status, float_flag_inexact);
- if ((absZ << 7) > exactAbsZ)
- set_float_rounding_up(status);
- }
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
-| `absZ1', with binary point between bits 63 and 64 (between the input words),
-| and returns the properly rounded 64-bit integer corresponding to the input.
-| If `zSign' is 1, the input is negated before being converted to an integer.
-| Ordinarily, the fixed-point input is simply rounded to an integer, with
-| the inexact exception raised if the input cannot be represented exactly as
-| an integer. However, if the fixed-point input is too large, the invalid
-| exception is raised and the integer indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64s roundAndPackInt64(int zSign, Bit64u absZ0, Bit64u absZ1, struct float_status_t *status)
-{
- Bit64s z;
- int roundingMode = get_float_rounding_mode(status);
- int roundNearestEven = (roundingMode == float_round_nearest_even);
- int increment = ((Bit64s) absZ1 < 0);
- if (! roundNearestEven) {
- if (roundingMode == float_round_to_zero) increment = 0;
- else {
- if (zSign) {
- increment = (roundingMode == float_round_down) && absZ1;
- }
- else {
- increment = (roundingMode == float_round_up) && absZ1;
- }
- }
- }
- Bit64u exactAbsZ0 = absZ0;
- if (increment) {
- ++absZ0;
- if (absZ0 == 0) goto overflow;
- absZ0 &= ~(((Bit64u) (absZ1<<1) == 0) & roundNearestEven);
- }
- z = absZ0;
- if (zSign) z = -z;
- if (z && ((z < 0) ^ zSign)) {
- overflow:
- float_raise(status, float_flag_invalid);
- return (Bit64s)(int64_indefinite);
- }
- if (absZ1) {
- float_raise(status, float_flag_inexact);
- if (absZ0 > exactAbsZ0)
- set_float_rounding_up(status);
- }
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
-| `absZ1', with binary point between bits 63 and 64 (between the input words),
-| and returns the properly rounded 64-bit unsigned integer corresponding to the
-| input. Ordinarily, the fixed-point input is simply rounded to an integer,
-| with the inexact exception raised if the input cannot be represented exactly
-| as an integer. However, if the fixed-point input is too large, the invalid
-| exception is raised and the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64u roundAndPackUint64(int zSign, Bit64u absZ0, Bit64u absZ1, struct float_status_t *status)
-{
- int roundingMode = get_float_rounding_mode(status);
- int roundNearestEven = (roundingMode == float_round_nearest_even);
- int increment = ((Bit64s) absZ1 < 0);
- if (!roundNearestEven) {
- if (roundingMode == float_round_to_zero) {
- increment = 0;
- } else if (absZ1) {
- if (zSign) {
- increment = (roundingMode == float_round_down) && absZ1;
- } else {
- increment = (roundingMode == float_round_up) && absZ1;
- }
- }
- }
- if (increment) {
- ++absZ0;
- if (absZ0 == 0) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
- absZ0 &= ~(((Bit64u) (absZ1<<1) == 0) & roundNearestEven);
- }
-
- if (zSign && absZ0) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
-
- if (absZ1) {
- float_raise(status, float_flag_inexact);
- }
- return absZ0;
-}
-
-#ifdef FLOAT16
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal half-precision floating-point value represented
-| by the denormalized significand `aSig'. The normalized exponent and
-| significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloat16Subnormal(Bit16u aSig, Bit16s *zExpPtr, Bit16u *zSigPtr)
-{
- int shiftCount = countLeadingZeros16(aSig) - 5;
- *zSigPtr = aSig<> 4;
- zSigRound &= ~(((roundBits ^ 0x10) == 0) & roundNearestEven);
- if (zSigRound == 0) zExp = 0;
- return packFloat16(zSign, zExp, zSigRound);
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal single-precision floating-point value represented
-| by the denormalized significand `aSig'. The normalized exponent and
-| significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloat32Subnormal(Bit32u aSig, Bit16s *zExpPtr, Bit32u *zSigPtr)
-{
- int shiftCount = countLeadingZeros32(aSig) - 8;
- *zSigPtr = aSig<> 7;
- zSigRound &= ~(((roundBits ^ 0x40) == 0) & roundNearestEven);
- if (zSigRound == 0) zExp = 0;
- if (roundBits) {
- float_raise(status, float_flag_inexact);
- if ((zSigRound << 7) > zSig) set_float_rounding_up(status);
- }
- return packFloat32(zSign, zExp, zSigRound);
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper single-precision floating-
-| point value corresponding to the abstract input. This routine is just like
-| `roundAndPackFloat32' except that `zSig' does not have to be normalized.
-| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
-| floating-point exponent.
-*----------------------------------------------------------------------------*/
-
-float32 normalizeRoundAndPackFloat32(int zSign, Bit16s zExp, Bit32u zSig, struct float_status_t *status)
-{
- int shiftCount = countLeadingZeros32(zSig) - 1;
- return roundAndPackFloat32(zSign, zExp - shiftCount, zSig<>10;
- zSigRound &= ~(((roundBits ^ 0x200) == 0) & roundNearestEven);
- if (zSigRound == 0) zExp = 0;
- if (roundBits) {
- float_raise(status, float_flag_inexact);
- if ((zSigRound << 10) > zSig) set_float_rounding_up(status);
- }
- return packFloat64(zSign, zExp, zSigRound);
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper double-precision floating-
-| point value corresponding to the abstract input. This routine is just like
-| `roundAndPackFloat64' except that `zSig' does not have to be normalized.
-| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
-| floating-point exponent.
-*----------------------------------------------------------------------------*/
-
-float64 normalizeRoundAndPackFloat64(int zSign, Bit16s zExp, Bit64u zSig, struct float_status_t *status)
-{
- int shiftCount = countLeadingZeros64(zSig) - 1;
- return roundAndPackFloat64(zSign, zExp - shiftCount, zSig< zSigExact) set_float_rounding_up(status);
- }
- return packFloatx80(zSign, zExp, zSig0);
- }
- }
- if (roundBits) float_raise(status, float_flag_inexact);
- zSigExact = zSig0;
- zSig0 += roundIncrement;
- if (zSig0 < roundIncrement) {
- // Basically scale by shifting right and keep overflow
- ++zExp;
- zSig0 = BX_CONST64(0x8000000000000000);
- zSigExact >>= 1; // must scale also, or else later tests will fail
- }
- roundIncrement = roundMask + 1;
- if (roundNearestEven && (roundBits<<1 == roundIncrement))
- roundMask |= roundIncrement;
- zSig0 &= ~roundMask;
- if (zSig0 > zSigExact) set_float_rounding_up(status);
- if (zSig0 == 0) zExp = 0;
- return packFloatx80(zSign, zExp, zSig0);
- precision80:
- increment = ((Bit64s) zSig1 < 0);
- if (! roundNearestEven) {
- if (roundingMode == float_round_to_zero) increment = 0;
- else {
- if (zSign) {
- increment = (roundingMode == float_round_down) && zSig1;
- }
- else {
- increment = (roundingMode == float_round_up) && zSig1;
- }
- }
- }
- if (0x7FFD <= (Bit32u) (zExp - 1)) {
- if ((0x7FFE < zExp)
- || ((zExp == 0x7FFE)
- && (zSig0 == BX_CONST64(0xFFFFFFFFFFFFFFFF))
- && increment))
- {
- roundMask = 0;
- overflow:
- float_raise(status, float_flag_overflow | float_flag_inexact);
- if ((roundingMode == float_round_to_zero)
- || (zSign && (roundingMode == float_round_up))
- || (! zSign && (roundingMode == float_round_down)))
- {
- return packFloatx80(zSign, 0x7FFE, ~roundMask);
- }
- set_float_rounding_up(status);
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (zExp <= 0) {
- int isTiny = (zExp < 0) || (! increment)
- || (zSig0 < BX_CONST64(0xFFFFFFFFFFFFFFFF));
- shift64ExtraRightJamming(zSig0, zSig1, 1 - zExp, &zSig0, &zSig1);
- zExp = 0;
- if (isTiny) {
- if (zSig1 || (zSig0 && !float_exception_masked(status, float_flag_underflow)))
- float_raise(status, float_flag_underflow);
- }
- if (zSig1) float_raise(status, float_flag_inexact);
- if (roundNearestEven) increment = ((Bit64s) zSig1 < 0);
- else {
- if (zSign) {
- increment = (roundingMode == float_round_down) && zSig1;
- } else {
- increment = (roundingMode == float_round_up) && zSig1;
- }
- }
- if (increment) {
- zSigExact = zSig0++;
- zSig0 &= ~(((Bit64u) (zSig1<<1) == 0) & roundNearestEven);
- if (zSig0 > zSigExact) set_float_rounding_up(status);
- if ((Bit64s) zSig0 < 0) zExp = 1;
- }
- return packFloatx80(zSign, zExp, zSig0);
- }
- }
- if (zSig1) float_raise(status, float_flag_inexact);
- if (increment) {
- zSigExact = zSig0++;
- if (zSig0 == 0) {
- zExp++;
- zSig0 = BX_CONST64(0x8000000000000000);
- zSigExact >>= 1; // must scale also, or else later tests will fail
- }
- else {
- zSig0 &= ~(((Bit64u) (zSig1<<1) == 0) & roundNearestEven);
- }
- if (zSig0 > zSigExact) set_float_rounding_up(status);
- }
- else {
- if (zSig0 == 0) zExp = 0;
- }
- return packFloatx80(zSign, zExp, zSig0);
-}
-
-floatx80 roundAndPackFloatx80(int roundingPrecision,
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status)
-{
- struct float_status_t *round_status = status;
- floatx80 result = SoftFloatRoundAndPackFloatx80(roundingPrecision, zSign, zExp, zSig0, zSig1, status);
-
- // bias unmasked undeflow
- if (status->float_exception_flags & ~status->float_exception_masks & float_flag_underflow) {
- float_raise(round_status, float_flag_underflow);
- return SoftFloatRoundAndPackFloatx80(roundingPrecision, zSign, zExp + 0x6000, zSig0, zSig1, status = round_status);
- }
-
- // bias unmasked overflow
- if (status->float_exception_flags & ~status->float_exception_masks & float_flag_overflow) {
- float_raise(round_status, float_flag_overflow);
- return SoftFloatRoundAndPackFloatx80(roundingPrecision, zSign, zExp - 0x6000, zSig0, zSig1, status = round_status);
- }
-
- return result;
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent
-| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
-| and returns the proper extended double-precision floating-point value
-| corresponding to the abstract input. This routine is just like
-| `roundAndPackFloatx80' except that the input significand does not have to be
-| normalized.
-*----------------------------------------------------------------------------*/
-
-floatx80 normalizeRoundAndPackFloatx80(int roundingPrecision,
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status)
-{
- if (zSig0 == 0) {
- zSig0 = zSig1;
- zSig1 = 0;
- zExp -= 64;
- }
- int shiftCount = countLeadingZeros64(zSig0);
- shortShift128Left(zSig0, zSig1, shiftCount, &zSig0, &zSig1);
- zExp -= shiftCount;
- return
- roundAndPackFloatx80(roundingPrecision, zSign, zExp, zSig0, zSig1, status);
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal quadruple-precision floating-point value
-| represented by the denormalized significand formed by the concatenation of
-| `aSig0' and `aSig1'. The normalized exponent is stored at the location
-| pointed to by `zExpPtr'. The most significant 49 bits of the normalized
-| significand are stored at the location pointed to by `zSig0Ptr', and the
-| least significant 64 bits of the normalized significand are stored at the
-| location pointed to by `zSig1Ptr'.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloat128Subnormal(
- Bit64u aSig0, Bit64u aSig1, Bit32s *zExpPtr, Bit64u *zSig0Ptr, Bit64u *zSig1Ptr)
-{
- int shiftCount;
-
- if (aSig0 == 0) {
- shiftCount = countLeadingZeros64(aSig1) - 15;
- if (shiftCount < 0) {
- *zSig0Ptr = aSig1 >>(-shiftCount);
- *zSig1Ptr = aSig1 << (shiftCount & 63);
- }
- else {
- *zSig0Ptr = aSig1 << shiftCount;
- *zSig1Ptr = 0;
- }
- *zExpPtr = - shiftCount - 63;
- }
- else {
- shiftCount = countLeadingZeros64(aSig0) - 15;
- shortShift128Left(aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr);
- *zExpPtr = 1 - shiftCount;
- }
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and extended significand formed by the concatenation of `zSig0', `zSig1',
-| and `zSig2', and returns the proper quadruple-precision floating-point value
-| corresponding to the abstract input. Ordinarily, the abstract value is
-| simply rounded and packed into the quadruple-precision format, with the
-| inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal quadruple-
-| precision floating-point number.
-| The input significand must be normalized or smaller. If the input
-| significand is not normalized, `zExp' must be 0; in that case, the result
-| returned is a subnormal number, and it must not require rounding. In the
-| usual case that the input significand is normalized, `zExp' must be 1 less
-| than the ``true'' floating-point exponent. The handling of underflow and
-| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 roundAndPackFloat128(
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, Bit64u zSig2, struct float_status_t *status)
-{
- int increment = ((Bit64s) zSig2 < 0);
- if (0x7FFD <= (Bit32u) zExp) {
- if ((0x7FFD < zExp)
- || ((zExp == 0x7FFD)
- && eq128(BX_CONST64(0x0001FFFFFFFFFFFF),
- BX_CONST64(0xFFFFFFFFFFFFFFFF), zSig0, zSig1)
- && increment))
- {
- float_raise(status, float_flag_overflow | float_flag_inexact);
- return packFloat128Four(zSign, 0x7FFF, 0, 0);
- }
- if (zExp < 0) {
- int isTiny = (zExp < -1)
- || ! increment
- || lt128(zSig0, zSig1,
- BX_CONST64(0x0001FFFFFFFFFFFF),
- BX_CONST64(0xFFFFFFFFFFFFFFFF));
- shift128ExtraRightJamming(
- zSig0, zSig1, zSig2, -zExp, &zSig0, &zSig1, &zSig2);
- zExp = 0;
- if (isTiny && zSig2) float_raise(status, float_flag_underflow);
- increment = ((Bit64s) zSig2 < 0);
- }
- }
- if (zSig2) float_raise(status, float_flag_inexact);
- if (increment) {
- add128(zSig0, zSig1, 0, 1, &zSig0, &zSig1);
- zSig1 &= ~((zSig2 + zSig2 == 0) & 1);
- }
- else {
- if ((zSig0 | zSig1) == 0) zExp = 0;
- }
- return packFloat128Four(zSign, zExp, zSig0, zSig1);
-}
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand formed by the concatenation of `zSig0' and `zSig1', and
-| returns the proper quadruple-precision floating-point value corresponding
-| to the abstract input. This routine is just like `roundAndPackFloat128'
-| except that the input significand has fewer bits and does not have to be
-| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating-
-| point exponent.
-*----------------------------------------------------------------------------*/
-
-float128 normalizeRoundAndPackFloat128(
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status)
-{
- Bit64u zSig2;
-
- if (zSig0 == 0) {
- zSig0 = zSig1;
- zSig1 = 0;
- zExp -= 64;
- }
- int shiftCount = countLeadingZeros64(zSig0) - 15;
- if (0 <= shiftCount) {
- zSig2 = 0;
- shortShift128Left(zSig0, zSig1, shiftCount, &zSig0, &zSig1);
- }
- else {
- shift128ExtraRightJamming(
- zSig0, zSig1, 0, -shiftCount, &zSig0, &zSig1, &zSig2);
- }
- zExp -= shiftCount;
- return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status);
-}
-
-#endif
diff --git a/src/cpu/softfloat/softfloat-round-pack.h b/src/cpu/softfloat/softfloat-round-pack.h
deleted file mode 100644
index 1422aaea6..000000000
--- a/src/cpu/softfloat/softfloat-round-pack.h
+++ /dev/null
@@ -1,309 +0,0 @@
-/*============================================================================
-This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#ifndef _SOFTFLOAT_ROUND_PACK_H_
-#define _SOFTFLOAT_ROUND_PACK_H_
-
-#include "softfloat.h"
-
-/*----------------------------------------------------------------------------
-| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
-| and 7, and returns the properly rounded 32-bit integer corresponding to the
-| input. If `zSign' is 1, the input is negated before being converted to an
-| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input
-| is simply rounded to an integer, with the inexact exception raised if the
-| input cannot be represented exactly as an integer. However, if the fixed-
-| point input is too large, the invalid exception is raised and the integer
-| indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32s roundAndPackInt32(int zSign, Bit64u absZ, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
-| `absZ1', with binary point between bits 63 and 64 (between the input words),
-| and returns the properly rounded 64-bit integer corresponding to the input.
-| If `zSign' is 1, the input is negated before being converted to an integer.
-| Ordinarily, the fixed-point input is simply rounded to an integer, with
-| the inexact exception raised if the input cannot be represented exactly as
-| an integer. However, if the fixed-point input is too large, the invalid
-| exception is raised and the integer indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64s roundAndPackInt64(int zSign, Bit64u absZ0, Bit64u absZ1, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
-| `absZ1', with binary point between bits 63 and 64 (between the input words),
-| and returns the properly rounded 64-bit unsigned integer corresponding to the
-| input. Ordinarily, the fixed-point input is simply rounded to an integer,
-| with the inexact exception raised if the input cannot be represented exactly
-| as an integer. However, if the fixed-point input is too large, the invalid
-| exception is raised and the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64u roundAndPackUint64(int zSign, Bit64u absZ0, Bit64u absZ1, struct float_status_t *status);
-
-#ifdef FLOAT16
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal half-precision floating-point value represented
-| by the denormalized significand `aSig'. The normalized exponent and
-| significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloat16Subnormal(Bit16u aSig, Bit16s *zExpPtr, Bit16u *zSigPtr);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper half-precision floating-
-| point value corresponding to the abstract input. Ordinarily, the abstract
-| value is simply rounded and packed into the half-precision format, with
-| the inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal single-
-| precision floating-point number.
-| The input significand `zSig' has its binary point between bits 14
-| and 13, which is 4 bits to the left of the usual location. This shifted
-| significand must be normalized or smaller. If `zSig' is not normalized,
-| `zExp' must be 0; in that case, the result returned is a subnormal number,
-| and it must not require rounding. In the usual case that `zSig' is
-| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
-| The handling of underflow and overflow follows the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float16 roundAndPackFloat16(int zSign, Bit16s zExp, Bit16u zSig, struct float_status_t *status);
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal single-precision floating-point value represented
-| by the denormalized significand `aSig'. The normalized exponent and
-| significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloat32Subnormal(Bit32u aSig, Bit16s *zExpPtr, Bit32u *zSigPtr);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper single-precision floating-
-| point value corresponding to the abstract input. Ordinarily, the abstract
-| value is simply rounded and packed into the single-precision format, with
-| the inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal single-
-| precision floating-point number.
-| The input significand `zSig' has its binary point between bits 30
-| and 29, which is 7 bits to the left of the usual location. This shifted
-| significand must be normalized or smaller. If `zSig' is not normalized,
-| `zExp' must be 0; in that case, the result returned is a subnormal number,
-| and it must not require rounding. In the usual case that `zSig' is
-| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
-| The handling of underflow and overflow follows the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 roundAndPackFloat32(int zSign, Bit16s zExp, Bit32u zSig, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper single-precision floating-
-| point value corresponding to the abstract input. This routine is just like
-| `roundAndPackFloat32' except that `zSig' does not have to be normalized.
-| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
-| floating-point exponent.
-*----------------------------------------------------------------------------*/
-
-float32 normalizeRoundAndPackFloat32(int zSign, Bit16s zExp, Bit32u zSig, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal double-precision floating-point value represented
-| by the denormalized significand `aSig'. The normalized exponent and
-| significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloat64Subnormal(Bit64u aSig, Bit16s *zExpPtr, Bit64u *zSigPtr);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper double-precision floating-
-| point value corresponding to the abstract input. Ordinarily, the abstract
-| value is simply rounded and packed into the double-precision format, with
-| the inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded
-| to a subnormal number, and the underflow and inexact exceptions are raised
-| if the abstract input cannot be represented exactly as a subnormal double-
-| precision floating-point number.
-| The input significand `zSig' has its binary point between bits 62
-| and 61, which is 10 bits to the left of the usual location. This shifted
-| significand must be normalized or smaller. If `zSig' is not normalized,
-| `zExp' must be 0; in that case, the result returned is a subnormal number,
-| and it must not require rounding. In the usual case that `zSig' is
-| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
-| The handling of underflow and overflow follows the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 roundAndPackFloat64(int zSign, Bit16s zExp, Bit64u zSig, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand `zSig', and returns the proper double-precision floating-
-| point value corresponding to the abstract input. This routine is just like
-| `roundAndPackFloat64' except that `zSig' does not have to be normalized.
-| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
-| floating-point exponent.
-*----------------------------------------------------------------------------*/
-
-float64 normalizeRoundAndPackFloat64(int zSign, Bit16s zExp, Bit64u zSig, struct float_status_t *status);
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal extended double-precision floating-point value
-| represented by the denormalized significand `aSig'. The normalized exponent
-| and significand are stored at the locations pointed to by `zExpPtr' and
-| `zSigPtr', respectively.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloatx80Subnormal(Bit64u aSig, Bit32s *zExpPtr, Bit64u *zSigPtr);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and extended significand formed by the concatenation of `zSig0' and `zSig1',
-| and returns the proper extended double-precision floating-point value
-| corresponding to the abstract input. Ordinarily, the abstract value is
-| rounded and packed into the extended double-precision format, with the
-| inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal extended
-| double-precision floating-point number.
-| If `roundingPrecision' is 32 or 64, the result is rounded to the same
-| number of bits as single or double precision, respectively. Otherwise, the
-| result is rounded to the full precision of the extended double-precision
-| format.
-| The input significand must be normalized or smaller. If the input
-| significand is not normalized, `zExp' must be 0; in that case, the result
-| returned is a subnormal number, and it must not require rounding. The
-| handling of underflow and overflow follows the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 roundAndPackFloatx80(int roundingPrecision,
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent
-| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
-| and returns the proper extended double-precision floating-point value
-| corresponding to the abstract input. This routine is just like
-| `roundAndPackFloatx80' except that the input significand does not have to be
-| normalized.
-*----------------------------------------------------------------------------*/
-
-floatx80 normalizeRoundAndPackFloatx80(int roundingPrecision,
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status);
-
-#endif // FLOATX80
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Normalizes the subnormal quadruple-precision floating-point value
-| represented by the denormalized significand formed by the concatenation of
-| `aSig0' and `aSig1'. The normalized exponent is stored at the location
-| pointed to by `zExpPtr'. The most significant 49 bits of the normalized
-| significand are stored at the location pointed to by `zSig0Ptr', and the
-| least significant 64 bits of the normalized significand are stored at the
-| location pointed to by `zSig1Ptr'.
-*----------------------------------------------------------------------------*/
-
-void normalizeFloat128Subnormal(
- Bit64u aSig0, Bit64u aSig1, Bit32s *zExpPtr, Bit64u *zSig0Ptr, Bit64u *zSig1Ptr);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and extended significand formed by the concatenation of `zSig0', `zSig1',
-| and `zSig2', and returns the proper quadruple-precision floating-point value
-| corresponding to the abstract input. Ordinarily, the abstract value is
-| simply rounded and packed into the quadruple-precision format, with the
-| inexact exception raised if the abstract input cannot be represented
-| exactly. However, if the abstract value is too large, the overflow and
-| inexact exceptions are raised and an infinity or maximal finite value is
-| returned. If the abstract value is too small, the input value is rounded to
-| a subnormal number, and the underflow and inexact exceptions are raised if
-| the abstract input cannot be represented exactly as a subnormal quadruple-
-| precision floating-point number.
-| The input significand must be normalized or smaller. If the input
-| significand is not normalized, `zExp' must be 0; in that case, the result
-| returned is a subnormal number, and it must not require rounding. In the
-| usual case that the input significand is normalized, `zExp' must be 1 less
-| than the ``true'' floating-point exponent. The handling of underflow and
-| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 roundAndPackFloat128(
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, Bit64u zSig2, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-| and significand formed by the concatenation of `zSig0' and `zSig1', and
-| returns the proper quadruple-precision floating-point value corresponding
-| to the abstract input. This routine is just like `roundAndPackFloat128'
-| except that the input significand has fewer bits and does not have to be
-| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating-
-| point exponent.
-*----------------------------------------------------------------------------*/
-
-float128 normalizeRoundAndPackFloat128(
- int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, struct float_status_t *status);
-
-#endif // FLOAT128
-
-#endif
diff --git a/src/cpu/softfloat/softfloat-specialize.cc b/src/cpu/softfloat/softfloat-specialize.cc
deleted file mode 100644
index bf0d11144..000000000
--- a/src/cpu/softfloat/softfloat-specialize.cc
+++ /dev/null
@@ -1,187 +0,0 @@
-/*============================================================================
-This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-#define FLOAT128
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#include "softfloat.h"
-#include "softfloat-specialize.h"
-
-/*----------------------------------------------------------------------------
-| Takes two single-precision floating-point values `a' and `b', one of which
-| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
-| signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-float32 propagateFloat32NaN(float32 a, float32 b, struct float_status_t *status)
-{
- int aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
-
- aIsNaN = float32_is_nan(a);
- aIsSignalingNaN = float32_is_signaling_nan(a);
- bIsNaN = float32_is_nan(b);
- bIsSignalingNaN = float32_is_signaling_nan(b);
- a |= 0x00400000;
- b |= 0x00400000;
- if (aIsSignalingNaN | bIsSignalingNaN) float_raise(status, float_flag_invalid);
- if (get_float_nan_handling_mode(status) == float_larger_significand_nan) {
- if (aIsSignalingNaN) {
- if (bIsSignalingNaN) goto returnLargerSignificand;
- return bIsNaN ? b : a;
- }
- else if (aIsNaN) {
- if (bIsSignalingNaN | ! bIsNaN) return a;
- returnLargerSignificand:
- if ((Bit32u) (a<<1) < (Bit32u) (b<<1)) return b;
- if ((Bit32u) (b<<1) < (Bit32u) (a<<1)) return a;
- return (a < b) ? a : b;
- }
- else {
- return b;
- }
- } else {
- return (aIsSignalingNaN | aIsNaN) ? a : b;
- }
-}
-
-/*----------------------------------------------------------------------------
-| Takes two double-precision floating-point values `a' and `b', one of which
-| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
-| signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-float64 propagateFloat64NaN(float64 a, float64 b, struct float_status_t *status)
-{
- int aIsNaN = float64_is_nan(a);
- int aIsSignalingNaN = float64_is_signaling_nan(a);
- int bIsNaN = float64_is_nan(b);
- int bIsSignalingNaN = float64_is_signaling_nan(b);
- a |= BX_CONST64(0x0008000000000000);
- b |= BX_CONST64(0x0008000000000000);
- if (aIsSignalingNaN | bIsSignalingNaN) float_raise(status, float_flag_invalid);
- if (get_float_nan_handling_mode(status) == float_larger_significand_nan) {
- if (aIsSignalingNaN) {
- if (bIsSignalingNaN) goto returnLargerSignificand;
- return bIsNaN ? b : a;
- }
- else if (aIsNaN) {
- if (bIsSignalingNaN | ! bIsNaN) return a;
- returnLargerSignificand:
- if ((Bit64u) (a<<1) < (Bit64u) (b<<1)) return b;
- if ((Bit64u) (b<<1) < (Bit64u) (a<<1)) return a;
- return (a < b) ? a : b;
- }
- else {
- return b;
- }
- } else {
- return (aIsSignalingNaN | aIsNaN) ? a : b;
- }
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Takes two extended double-precision floating-point values `a' and `b', one
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
-| `b' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, struct float_status_t *status)
-{
- int aIsNaN = floatx80_is_nan(a);
- int aIsSignalingNaN = floatx80_is_signaling_nan(a);
- int bIsNaN = floatx80_is_nan(b);
- int bIsSignalingNaN = floatx80_is_signaling_nan(b);
- a.fraction |= BX_CONST64(0xC000000000000000);
- b.fraction |= BX_CONST64(0xC000000000000000);
- if (aIsSignalingNaN | bIsSignalingNaN) float_raise(status, float_flag_invalid);
- if (aIsSignalingNaN) {
- if (bIsSignalingNaN) goto returnLargerSignificand;
- return bIsNaN ? b : a;
- }
- else if (aIsNaN) {
- if (bIsSignalingNaN | ! bIsNaN) return a;
- returnLargerSignificand:
- if (a.fraction < b.fraction) return b;
- if (b.fraction < a.fraction) return a;
- return (a.exp < b.exp) ? a : b;
- }
- else {
- return b;
- }
-}
-
-#endif /* FLOATX80 */
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Takes two quadruple-precision floating-point values `a' and `b', one of
-| which is a NaN, and returns the appropriate NaN result. If either `a' or
-| `b' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-float128 propagateFloat128NaN(float128 a, float128 b, struct float_status_t *status)
-{
- int aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
- aIsNaN = float128_is_nan(a);
- aIsSignalingNaN = float128_is_signaling_nan(a);
- bIsNaN = float128_is_nan(b);
- bIsSignalingNaN = float128_is_signaling_nan(b);
- a.hi |= BX_CONST64(0x0000800000000000);
- b.hi |= BX_CONST64(0x0000800000000000);
- if (aIsSignalingNaN | bIsSignalingNaN) float_raise(status, float_flag_invalid);
- if (aIsSignalingNaN) {
- if (bIsSignalingNaN) goto returnLargerSignificand;
- return bIsNaN ? b : a;
- }
- else if (aIsNaN) {
- if (bIsSignalingNaN | !bIsNaN) return a;
- returnLargerSignificand:
- if (lt128(a.hi<<1, a.lo, b.hi<<1, b.lo)) return b;
- if (lt128(b.hi<<1, b.lo, a.hi<<1, a.lo)) return a;
- return (a.hi < b.hi) ? a : b;
- }
- else {
- return b;
- }
-}
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated quadruple-precision NaN.
-*----------------------------------------------------------------------------*/
-const float128 float128_default_nan =
- packFloat128(float128_default_nan_hi, float128_default_nan_lo);
-
-#endif /* FLOAT128 */
diff --git a/src/cpu/softfloat/softfloat-specialize.h b/src/cpu/softfloat/softfloat-specialize.h
deleted file mode 100644
index 302ce53e4..000000000
--- a/src/cpu/softfloat/softfloat-specialize.h
+++ /dev/null
@@ -1,789 +0,0 @@
-/*============================================================================
-This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-#ifndef _SOFTFLOAT_SPECIALIZE_H_
-#define _SOFTFLOAT_SPECIALIZE_H_
-
-#include "softfloat.h"
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#define int16_indefinite ((Bit16s)0x8000)
-#define int32_indefinite ((Bit32s)0x80000000)
-#define int64_indefinite BX_CONST64(0x8000000000000000)
-
-#define uint16_indefinite (0xffff)
-#define uint32_indefinite (0xffffffff)
-#define uint64_indefinite BX_CONST64(0xffffffffffffffff)
-
-/*----------------------------------------------------------------------------
-| Internal canonical NaN format.
-*----------------------------------------------------------------------------*/
-
-typedef struct {
- int sign;
- Bit64u hi, lo;
-} commonNaNT;
-
-#ifdef FLOAT16
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated half-precision NaN.
-*----------------------------------------------------------------------------*/
-extern const float16 float16_default_nan;
-
-#define float16_fraction extractFloat16Frac
-#define float16_exp extractFloat16Exp
-#define float16_sign extractFloat16Sign
-
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the half-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit16u extractFloat16Frac(float16 a)
-{
- return a & 0x3FF;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the half-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit16s extractFloat16Exp(float16 a)
-{
- return (a>>10) & 0x1F;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the half-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int extractFloat16Sign(float16 a)
-{
- return a>>15;
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
-| single-precision floating-point value, returning the result. After being
-| shifted into the proper positions, the three fields are simply added
-| together to form the result. This means that any integer portion of `zSig'
-| will be added into the exponent. Since a properly normalized significand
-| will have an integer portion equal to 1, the `zExp' input should be 1 less
-| than the desired result exponent whenever `zSig' is a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float16 packFloat16(int zSign, int zExp, Bit16u zSig)
-{
- return (((Bit16u) zSign)<<15) + (((Bit16u) zExp)<<10) + zSig;
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the half-precision floating-point value `a' is a NaN;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float16_is_nan(float16 a)
-{
- return (0xF800 < (Bit16u) (a<<1));
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the half-precision floating-point value `a' is a signaling
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float16_is_signaling_nan(float16 a)
-{
- return (((a>>9) & 0x3F) == 0x3E) && (a & 0x1FF);
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the half-precision floating-point value `a' is denormal;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float16_is_denormal(float16 a)
-{
- return (extractFloat16Exp(a) == 0) && (extractFloat16Frac(a) != 0);
-}
-
-/*----------------------------------------------------------------------------
-| Convert float16 denormals to zero.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float16 float16_denormal_to_zero(float16 a)
-{
- if (float16_is_denormal(a)) a &= 0x8000;
- return a;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the half-precision floating-point NaN
-| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE commonNaNT float16ToCommonNaN(float16 a, struct float_status_t *status)
-{
- commonNaNT z;
- if (float16_is_signaling_nan(a)) float_raise(status, float_flag_invalid);
- z.sign = a>>15;
- z.lo = 0;
- z.hi = ((Bit64u) a)<<54;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the half-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float16 commonNaNToFloat16(commonNaNT a)
-{
- return (((Bit16u) a.sign)<<15) | 0x7E00 | (Bit16u)(a.hi>>54);
-}
-
-#endif
-
-/*----------------------------------------------------------------------------
-| Commonly used single-precision floating point constants
-*----------------------------------------------------------------------------*/
-extern const float32 float32_negative_inf;
-extern const float32 float32_positive_inf;
-extern const float32 float32_negative_zero;
-extern const float32 float32_positive_zero;
-extern const float32 float32_negative_one;
-extern const float32 float32_positive_one;
-extern const float32 float32_max_float;
-extern const float32 float32_min_float;
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated single-precision NaN.
-*----------------------------------------------------------------------------*/
-extern const float32 float32_default_nan;
-
-#define float32_fraction extractFloat32Frac
-#define float32_exp extractFloat32Exp
-#define float32_sign extractFloat32Sign
-
-#define FLOAT32_EXP_BIAS 0x7F
-
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the single-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit32u extractFloat32Frac(float32 a)
-{
- return a & 0x007FFFFF;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the single-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit16s extractFloat32Exp(float32 a)
-{
- return (a>>23) & 0xFF;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the single-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int extractFloat32Sign(float32 a)
-{
- return a>>31;
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
-| single-precision floating-point value, returning the result. After being
-| shifted into the proper positions, the three fields are simply added
-| together to form the result. This means that any integer portion of `zSig'
-| will be added into the exponent. Since a properly normalized significand
-| will have an integer portion equal to 1, the `zExp' input should be 1 less
-| than the desired result exponent whenever `zSig' is a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float32 packFloat32(int zSign, Bit16s zExp, Bit32u zSig)
-{
- return (((Bit32u) zSign)<<31) + (((Bit32u) zExp)<<23) + zSig;
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is a NaN;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float32_is_nan(float32 a)
-{
- return (0xFF000000 < (Bit32u) (a<<1));
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is a signaling
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float32_is_signaling_nan(float32 a)
-{
- return (((a>>22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF);
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the single-precision floating-point value `a' is denormal;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float32_is_denormal(float32 a)
-{
- return (extractFloat32Exp(a) == 0) && (extractFloat32Frac(a) != 0);
-}
-
-/*----------------------------------------------------------------------------
-| Convert float32 denormals to zero.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float32 float32_denormal_to_zero(float32 a)
-{
- if (float32_is_denormal(a)) a &= 0x80000000;
- return a;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point NaN
-| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE commonNaNT float32ToCommonNaN(float32 a, struct float_status_t *status)
-{
- commonNaNT z;
- if (float32_is_signaling_nan(a)) float_raise(status, float_flag_invalid);
- z.sign = a>>31;
- z.lo = 0;
- z.hi = ((Bit64u) a)<<41;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the single-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float32 commonNaNToFloat32(commonNaNT a)
-{
- return (((Bit32u) a.sign)<<31) | 0x7FC00000 | (Bit32u)(a.hi>>41);
-}
-
-/*----------------------------------------------------------------------------
-| Takes two single-precision floating-point values `a' and `b', one of which
-| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
-| signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-float32 propagateFloat32NaN(float32 a, float32 b, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes single-precision floating-point NaN `a' and returns the appropriate
-| NaN result. If `a' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float32 propagateFloat32NaNOne(float32 a, struct float_status_t *status)
-{
- if (float32_is_signaling_nan(a))
- float_raise(status, float_flag_invalid);
-
- return a | 0x00400000;
-}
-
-/*----------------------------------------------------------------------------
-| Commonly used single-precision floating point constants
-*----------------------------------------------------------------------------*/
-extern const float64 float64_negative_inf;
-extern const float64 float64_positive_inf;
-extern const float64 float64_negative_zero;
-extern const float64 float64_positive_zero;
-extern const float64 float64_negative_one;
-extern const float64 float64_positive_one;
-extern const float64 float64_max_float;
-extern const float64 float64_min_float;
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated double-precision NaN.
-*----------------------------------------------------------------------------*/
-extern const float64 float64_default_nan;
-
-#define float64_fraction extractFloat64Frac
-#define float64_exp extractFloat64Exp
-#define float64_sign extractFloat64Sign
-
-#define FLOAT64_EXP_BIAS 0x3FF
-
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the double-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit64u extractFloat64Frac(float64 a)
-{
- return a & BX_CONST64(0x000FFFFFFFFFFFFF);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the double-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit16s extractFloat64Exp(float64 a)
-{
- return (Bit16s)(a>>52) & 0x7FF;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the double-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int extractFloat64Sign(float64 a)
-{
- return (int)(a>>63);
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
-| double-precision floating-point value, returning the result. After being
-| shifted into the proper positions, the three fields are simply added
-| together to form the result. This means that any integer portion of `zSig'
-| will be added into the exponent. Since a properly normalized significand
-| will have an integer portion equal to 1, the `zExp' input should be 1 less
-| than the desired result exponent whenever `zSig' is a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float64 packFloat64(int zSign, Bit16s zExp, Bit64u zSig)
-{
- return (((Bit64u) zSign)<<63) + (((Bit64u) zExp)<<52) + zSig;
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is a NaN;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float64_is_nan(float64 a)
-{
- return (BX_CONST64(0xFFE0000000000000) < (Bit64u) (a<<1));
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is a signaling
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float64_is_signaling_nan(float64 a)
-{
- return (((a>>51) & 0xFFF) == 0xFFE) && (a & BX_CONST64(0x0007FFFFFFFFFFFF));
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the double-precision floating-point value `a' is denormal;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float64_is_denormal(float64 a)
-{
- return (extractFloat64Exp(a) == 0) && (extractFloat64Frac(a) != 0);
-}
-
-/*----------------------------------------------------------------------------
-| Convert float64 denormals to zero.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float64 float64_denormal_to_zero(float64 a)
-{
- if (float64_is_denormal(a)) a &= ((Bit64u)(1) << 63);
- return a;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point NaN
-| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE commonNaNT float64ToCommonNaN(float64 a, struct float_status_t *status)
-{
- commonNaNT z;
- if (float64_is_signaling_nan(a)) float_raise(status, float_flag_invalid);
- z.sign = (int)(a>>63);
- z.lo = 0;
- z.hi = a<<12;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the double-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float64 commonNaNToFloat64(commonNaNT a)
-{
- return (((Bit64u) a.sign)<<63) | BX_CONST64(0x7FF8000000000000) | (a.hi>>12);
-}
-
-/*----------------------------------------------------------------------------
-| Takes two double-precision floating-point values `a' and `b', one of which
-| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
-| signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-float64 propagateFloat64NaN(float64 a, float64 b, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes double-precision floating-point NaN `a' and returns the appropriate
-| NaN result. If `a' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float64 propagateFloat64NaNOne(float64 a, struct float_status_t *status)
-{
- if (float64_is_signaling_nan(a))
- float_raise(status, float_flag_invalid);
-
- return a | BX_CONST64(0x0008000000000000);
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN. The
-| `high' and `low' values hold the most- and least-significant bits,
-| respectively.
-*----------------------------------------------------------------------------*/
-#define floatx80_default_nan_exp 0xFFFF
-#define floatx80_default_nan_fraction BX_CONST64(0xC000000000000000)
-
-#define floatx80_fraction extractFloatx80Frac
-#define floatx80_exp extractFloatx80Exp
-#define floatx80_sign extractFloatx80Sign
-
-#define FLOATX80_EXP_BIAS 0x3FFF
-
-/*----------------------------------------------------------------------------
-| Returns the fraction bits of the extended double-precision floating-point
-| value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit64u extractFloatx80Frac(floatx80 a)
-{
- return a.fraction;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the extended double-precision floating-point
-| value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit32s extractFloatx80Exp(floatx80 a)
-{
- return a.exp & 0x7FFF;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the extended double-precision floating-point value
-| `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int extractFloatx80Sign(floatx80 a)
-{
- return a.exp>>15;
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
-| extended double-precision floating-point value, returning the result.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE floatx80 packFloatx80(int zSign, Bit32s zExp, Bit64u zSig)
-{
- floatx80 z;
- z.fraction = zSig;
- z.exp = (zSign << 15) + zExp;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is a
-| NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int floatx80_is_nan(floatx80 a)
-{
- // return ((a.exp & 0x7FFF) == 0x7FFF) && (Bit64s) (a.fraction<<1);
- return ((a.exp & 0x7FFF) == 0x7FFF) && (((Bit64s) (a.fraction<<1)) != 0);
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is a
-| signaling NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int floatx80_is_signaling_nan(floatx80 a)
-{
- Bit64u aLow = a.fraction & ~BX_CONST64(0x4000000000000000);
- return ((a.exp & 0x7FFF) == 0x7FFF) &&
- ((Bit64u) (aLow<<1)) && (a.fraction == aLow);
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is an
-| unsupported; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int floatx80_is_unsupported(floatx80 a)
-{
- return ((a.exp & 0x7FFF) && !(a.fraction & BX_CONST64(0x8000000000000000)));
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
-| invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE commonNaNT floatx80ToCommonNaN(floatx80 a, struct float_status_t *status)
-{
- commonNaNT z;
- if (floatx80_is_signaling_nan(a)) float_raise(status, float_flag_invalid);
- z.sign = a.exp >> 15;
- z.lo = 0;
- z.hi = a.fraction << 1;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the extended
-| double-precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE floatx80 commonNaNToFloatx80(commonNaNT a)
-{
- floatx80 z;
- z.fraction = BX_CONST64(0xC000000000000000) | (a.hi>>1);
- z.exp = (((Bit16u) a.sign)<<15) | 0x7FFF;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Takes two extended double-precision floating-point values `a' and `b', one
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
-| `b' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Takes extended double-precision floating-point NaN `a' and returns the
-| appropriate NaN result. If `a' is a signaling NaN, the invalid exception
-| is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE floatx80 propagateFloatx80NaNOne(floatx80 a, struct float_status_t *status)
-{
- if (floatx80_is_signaling_nan(a))
- float_raise(status, float_flag_invalid);
-
- a.fraction |= BX_CONST64(0xC000000000000000);
-
- return a;
-}
-
-#endif /* FLOATX80 */
-
-#ifdef FLOAT128
-
-#include "softfloat-macros.h"
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated quadruple-precision NaN. The `high' and
-| `low' values hold the most- and least-significant bits, respectively.
-*----------------------------------------------------------------------------*/
-#define float128_default_nan_hi BX_CONST64(0xFFFF800000000000)
-#define float128_default_nan_lo BX_CONST64(0x0000000000000000)
-
-#define float128_exp extractFloat128Exp
-
-/*----------------------------------------------------------------------------
-| Returns the least-significant 64 fraction bits of the quadruple-precision
-| floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit64u extractFloat128Frac1(float128 a)
-{
- return a.lo;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the most-significant 48 fraction bits of the quadruple-precision
-| floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit64u extractFloat128Frac0(float128 a)
-{
- return a.hi & BX_CONST64(0x0000FFFFFFFFFFFF);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the exponent bits of the quadruple-precision floating-point value
-| `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE Bit32s extractFloat128Exp(float128 a)
-{
- return ((Bit32s)(a.hi>>48)) & 0x7FFF;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the sign bit of the quadruple-precision floating-point value `a'.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int extractFloat128Sign(float128 a)
-{
- return (int)(a.hi >> 63);
-}
-
-/*----------------------------------------------------------------------------
-| Packs the sign `zSign', the exponent `zExp', and the significand formed
-| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
-| floating-point value, returning the result. After being shifted into the
-| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply
-| added together to form the most significant 32 bits of the result. This
-| means that any integer portion of `zSig0' will be added into the exponent.
-| Since a properly normalized significand will have an integer portion equal
-| to 1, the `zExp' input should be 1 less than the desired result exponent
-| whenever `zSig0' and `zSig1' concatenated form a complete, normalized
-| significand.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float128 packFloat128Four(int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1)
-{
- float128 z;
- z.lo = zSig1;
- z.hi = (((Bit64u) zSign)<<63) + (((Bit64u) zExp)<<48) + zSig0;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Packs two 64-bit precision integers into into the quadruple-precision
-| floating-point value, returning the result.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float128 packFloat128(Bit64u zHi, Bit64u zLo)
-{
- float128 z;
- z.lo = zLo;
- z.hi = zHi;
- return z;
-}
-
-#ifdef _MSC_VER
-#define PACK_FLOAT_128(hi,lo) { lo, hi }
-#else
-#define PACK_FLOAT_128(hi,lo) packFloat128(BX_CONST64(hi),BX_CONST64(lo))
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float128_is_nan(float128 a)
-{
- return (BX_CONST64(0xFFFE000000000000) <= (Bit64u) (a.hi<<1))
- && (a.lo || (a.hi & BX_CONST64(0x0000FFFFFFFFFFFF)));
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the quadruple-precision floating-point value `a' is a
-| signaling NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float128_is_signaling_nan(float128 a)
-{
- return (((a.hi>>47) & 0xFFFF) == 0xFFFE)
- && (a.lo || (a.hi & BX_CONST64(0x00007FFFFFFFFFFF)));
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point NaN
-| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
-| exception is raised.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE commonNaNT float128ToCommonNaN(float128 a, struct float_status_t *status)
-{
- commonNaNT z;
- if (float128_is_signaling_nan(a)) float_raise(status, float_flag_invalid);
- z.sign = (int)(a.hi>>63);
- shortShift128Left(a.hi, a.lo, 16, &z.hi, &z.lo);
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the canonical NaN `a' to the quadruple-
-| precision floating-point format.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE float128 commonNaNToFloat128(commonNaNT a)
-{
- float128 z;
- shift128Right(a.hi, a.lo, 16, &z.hi, &z.lo);
- z.hi |= (((Bit64u) a.sign)<<63) | BX_CONST64(0x7FFF800000000000);
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Takes two quadruple-precision floating-point values `a' and `b', one of
-| which is a NaN, and returns the appropriate NaN result. If either `a' or
-| `b' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-float128 propagateFloat128NaN(float128 a, float128 b, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated quadruple-precision NaN.
-*----------------------------------------------------------------------------*/
-extern const float128 float128_default_nan;
-
-#endif /* FLOAT128 */
-
-#endif
diff --git a/src/cpu/softfloat/softfloat.cc b/src/cpu/softfloat/softfloat.cc
deleted file mode 100644
index 0802089b9..000000000
--- a/src/cpu/softfloat/softfloat.cc
+++ /dev/null
@@ -1,4012 +0,0 @@
-/*============================================================================
-This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-#define FLOAT128
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#include "softfloat.h"
-#include "softfloat-round-pack.h"
-
-/*----------------------------------------------------------------------------
-| Primitive arithmetic functions, including multi-word arithmetic, and
-| division and square root approximations. (Can be specialized to target
-| if desired).
-*----------------------------------------------------------------------------*/
-#define USE_estimateDiv128To64
-#define USE_estimateSqrt32
-#include "softfloat-macros.h"
-
-/*----------------------------------------------------------------------------
-| Functions and definitions to determine: (1) whether tininess for underflow
-| is detected before or after rounding by default, (2) what (if anything)
-| happens when exceptions are raised, (3) how signaling NaNs are distinguished
-| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
-| are propagated from function inputs to output. These details are target-
-| specific.
-*----------------------------------------------------------------------------*/
-#include "softfloat-specialize.h"
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit two's complement integer `a'
-| to the single-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-const unsigned float_all_exceptions_mask = 0x3f;
-
-float32 int32_to_float32(Bit32s a, struct float_status_t *status)
-{
- if (a == 0) return 0;
- if (a == (Bit32s) 0x80000000) return packFloat32(1, 0x9E, 0);
- int zSign = (a < 0);
- return normalizeRoundAndPackFloat32(zSign, 0x9C, zSign ? -a : a, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit two's complement integer `a'
-| to the double-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 int32_to_float64(Bit32s a)
-{
- if (a == 0) return 0;
- int zSign = (a < 0);
- Bit32u absA = zSign ? -a : a;
- int shiftCount = countLeadingZeros32(absA) + 21;
- Bit64u zSig = absA;
- return packFloat64(zSign, 0x432 - shiftCount, zSig<> 1, status);
- return normalizeRoundAndPackFloat32(0, 0x9C, a, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit unsigned integer `a' to the
-| double-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 uint32_to_float64(Bit32u a)
-{
- if (a == 0) return 0;
- int shiftCount = countLeadingZeros32(a) + 21;
- Bit64u zSig = a;
- return packFloat64(0, 0x432 - shiftCount, zSig<> 1, status);
- return normalizeRoundAndPackFloat64(0, 0x43C, a, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic - which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN or the
-| conversion overflows the integer indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32s float32_to_int32(float32 a, struct float_status_t *status)
-{
- Bit32u aSig = extractFloat32Frac(a);
- Bit16s aExp = extractFloat32Exp(a);
- int aSign = extractFloat32Sign(a);
- if ((aExp == 0xFF) && aSig) aSign = 0;
- if (aExp) aSig |= 0x00800000;
- else {
- if (get_denormals_are_zeros(status)) aSig = 0;
- }
- int shiftCount = 0xAF - aExp;
- Bit64u aSig64 = Bit64u(aSig) << 32;
- if (0 < shiftCount) aSig64 = shift64RightJamming(aSig64, shiftCount);
- return roundAndPackInt32(aSign, aSig64, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero.
-| If `a' is a NaN or the conversion overflows, the integer indefinite
-| value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32s float32_to_int32_round_to_zero(float32 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp;
- Bit32u aSig;
- Bit32s z;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
- int shiftCount = aExp - 0x9E;
- if (0 <= shiftCount) {
- if (a != 0xCF000000) {
- float_raise(status, float_flag_invalid);
- }
- return (Bit32s)(int32_indefinite);
- }
- else if (aExp <= 0x7E) {
- if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0;
- if (aExp | aSig) float_raise(status, float_flag_inexact);
- return 0;
- }
- aSig = (aSig | 0x800000)<<8;
- z = aSig>>(-shiftCount);
- if ((Bit32u) (aSig<<(shiftCount & 31))) {
- float_raise(status, float_flag_inexact);
- }
- if (aSign) z = -z;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 32-bit unsigned integer format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-point Arithmetic,
-| except that the conversion is always rounded toward zero. If `a' is a NaN
-| or conversion overflows, the largest positive integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32u float32_to_uint32_round_to_zero(float32 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp;
- Bit32u aSig;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
- int shiftCount = aExp - 0x9E;
-
- if (aExp <= 0x7E) {
- if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0;
- if (aExp | aSig) float_raise(status, float_flag_inexact);
- return 0;
- }
- else if (0 < shiftCount || aSign) {
- float_raise(status, float_flag_invalid);
- return uint32_indefinite;
- }
-
- aSig = (aSig | 0x800000)<<8;
- Bit32u z = aSig >> (-shiftCount);
- if (aSig << (shiftCount & 31)) {
- float_raise(status, float_flag_inexact);
- }
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 64-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic - which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN or the
-| conversion overflows, the integer indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64s float32_to_int64(float32 a, struct float_status_t *status)
-{
- Bit64u aSig64, aSigExtra;
-
- Bit32u aSig = extractFloat32Frac(a);
- Bit16s aExp = extractFloat32Exp(a);
- int aSign = extractFloat32Sign(a);
-
- int shiftCount = 0xBE - aExp;
- if (shiftCount < 0) {
- float_raise(status, float_flag_invalid);
- return (Bit64s)(int64_indefinite);
- }
- if (aExp) aSig |= 0x00800000;
- else {
- if (get_denormals_are_zeros(status)) aSig = 0;
- }
- aSig64 = aSig;
- aSig64 <<= 40;
- shift64ExtraRightJamming(aSig64, 0, shiftCount, &aSig64, &aSigExtra);
- return roundAndPackInt64(aSign, aSig64, aSigExtra, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 64-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero.
-| If `a' is a NaN or the conversion overflows, the integer indefinite
-| value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64s float32_to_int64_round_to_zero(float32 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp;
- Bit32u aSig;
- Bit64u aSig64;
- Bit64s z;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
- int shiftCount = aExp - 0xBE;
- if (0 <= shiftCount) {
- if (a != 0xDF000000) {
- float_raise(status, float_flag_invalid);
- }
- return (Bit64s)(int64_indefinite);
- }
- else if (aExp <= 0x7E) {
- if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0;
- if (aExp | aSig) float_raise(status, float_flag_inexact);
- return 0;
- }
- aSig64 = aSig | 0x00800000;
- aSig64 <<= 40;
- z = aSig64>>(-shiftCount);
- if ((Bit64u) (aSig64<<(shiftCount & 63))) {
- float_raise(status, float_flag_inexact);
- }
- if (aSign) z = -z;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 64-bit unsigned integer format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic,
-| except that the conversion is always rounded toward zero. If `a' is a NaN
-| or the conversion overflows, the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64u float32_to_uint64_round_to_zero(float32 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp;
- Bit32u aSig;
- Bit64u aSig64;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
- int shiftCount = aExp - 0xBE;
-
- if (aExp <= 0x7E) {
- if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0;
- if (aExp | aSig) float_raise(status, float_flag_inexact);
- return 0;
- }
- else if (0 < shiftCount || aSign) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
-
- aSig64 = aSig | 0x00800000;
- aSig64 <<= 40;
- Bit64u z = aSig64>>(-shiftCount);
- if ((Bit64u) (aSig64<<(shiftCount & 63))) {
- float_raise(status, float_flag_inexact);
- }
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 64-bit unsigned integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN or the conversion
-| overflows, the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64u float32_to_uint64(float32 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp, shiftCount;
- Bit32u aSig;
- Bit64u aSig64, aSigExtra;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- }
-
- if ((aSign) && (aExp > 0x7E)) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
-
- shiftCount = 0xBE - aExp;
- if (aExp) aSig |= 0x00800000;
-
- if (shiftCount < 0) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
-
- aSig64 = aSig;
- aSig64 <<= 40;
- shift64ExtraRightJamming(aSig64, 0, shiftCount, &aSig64, &aSigExtra);
- return roundAndPackUint64(aSign, aSig64, aSigExtra, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the 32-bit unsigned integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN or the conversion
-| overflows, the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32u float32_to_uint32(float32 a, struct float_status_t *status)
-{
- Bit64u val_64 = float32_to_uint64(a, status);
-
- if (val_64 > 0xffffffff) {
- status->float_exception_flags = float_flag_invalid; // throw away other flags
- return uint32_indefinite;
- }
-
- return (Bit32u) val_64;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the double-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float32_to_float64(float32 a, struct float_status_t *status)
-{
- Bit32u aSig = extractFloat32Frac(a);
- Bit16s aExp = extractFloat32Exp(a);
- int aSign = extractFloat32Sign(a);
-
- if (aExp == 0xFF) {
- if (aSig) return commonNaNToFloat64(float32ToCommonNaN(a, status));
- return packFloat64(aSign, 0x7FF, 0);
- }
- if (aExp == 0) {
- if (aSig == 0 || get_denormals_are_zeros(status))
- return packFloat64(aSign, 0, 0);
-
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(aSig, &aExp, &aSig);
- --aExp;
- }
- return packFloat64(aSign, aExp + 0x380, ((Bit64u) aSig)<<29);
-}
-
-/*----------------------------------------------------------------------------
-| Rounds the single-precision floating-point value `a' to an integer, and
-| returns the result as a single-precision floating-point value. The
-| operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_round_to_int(float32 a, Bit8u scale, struct float_status_t *status)
-{
- Bit32u lastBitMask, roundBitsMask;
- int roundingMode = get_float_rounding_mode(status);
- Bit16s aExp = extractFloat32Exp(a);
- scale &= 0xf;
-
- if ((aExp == 0xFF) && extractFloat32Frac(a)) {
- return propagateFloat32NaNOne(a, status);
- }
-
- aExp += scale; // scale the exponent
-
- if (0x96 <= aExp) {
- return a;
- }
-
- if (get_denormals_are_zeros(status)) {
- a = float32_denormal_to_zero(a);
- }
-
- if (aExp <= 0x7E) {
- if ((Bit32u) (a<<1) == 0) return a;
- float_raise(status, float_flag_inexact);
- int aSign = extractFloat32Sign(a);
- switch (roundingMode) {
- case float_round_nearest_even:
- if ((aExp == 0x7E) && extractFloat32Frac(a)) {
- return packFloat32(aSign, 0x7F - scale, 0);
- }
- break;
- case float_round_down:
- return aSign ? packFloat32(1, 0x7F - scale, 0) : float32_positive_zero;
- case float_round_up:
- return aSign ? float32_negative_zero : packFloat32(0, 0x7F - scale, 0);
- }
- return packFloat32(aSign, 0, 0);
- }
-
- lastBitMask = 1;
- lastBitMask <<= 0x96 - aExp;
- roundBitsMask = lastBitMask - 1;
- float32 z = a;
- if (roundingMode == float_round_nearest_even) {
- z += lastBitMask>>1;
- if ((z & roundBitsMask) == 0) z &= ~lastBitMask;
- }
- else if (roundingMode != float_round_to_zero) {
- if (extractFloat32Sign(z) ^ (roundingMode == float_round_up)) {
- z += roundBitsMask;
- }
- }
- z &= ~roundBitsMask;
- if (z != a) float_raise(status, float_flag_inexact);
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Extracts the fractional portion of single-precision floating-point value `a',
-| and returns the result as a single-precision floating-point value. The
-| fractional results are precise. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_frc(float32 a, struct float_status_t *status)
-{
- int roundingMode = get_float_rounding_mode(status);
-
- Bit16s aExp = extractFloat32Exp(a);
- Bit32u aSig = extractFloat32Frac(a);
- int aSign = extractFloat32Sign(a);
-
- if (aExp == 0xFF) {
- if (aSig) return propagateFloat32NaNOne(a, status);
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
-
- if (aExp >= 0x96) {
- return packFloat32(roundingMode == float_round_down, 0, 0);
- }
-
- if (aExp < 0x7F) {
- if (aExp == 0) {
- if (aSig == 0 || get_denormals_are_zeros(status))
- return packFloat32(roundingMode == float_round_down, 0, 0);
-
- float_raise(status, float_flag_denormal);
- if (! float_exception_masked(status, float_flag_underflow))
- float_raise(status, float_flag_underflow);
-
- if(get_flush_underflow_to_zero(status)) {
- float_raise(status, float_flag_underflow | float_flag_inexact);
- return packFloat32(aSign, 0, 0);
- }
- }
- return a;
- }
-
- Bit32u lastBitMask = 1 << (0x96 - aExp);
- Bit32u roundBitsMask = lastBitMask - 1;
-
- aSig &= roundBitsMask;
- aSig <<= 7;
- aExp--;
-
- if (aSig == 0)
- return packFloat32(roundingMode == float_round_down, 0, 0);
-
- return normalizeRoundAndPackFloat32(aSign, aExp, aSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Extracts the exponent portion of single-precision floating-point value 'a',
-| and returns the result as a single-precision floating-point value
-| representing unbiased integer exponent. The operation is performed according
-| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_getexp(float32 a, struct float_status_t *status)
-{
- Bit16s aExp = extractFloat32Exp(a);
- Bit32u aSig = extractFloat32Frac(a);
-
- if (aExp == 0xFF) {
- if (aSig) return propagateFloat32NaNOne(a, status);
- return float32_positive_inf;
- }
-
- if (aExp == 0) {
- if (aSig == 0 || get_denormals_are_zeros(status))
- return float32_negative_inf;
-
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(aSig, &aExp, &aSig);
- }
-
- return int32_to_float32(aExp - 0x7F, status);
-}
-
-/*----------------------------------------------------------------------------
-| Extracts the mantissa of single-precision floating-point value 'a' and
-| returns the result as a single-precision floating-point after applying
-| the mantissa interval normalization and sign control. The operation is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_getmant(float32 a, struct float_status_t *status, int sign_ctrl, int interv)
-{
- Bit16s aExp = extractFloat32Exp(a);
- Bit32u aSig = extractFloat32Frac(a);
- int aSign = extractFloat32Sign(a);
-
- if (aExp == 0xFF) {
- if (aSig) return propagateFloat32NaNOne(a, status);
- if (aSign) {
- if (sign_ctrl & 0x2) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- }
- return packFloat32(~sign_ctrl & aSign, 0x7F, 0);
- }
-
- if (aExp == 0 && (aSig == 0 || get_denormals_are_zeros(status))) {
- return packFloat32(~sign_ctrl & aSign, 0x7F, 0);
- }
-
- if (aSign) {
- if (sign_ctrl & 0x2) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- }
-
- if (aExp == 0) {
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(aSig, &aExp, &aSig);
-// aExp += 0x7E;
- aSig &= 0x7FFFFF;
- }
-
- switch(interv) {
- case 0x0: // interval [1,2)
- aExp = 0x7F;
- break;
- case 0x1: // interval [1/2,2)
- aExp -= 0x7F;
- aExp = 0x7F - (aExp & 0x1);
- break;
- case 0x2: // interval [1/2,1)
- aExp = 0x7E;
- break;
- case 0x3: // interval [3/4,3/2)
- aExp = 0x7F - ((aSig >> 22) & 0x1);
- break;
- }
-
- return packFloat32(~sign_ctrl & aSign, aExp, aSig);
-}
-
-/*----------------------------------------------------------------------------
-| Return the result of a floating point scale of the single-precision floating
-| point value `a' by multiplying it by 2 power of the single-precision
-| floating point value 'b' converted to integral value. If the result cannot
-| be represented in single precision, then the proper overflow response (for
-| positive scaling operand), or the proper underflow response (for negative
-| scaling operand) is issued. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_scalef(float32 a, float32 b, struct float_status_t *status)
-{
- Bit32u aSig = extractFloat32Frac(a);
- Bit16s aExp = extractFloat32Exp(a);
- int aSign = extractFloat32Sign(a);
- Bit32u bSig = extractFloat32Frac(b);
- Bit16s bExp = extractFloat32Exp(b);
- int bSign = extractFloat32Sign(b);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- if (bExp == 0xFF) {
- if (bSig) return propagateFloat32NaN(a, b, status);
- }
-
- if (aExp == 0xFF) {
- if (aSig) {
- int aIsSignalingNaN = (aSig & 0x00400000) == 0;
- if (aIsSignalingNaN || bExp != 0xFF || bSig)
- return propagateFloat32NaN(a, b, status);
-
- return bSign ? 0 : float32_positive_inf;
- }
-
- if (bExp == 0xFF && bSign) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- return a;
- }
-
- if (aExp == 0) {
- if (aSig == 0) {
- if (bExp == 0xFF && ! bSign) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- return a;
- }
- float_raise(status, float_flag_denormal);
- }
-
- if ((bExp | bSig) == 0) return a;
-
- if (bExp == 0xFF) {
- if (bSign) return packFloat32(aSign, 0, 0);
- return packFloat32(aSign, 0xFF, 0);
- }
-
- if (bExp >= 0x8E) {
- // handle obvious overflow/underflow result
- return roundAndPackFloat32(aSign, bSign ? -0x7F : 0xFF, aSig, status);
- }
-
- int scale = 0;
-
- if (bExp <= 0x7E) {
- if (bExp == 0)
- float_raise(status, float_flag_denormal);
- scale = -bSign;
- }
- else {
- int shiftCount = bExp - 0x9E;
- bSig = (bSig | 0x800000)<<8;
- scale = bSig>>(-shiftCount);
-
- if (bSign) {
- if ((Bit32u) (bSig<<(shiftCount & 31))) scale++;
- scale = -scale;
- }
-
- if (scale > 0x200) scale = 0x200;
- if (scale < -0x200) scale = -0x200;
- }
-
- if (aExp != 0) {
- aSig |= 0x00800000;
- } else {
- aExp++;
- }
-
- aExp += scale - 1;
- aSig <<= 7;
- return normalizeRoundAndPackFloat32(aSign, aExp, aSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the single-precision
-| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
-| before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float32 addFloat32Sigs(float32 a, float32 b, int zSign, struct float_status_t *status)
-{
- Bit16s aExp, bExp, zExp;
- Bit32u aSig, bSig, zSig;
- Bit16s expDiff;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- bSig = extractFloat32Frac(b);
- bExp = extractFloat32Exp(b);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- expDiff = aExp - bExp;
- aSig <<= 6;
- bSig <<= 6;
-
- if (0 < expDiff) {
- if (aExp == 0xFF) {
- if (aSig) return propagateFloat32NaN(a, b, status);
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return a;
- }
- if ((aExp == 0) && aSig)
- float_raise(status, float_flag_denormal);
-
- if (bExp == 0) {
- if (bSig) float_raise(status, float_flag_denormal);
- --expDiff;
- }
- else bSig |= 0x20000000;
-
- bSig = shift32RightJamming(bSig, expDiff);
- zExp = aExp;
- }
- else if (expDiff < 0) {
- if (bExp == 0xFF) {
- if (bSig) return propagateFloat32NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat32(zSign, 0xFF, 0);
- }
- if ((bExp == 0) && bSig)
- float_raise(status, float_flag_denormal);
-
- if (aExp == 0) {
- if (aSig) float_raise(status, float_flag_denormal);
- ++expDiff;
- }
- else aSig |= 0x20000000;
-
- aSig = shift32RightJamming(aSig, -expDiff);
- zExp = bExp;
- }
- else {
- if (aExp == 0xFF) {
- if (aSig | bSig) return propagateFloat32NaN(a, b, status);
- return a;
- }
- if (aExp == 0) {
- zSig = (aSig + bSig) >> 6;
- if (aSig | bSig) {
- float_raise(status, float_flag_denormal);
- if (get_flush_underflow_to_zero(status) && (extractFloat32Frac(zSig) == zSig)) {
- float_raise(status, float_flag_underflow | float_flag_inexact);
- return packFloat32(zSign, 0, 0);
- }
- if (! float_exception_masked(status, float_flag_underflow)) {
- if (extractFloat32Frac(zSig) == zSig)
- float_raise(status, float_flag_underflow);
- }
- }
- return packFloat32(zSign, 0, zSig);
- }
- zSig = 0x40000000 + aSig + bSig;
- return roundAndPackFloat32(zSign, aExp, zSig, status);
- }
- aSig |= 0x20000000;
- zSig = (aSig + bSig)<<1;
- --zExp;
- if ((Bit32s) zSig < 0) {
- zSig = aSig + bSig;
- ++zExp;
- }
- return roundAndPackFloat32(zSign, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the single-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float32 subFloat32Sigs(float32 a, float32 b, int zSign, struct float_status_t *status)
-{
- Bit16s aExp, bExp, zExp;
- Bit32u aSig, bSig, zSig;
- Bit16s expDiff;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- bSig = extractFloat32Frac(b);
- bExp = extractFloat32Exp(b);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- expDiff = aExp - bExp;
- aSig <<= 7;
- bSig <<= 7;
- if (0 < expDiff) goto aExpBigger;
- if (expDiff < 0) goto bExpBigger;
- if (aExp == 0xFF) {
- if (aSig | bSig) return propagateFloat32NaN(a, b, status);
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- if (aExp == 0) {
- if (aSig | bSig) float_raise(status, float_flag_denormal);
- aExp = 1;
- bExp = 1;
- }
- if (bSig < aSig) goto aBigger;
- if (aSig < bSig) goto bBigger;
- return packFloat32(get_float_rounding_mode(status) == float_round_down, 0, 0);
- bExpBigger:
- if (bExp == 0xFF) {
- if (bSig) return propagateFloat32NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat32(zSign ^ 1, 0xFF, 0);
- }
- if ((bExp == 0) && bSig)
- float_raise(status, float_flag_denormal);
-
- if (aExp == 0) {
- if (aSig) float_raise(status, float_flag_denormal);
- ++expDiff;
- }
- else aSig |= 0x40000000;
-
- aSig = shift32RightJamming(aSig, -expDiff);
- bSig |= 0x40000000;
- bBigger:
- zSig = bSig - aSig;
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aExpBigger:
- if (aExp == 0xFF) {
- if (aSig) return propagateFloat32NaN(a, b, status);
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return a;
- }
- if ((aExp == 0) && aSig)
- float_raise(status, float_flag_denormal);
-
- if (bExp == 0) {
- if (bSig) float_raise(status, float_flag_denormal);
- --expDiff;
- }
- else bSig |= 0x40000000;
-
- bSig = shift32RightJamming(bSig, expDiff);
- aSig |= 0x40000000;
- aBigger:
- zSig = aSig - bSig;
- zExp = aExp;
- normalizeRoundAndPack:
- --zExp;
- return normalizeRoundAndPackFloat32(zSign, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the single-precision floating-point values `a'
-| and `b'. The operation is performed according to the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_add(float32 a, float32 b, struct float_status_t *status)
-{
- int aSign = extractFloat32Sign(a);
- int bSign = extractFloat32Sign(b);
-
- if (aSign == bSign) {
- return addFloat32Sigs(a, b, aSign, status);
- }
- else {
- return subFloat32Sigs(a, b, aSign, status);
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the single-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_sub(float32 a, float32 b, struct float_status_t *status)
-{
- int aSign = extractFloat32Sign(a);
- int bSign = extractFloat32Sign(b);
-
- if (aSign == bSign) {
- return subFloat32Sigs(a, b, aSign, status);
- }
- else {
- return addFloat32Sigs(a, b, aSign, status);
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the single-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_mul(float32 a, float32 b, struct float_status_t *status)
-{
- int aSign, bSign, zSign;
- Bit16s aExp, bExp, zExp;
- Bit32u aSig, bSig;
- Bit64u zSig64;
- Bit32u zSig;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
- bSig = extractFloat32Frac(b);
- bExp = extractFloat32Exp(b);
- bSign = extractFloat32Sign(b);
- zSign = aSign ^ bSign;
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- if (aExp == 0xFF) {
- if (aSig || ((bExp == 0xFF) && bSig))
- return propagateFloat32NaN(a, b, status);
-
- if ((bExp | bSig) == 0) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat32(zSign, 0xFF, 0);
- }
- if (bExp == 0xFF) {
- if (bSig) return propagateFloat32NaN(a, b, status);
- if ((aExp | aSig) == 0) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat32(zSign, 0xFF, 0);
- }
- if (aExp == 0) {
- if (aSig == 0) {
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat32(zSign, 0, 0);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- if (bSig == 0) return packFloat32(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(bSig, &bExp, &bSig);
- }
- zExp = aExp + bExp - 0x7F;
- aSig = (aSig | 0x00800000)<<7;
- bSig = (bSig | 0x00800000)<<8;
- zSig64 = shift64RightJamming(((Bit64u) aSig) * bSig, 32);
- zSig = (Bit32u) zSig64;
- if (0 <= (Bit32s) (zSig<<1)) {
- zSig <<= 1;
- --zExp;
- }
- return roundAndPackFloat32(zSign, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the single-precision floating-point value `a'
-| by the corresponding value `b'. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_div(float32 a, float32 b, struct float_status_t *status)
-{
- int aSign, bSign, zSign;
- Bit16s aExp, bExp, zExp;
- Bit32u aSig, bSig, zSig;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
- bSig = extractFloat32Frac(b);
- bExp = extractFloat32Exp(b);
- bSign = extractFloat32Sign(b);
- zSign = aSign ^ bSign;
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- if (aExp == 0xFF) {
- if (aSig) return propagateFloat32NaN(a, b, status);
- if (bExp == 0xFF) {
- if (bSig) return propagateFloat32NaN(a, b, status);
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat32(zSign, 0xFF, 0);
- }
- if (bExp == 0xFF) {
- if (bSig) return propagateFloat32NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat32(zSign, 0, 0);
- }
- if (bExp == 0) {
- if (bSig == 0) {
- if ((aExp | aSig) == 0) {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- float_raise(status, float_flag_divbyzero);
- return packFloat32(zSign, 0xFF, 0);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(bSig, &bExp, &bSig);
- }
- if (aExp == 0) {
- if (aSig == 0) return packFloat32(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(aSig, &aExp, &aSig);
- }
- zExp = aExp - bExp + 0x7D;
- aSig = (aSig | 0x00800000)<<7;
- bSig = (bSig | 0x00800000)<<8;
- if (bSig <= (aSig + aSig)) {
- aSig >>= 1;
- ++zExp;
- }
- zSig = (((Bit64u) aSig)<<32) / bSig;
- if ((zSig & 0x3F) == 0) {
- zSig |= ((Bit64u) bSig * zSig != ((Bit64u) aSig)<<32);
- }
- return roundAndPackFloat32(zSign, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the square root of the single-precision floating-point value `a'.
-| The operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_sqrt(float32 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp, zExp;
- Bit32u aSig, zSig;
- Bit64u rem, term;
-
- aSig = extractFloat32Frac(a);
- aExp = extractFloat32Exp(a);
- aSign = extractFloat32Sign(a);
-
- if (aExp == 0xFF) {
- if (aSig) return propagateFloat32NaNOne(a, status);
- if (! aSign) return a;
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- }
-
- if (aSign) {
- if ((aExp | aSig) == 0) return packFloat32(aSign, 0, 0);
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
- if (aExp == 0) {
- if (aSig == 0) return 0;
- float_raise(status, float_flag_denormal);
- normalizeFloat32Subnormal(aSig, &aExp, &aSig);
- }
- zExp = ((aExp - 0x7F)>>1) + 0x7E;
- aSig = (aSig | 0x00800000)<<8;
- zSig = estimateSqrt32(aExp, aSig) + 2;
- if ((zSig & 0x7F) <= 5) {
- if (zSig < 2) {
- zSig = 0x7FFFFFFF;
- goto roundAndPack;
- }
- aSig >>= aExp & 1;
- term = ((Bit64u) zSig) * zSig;
- rem = (((Bit64u) aSig)<<32) - term;
- while ((Bit64s) rem < 0) {
- --zSig;
- rem += (((Bit64u) zSig)<<1) | 1;
- }
- zSig |= (rem != 0);
- }
- zSig = shift32RightJamming(zSig, 1);
- roundAndPack:
- return roundAndPackFloat32(0, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Determine single-precision floating-point number class.
-*----------------------------------------------------------------------------*/
-
-float_class_t float32_class(float32 a)
-{
- Bit16s aExp = extractFloat32Exp(a);
- Bit32u aSig = extractFloat32Frac(a);
- int aSign = extractFloat32Sign(a);
-
- if(aExp == 0xFF) {
- if (aSig == 0)
- return (aSign) ? float_negative_inf : float_positive_inf;
-
- return (aSig & 0x00400000) ? float_QNaN : float_SNaN;
- }
-
- if(aExp == 0) {
- if (aSig == 0) return float_zero;
- return float_denormal;
- }
-
- return float_normalized;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two single precision floating point numbers. Returns
-| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
-| the value 'a' is less than the corresponding value `b',
-| 'float_relation_greater' if the value 'a' is greater than the corresponding
-| value `b', or 'float_relation_unordered' otherwise.
-*----------------------------------------------------------------------------*/
-
-int float32_compare(float32 a, float32 b, int quiet, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float32_denormal_to_zero(a);
- b = float32_denormal_to_zero(b);
- }
-
- float_class_t aClass = float32_class(a);
- float_class_t bClass = float32_class(b);
-
- if (aClass == float_SNaN || bClass == float_SNaN) {
- float_raise(status, float_flag_invalid);
- return float_relation_unordered;
- }
-
- if (aClass == float_QNaN || bClass == float_QNaN) {
- if (! quiet) float_raise(status, float_flag_invalid);
- return float_relation_unordered;
- }
-
- if (aClass == float_denormal || bClass == float_denormal) {
- float_raise(status, float_flag_denormal);
- }
-
- if ((a == b) || ((Bit32u) ((a | b)<<1) == 0)) return float_relation_equal;
-
- int aSign = extractFloat32Sign(a);
- int bSign = extractFloat32Sign(b);
- if (aSign != bSign)
- return (aSign) ? float_relation_less : float_relation_greater;
-
- if (aSign ^ (a < b)) return float_relation_less;
- return float_relation_greater;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two single precision floating point numbers and return the
-| smaller of them.
-*----------------------------------------------------------------------------*/
-
-float32 float32_min(float32 a, float32 b, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float32_denormal_to_zero(a);
- b = float32_denormal_to_zero(b);
- }
-
- return (float32_compare_two(a, b, status) == float_relation_less) ? a : b;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two single precision floating point numbers and return the
-| larger of them.
-*----------------------------------------------------------------------------*/
-
-float32 float32_max(float32 a, float32 b, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float32_denormal_to_zero(a);
- b = float32_denormal_to_zero(b);
- }
-
- return (float32_compare_two(a, b, status) == float_relation_greater) ? a : b;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two single precision floating point numbers and return the
-| smaller/larger of them. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float32_minmax(float32 a, float32 b, int is_max, int is_abs, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float32_denormal_to_zero(a);
- b = float32_denormal_to_zero(b);
- }
-
- if (float32_is_nan(a) || float32_is_nan(b)) {
- if (float32_is_signaling_nan(a)) {
- return propagateFloat32NaNOne(a, status);
- }
- if (float32_is_signaling_nan(b) ) {
- return propagateFloat32NaNOne(b, status);
- }
- if (! float32_is_nan(b)) {
- if (float32_is_denormal(b))
- float_raise(status, float_flag_denormal);
- return b;
- }
- if (! float32_is_nan(a)) {
- if (float32_is_denormal(a))
- float_raise(status, float_flag_denormal);
- return a;
- }
- return propagateFloat32NaN(a, b, status);
- }
-
- float32 tmp_a = a, tmp_b = b;
- if (is_abs) {
- tmp_a &= ~0x80000000; // clear the sign bit
- tmp_b &= ~0x80000000;
- }
-
- int aSign = extractFloat32Sign(tmp_a);
- int bSign = extractFloat32Sign(tmp_b);
-
- if (float32_is_denormal(a) || float32_is_denormal(b))
- float_raise(status, float_flag_denormal);
-
- if (aSign != bSign) {
- if (! is_max) {
- return aSign ? a : b;
- } else {
- return aSign ? b : a;
- }
- } else {
- if (! is_max) {
- return (aSign ^ (tmp_a < tmp_b)) ? a : b;
- } else {
- return (aSign ^ (tmp_a < tmp_b)) ? b : a;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic - which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN or the
-| conversion overflows, the integer indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32s float64_to_int32(float64 a, struct float_status_t *status)
-{
- Bit64u aSig = extractFloat64Frac(a);
- Bit16s aExp = extractFloat64Exp(a);
- int aSign = extractFloat64Sign(a);
- if ((aExp == 0x7FF) && aSig) aSign = 0;
- if (aExp) aSig |= BX_CONST64(0x0010000000000000);
- else {
- if (get_denormals_are_zeros(status)) aSig = 0;
- }
- int shiftCount = 0x42C - aExp;
- if (0 < shiftCount) aSig = shift64RightJamming(aSig, shiftCount);
- return roundAndPackInt32(aSign, aSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 32-bit two's complement integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic, except that the conversion is always rounded toward zero.
-| If `a' is a NaN or the conversion overflows, the integer indefinite
-| value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32s float64_to_int32_round_to_zero(float64 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp;
- Bit64u aSig, savedASig;
- Bit32s z;
- int shiftCount;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
- if (0x41E < aExp) {
- float_raise(status, float_flag_invalid);
- return (Bit32s)(int32_indefinite);
- }
- else if (aExp < 0x3FF) {
- if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0;
- if (aExp || aSig) float_raise(status, float_flag_inexact);
- return 0;
- }
- aSig |= BX_CONST64(0x0010000000000000);
- shiftCount = 0x433 - aExp;
- savedASig = aSig;
- aSig >>= shiftCount;
- z = (Bit32s) aSig;
- if (aSign) z = -z;
- if ((z < 0) ^ aSign) {
- float_raise(status, float_flag_invalid);
- return (Bit32s)(int32_indefinite);
- }
- if ((aSig<>= shiftCount;
- if ((aSig<>(-shiftCount);
- if ((Bit64u) (aSig<<(shiftCount & 63))) {
- float_raise(status, float_flag_inexact);
- }
- }
- if (aSign) z = -z;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 64-bit unsigned integer format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic,
-| except that the conversion is always rounded toward zero. If `a' is a NaN
-| or the conversion overflows, the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64u float64_to_uint64_round_to_zero(float64 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp;
- Bit64u aSig, z;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
-
- if (aExp < 0x3FE) {
- if (get_denormals_are_zeros(status) && aExp == 0) aSig = 0;
- if (aExp | aSig) float_raise(status, float_flag_inexact);
- return 0;
- }
-
- if (0x43E <= aExp || aSign) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
-
- if (aExp) aSig |= BX_CONST64(0x0010000000000000);
- int shiftCount = aExp - 0x433;
-
- if (0 <= shiftCount) {
- z = aSig<>(-shiftCount);
- if ((Bit64u) (aSig<<(shiftCount & 63))) {
- float_raise(status, float_flag_inexact);
- }
- }
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 32-bit unsigned integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN or the conversion
-| overflows, the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit32u float64_to_uint32(float64 a, struct float_status_t *status)
-{
- Bit64u val_64 = float64_to_uint64(a, status);
-
- if (val_64 > 0xffffffff) {
- status->float_exception_flags = float_flag_invalid; // throw away other flags
- return uint32_indefinite;
- }
-
- return (Bit32u) val_64;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the 64-bit unsigned integer format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode. If `a' is a NaN or the conversion
-| overflows, the largest unsigned integer is returned.
-*----------------------------------------------------------------------------*/
-
-Bit64u float64_to_uint64(float64 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp, shiftCount;
- Bit64u aSig, aSigExtra;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- }
-
- if (aSign && (aExp > 0x3FE)) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
-
- if (aExp) {
- aSig |= BX_CONST64(0x0010000000000000);
- }
- shiftCount = 0x433 - aExp;
- if (shiftCount <= 0) {
- if (0x43E < aExp) {
- float_raise(status, float_flag_invalid);
- return uint64_indefinite;
- }
- aSigExtra = 0;
- aSig <<= -shiftCount;
- } else {
- shift64ExtraRightJamming(aSig, 0, shiftCount, &aSig, &aSigExtra);
- }
-
- return roundAndPackUint64(aSign, aSig, aSigExtra, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the double-precision floating-point value
-| `a' to the single-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float64_to_float32(float64 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp;
- Bit64u aSig;
- Bit32u zSig;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
- if (aExp == 0x7FF) {
- if (aSig) return commonNaNToFloat32(float64ToCommonNaN(a, status));
- return packFloat32(aSign, 0xFF, 0);
- }
- if (aExp == 0) {
- if (aSig == 0 || get_denormals_are_zeros(status))
- return packFloat32(aSign, 0, 0);
- float_raise(status, float_flag_denormal);
- }
- aSig = shift64RightJamming(aSig, 22);
- zSig = (Bit32u) aSig;
- if (aExp || zSig) {
- zSig |= 0x40000000;
- aExp -= 0x381;
- }
- return roundAndPackFloat32(aSign, aExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Rounds the double-precision floating-point value `a' to an integer, and
-| returns the result as a double-precision floating-point value. The
-| operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_round_to_int(float64 a, Bit8u scale, struct float_status_t *status)
-{
- Bit64u lastBitMask, roundBitsMask;
- int roundingMode = get_float_rounding_mode(status);
- Bit16s aExp = extractFloat64Exp(a);
- scale &= 0xf;
-
- if ((aExp == 0x7FF) && extractFloat64Frac(a)) {
- return propagateFloat64NaNOne(a, status);
- }
-
- aExp += scale; // scale the exponent
-
- if (0x433 <= aExp) {
- return a;
- }
-
- if (get_denormals_are_zeros(status)) {
- a = float64_denormal_to_zero(a);
- }
-
- if (aExp < 0x3FF) {
- if ((Bit64u) (a<<1) == 0) return a;
- float_raise(status, float_flag_inexact);
- int aSign = extractFloat64Sign(a);
- switch (roundingMode) {
- case float_round_nearest_even:
- if ((aExp == 0x3FE) && extractFloat64Frac(a)) {
- return packFloat64(aSign, 0x3FF - scale, 0);
- }
- break;
- case float_round_down:
- return aSign ? packFloat64(1, 0x3FF - scale, 0) : float64_positive_zero;
- case float_round_up:
- return aSign ? float64_negative_zero : packFloat64(0, 0x3FF - scale, 0);
- }
- return packFloat64(aSign, 0, 0);
- }
-
- lastBitMask = 1;
- lastBitMask <<= 0x433 - aExp;
- roundBitsMask = lastBitMask - 1;
- float64 z = a;
- if (roundingMode == float_round_nearest_even) {
- z += lastBitMask>>1;
- if ((z & roundBitsMask) == 0) z &= ~lastBitMask;
- }
- else if (roundingMode != float_round_to_zero) {
- if (extractFloat64Sign(z) ^ (roundingMode == float_round_up)) {
- z += roundBitsMask;
- }
- }
- z &= ~roundBitsMask;
- if (z != a) float_raise(status, float_flag_inexact);
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Extracts the fractional portion of double-precision floating-point value `a',
-| and returns the result as a double-precision floating-point value. The
-| fractional results are precise. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_frc(float64 a, struct float_status_t *status)
-{
- int roundingMode = get_float_rounding_mode(status);
-
- Bit64u aSig = extractFloat64Frac(a);
- Bit16s aExp = extractFloat64Exp(a);
- int aSign = extractFloat64Sign(a);
-
- if (aExp == 0x7FF) {
- if (aSig) return propagateFloat64NaNOne(a, status);
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
-
- if (aExp >= 0x433) {
- return packFloat64(roundingMode == float_round_down, 0, 0);
- }
-
- if (aExp < 0x3FF) {
- if (aExp == 0) {
- if (aSig == 0 || get_denormals_are_zeros(status))
- return packFloat64(roundingMode == float_round_down, 0, 0);
-
- float_raise(status, float_flag_denormal);
- if (! float_exception_masked(status, float_flag_underflow))
- float_raise(status, float_flag_underflow);
-
- if(get_flush_underflow_to_zero(status)) {
- float_raise(status, float_flag_underflow | float_flag_inexact);
- return packFloat64(aSign, 0, 0);
- }
- }
- return a;
- }
-
- Bit64u lastBitMask = BX_CONST64(1) << (0x433 - aExp);
- Bit64u roundBitsMask = lastBitMask - 1;
-
- aSig &= roundBitsMask;
- aSig <<= 10;
- aExp--;
-
- if (aSig == 0)
- return packFloat64(roundingMode == float_round_down, 0, 0);
-
- return normalizeRoundAndPackFloat64(aSign, aExp, aSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Extracts the exponent portion of double-precision floating-point value 'a',
-| and returns the result as a double-precision floating-point value
-| representing unbiased integer exponent. The operation is performed according
-| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_getexp(float64 a, struct float_status_t *status)
-{
- Bit16s aExp = extractFloat64Exp(a);
- Bit64u aSig = extractFloat64Frac(a);
-
- if (aExp == 0x7FF) {
- if (aSig) return propagateFloat64NaNOne(a, status);
- return float64_positive_inf;
- }
-
- if (aExp == 0) {
- if (aSig == 0 || get_denormals_are_zeros(status))
- return float64_negative_inf;
-
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(aSig, &aExp, &aSig);
- }
-
- return int32_to_float64(aExp - 0x3FF);
-}
-
-/*----------------------------------------------------------------------------
-| Extracts the mantissa of double-precision floating-point value 'a' and
-| returns the result as a double-precision floating-point after applying
-| the mantissa interval normalization and sign control. The operation is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_getmant(float64 a, struct float_status_t *status, int sign_ctrl, int interv)
-{
- Bit16s aExp = extractFloat64Exp(a);
- Bit64u aSig = extractFloat64Frac(a);
- int aSign = extractFloat64Sign(a);
-
- if (aExp == 0x7FF) {
- if (aSig) return propagateFloat64NaNOne(a, status);
- if (aSign) {
- if (sign_ctrl & 0x2) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- }
- return packFloat64(~sign_ctrl & aSign, 0x3FF, 0);
- }
-
- if (aExp == 0 && (aSig == 0 || get_denormals_are_zeros(status))) {
- return packFloat64(~sign_ctrl & aSign, 0x3FF, 0);
- }
-
- if (aSign) {
- if (sign_ctrl & 0x2) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- }
-
- if (aExp == 0) {
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(aSig, &aExp, &aSig);
-// aExp += 0x3FE;
- aSig &= BX_CONST64(0xFFFFFFFFFFFFFFFF);
- }
-
- switch(interv) {
- case 0x0: // interval [1,2)
- aExp = 0x3FF;
- break;
- case 0x1: // interval [1/2,2)
- aExp -= 0x3FF;
- aExp = 0x3FF - (aExp & 0x1);
- break;
- case 0x2: // interval [1/2,1)
- aExp = 0x3FE;
- break;
- case 0x3: // interval [3/4,3/2)
- aExp = 0x3FF - ((aSig >> 51) & 0x1);
- break;
- }
-
- return packFloat64(~sign_ctrl & aSign, aExp, aSig);
-}
-
-/*----------------------------------------------------------------------------
-| Return the result of a floating point scale of the double-precision floating
-| point value `a' by multiplying it by 2 power of the double-precision
-| floating point value 'b' converted to integral value. If the result cannot
-| be represented in double precision, then the proper overflow response (for
-| positive scaling operand), or the proper underflow response (for negative
-| scaling operand) is issued. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_scalef(float64 a, float64 b, struct float_status_t *status)
-{
- Bit64u aSig = extractFloat64Frac(a);
- Bit16s aExp = extractFloat64Exp(a);
- int aSign = extractFloat64Sign(a);
- Bit64u bSig = extractFloat64Frac(b);
- Bit16s bExp = extractFloat64Exp(b);
- int bSign = extractFloat64Sign(b);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- if (bExp == 0x7FF) {
- if (bSig) return propagateFloat64NaN(a, b, status);
- }
-
- if (aExp == 0x7FF) {
- if (aSig) {
- int aIsSignalingNaN = (aSig & BX_CONST64(0x0008000000000000)) == 0;
- if (aIsSignalingNaN || bExp != 0x7FF || bSig)
- return propagateFloat64NaN(a, b, status);
-
- return bSign ? 0 : float64_positive_inf;
- }
-
- if (bExp == 0x7FF && bSign) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- return a;
- }
-
- if (aExp == 0) {
- if (aSig == 0) {
- if (bExp == 0x7FF && ! bSign) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- return a;
- }
- float_raise(status, float_flag_denormal);
- }
-
- if ((bExp | bSig) == 0) return a;
-
- if (bExp == 0x7FF) {
- if (bSign) return packFloat64(aSign, 0, 0);
- return packFloat64(aSign, 0x7FF, 0);
- }
-
- if (0x40F <= bExp) {
- // handle obvious overflow/underflow result
- return roundAndPackFloat64(aSign, bSign ? -0x3FF : 0x7FF, aSig, status);
- }
-
- int scale = 0;
-
- if (bExp < 0x3FF) {
- if (bExp == 0)
- float_raise(status, float_flag_denormal);
- scale = -bSign;
- }
- else {
- bSig |= BX_CONST64(0x0010000000000000);
- int shiftCount = 0x433 - bExp;
- Bit64u savedBSig = bSig;
- bSig >>= shiftCount;
- scale = (Bit32s) bSig;
- if (bSign) {
- if ((bSig< 0x1000) scale = 0x1000;
- if (scale < -0x1000) scale = -0x1000;
- }
-
- if (aExp != 0) {
- aSig |= BX_CONST64(0x0010000000000000);
- } else {
- aExp++;
- }
-
- aExp += scale - 1;
- aSig <<= 10;
- return normalizeRoundAndPackFloat64(aSign, aExp, aSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the double-precision
-| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
-| before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float64 addFloat64Sigs(float64 a, float64 b, int zSign, struct float_status_t *status)
-{
- Bit16s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig;
- Bit16s expDiff;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- bSig = extractFloat64Frac(b);
- bExp = extractFloat64Exp(b);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- expDiff = aExp - bExp;
- aSig <<= 9;
- bSig <<= 9;
- if (0 < expDiff) {
- if (aExp == 0x7FF) {
- if (aSig) return propagateFloat64NaN(a, b, status);
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return a;
- }
- if ((aExp == 0) && aSig)
- float_raise(status, float_flag_denormal);
-
- if (bExp == 0) {
- if (bSig) float_raise(status, float_flag_denormal);
- --expDiff;
- }
- else bSig |= BX_CONST64(0x2000000000000000);
-
- bSig = shift64RightJamming(bSig, expDiff);
- zExp = aExp;
- }
- else if (expDiff < 0) {
- if (bExp == 0x7FF) {
- if (bSig) return propagateFloat64NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat64(zSign, 0x7FF, 0);
- }
- if ((bExp == 0) && bSig)
- float_raise(status, float_flag_denormal);
-
- if (aExp == 0) {
- if (aSig) float_raise(status, float_flag_denormal);
- ++expDiff;
- }
- else aSig |= BX_CONST64(0x2000000000000000);
-
- aSig = shift64RightJamming(aSig, -expDiff);
- zExp = bExp;
- }
- else {
- if (aExp == 0x7FF) {
- if (aSig | bSig) return propagateFloat64NaN(a, b, status);
- return a;
- }
- if (aExp == 0) {
- zSig = (aSig + bSig) >> 9;
- if (aSig | bSig) {
- float_raise(status, float_flag_denormal);
- if (get_flush_underflow_to_zero(status) && (extractFloat64Frac(zSig) == zSig)) {
- float_raise(status, float_flag_underflow | float_flag_inexact);
- return packFloat64(zSign, 0, 0);
- }
- if (! float_exception_masked(status, float_flag_underflow)) {
- if (extractFloat64Frac(zSig) == zSig)
- float_raise(status, float_flag_underflow);
- }
- }
- return packFloat64(zSign, 0, zSig);
- }
- zSig = BX_CONST64(0x4000000000000000) + aSig + bSig;
- return roundAndPackFloat64(zSign, aExp, zSig, status);
- }
- aSig |= BX_CONST64(0x2000000000000000);
- zSig = (aSig + bSig)<<1;
- --zExp;
- if ((Bit64s) zSig < 0) {
- zSig = aSig + bSig;
- ++zExp;
- }
- return roundAndPackFloat64(zSign, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the double-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float64 subFloat64Sigs(float64 a, float64 b, int zSign, struct float_status_t *status)
-{
- Bit16s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig;
- Bit16s expDiff;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- bSig = extractFloat64Frac(b);
- bExp = extractFloat64Exp(b);
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- expDiff = aExp - bExp;
- aSig <<= 10;
- bSig <<= 10;
- if (0 < expDiff) goto aExpBigger;
- if (expDiff < 0) goto bExpBigger;
- if (aExp == 0x7FF) {
- if (aSig | bSig) return propagateFloat64NaN(a, b, status);
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- if (aExp == 0) {
- if (aSig | bSig) float_raise(status, float_flag_denormal);
- aExp = 1;
- bExp = 1;
- }
- if (bSig < aSig) goto aBigger;
- if (aSig < bSig) goto bBigger;
- return packFloat64(get_float_rounding_mode(status) == float_round_down, 0, 0);
- bExpBigger:
- if (bExp == 0x7FF) {
- if (bSig) return propagateFloat64NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat64(zSign ^ 1, 0x7FF, 0);
- }
- if ((bExp == 0) && bSig)
- float_raise(status, float_flag_denormal);
-
- if (aExp == 0) {
- if (aSig) float_raise(status, float_flag_denormal);
- ++expDiff;
- }
- else aSig |= BX_CONST64(0x4000000000000000);
-
- aSig = shift64RightJamming(aSig, -expDiff);
- bSig |= BX_CONST64(0x4000000000000000);
- bBigger:
- zSig = bSig - aSig;
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aExpBigger:
- if (aExp == 0x7FF) {
- if (aSig) return propagateFloat64NaN(a, b, status);
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return a;
- }
- if ((aExp == 0) && aSig)
- float_raise(status, float_flag_denormal);
-
- if (bExp == 0) {
- if (bSig) float_raise(status, float_flag_denormal);
- --expDiff;
- }
- else bSig |= BX_CONST64(0x4000000000000000);
-
- bSig = shift64RightJamming(bSig, expDiff);
- aSig |= BX_CONST64(0x4000000000000000);
- aBigger:
- zSig = aSig - bSig;
- zExp = aExp;
- normalizeRoundAndPack:
- --zExp;
- return normalizeRoundAndPackFloat64(zSign, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the double-precision floating-point values `a'
-| and `b'. The operation is performed according to the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_add(float64 a, float64 b, struct float_status_t *status)
-{
- int aSign = extractFloat64Sign(a);
- int bSign = extractFloat64Sign(b);
-
- if (aSign == bSign) {
- return addFloat64Sigs(a, b, aSign, status);
- }
- else {
- return subFloat64Sigs(a, b, aSign, status);
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the double-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_sub(float64 a, float64 b, struct float_status_t *status)
-{
- int aSign = extractFloat64Sign(a);
- int bSign = extractFloat64Sign(b);
-
- if (aSign == bSign) {
- return subFloat64Sigs(a, b, aSign, status);
- }
- else {
- return addFloat64Sigs(a, b, aSign, status);
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the double-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_mul(float64 a, float64 b, struct float_status_t *status)
-{
- int aSign, bSign, zSign;
- Bit16s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig0, zSig1;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
- bSig = extractFloat64Frac(b);
- bExp = extractFloat64Exp(b);
- bSign = extractFloat64Sign(b);
- zSign = aSign ^ bSign;
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- if (aExp == 0x7FF) {
- if (aSig || ((bExp == 0x7FF) && bSig)) {
- return propagateFloat64NaN(a, b, status);
- }
- if ((bExp | bSig) == 0) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat64(zSign, 0x7FF, 0);
- }
- if (bExp == 0x7FF) {
- if (bSig) return propagateFloat64NaN(a, b, status);
- if ((aExp | aSig) == 0) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat64(zSign, 0x7FF, 0);
- }
- if (aExp == 0) {
- if (aSig == 0) {
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat64(zSign, 0, 0);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- if (bSig == 0) return packFloat64(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(bSig, &bExp, &bSig);
- }
- zExp = aExp + bExp - 0x3FF;
- aSig = (aSig | BX_CONST64(0x0010000000000000))<<10;
- bSig = (bSig | BX_CONST64(0x0010000000000000))<<11;
- mul64To128(aSig, bSig, &zSig0, &zSig1);
- zSig0 |= (zSig1 != 0);
- if (0 <= (Bit64s) (zSig0<<1)) {
- zSig0 <<= 1;
- --zExp;
- }
- return roundAndPackFloat64(zSign, zExp, zSig0, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the double-precision floating-point value `a'
-| by the corresponding value `b'. The operation is performed according to
-| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_div(float64 a, float64 b, struct float_status_t *status)
-{
- int aSign, bSign, zSign;
- Bit16s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig;
- Bit64u rem0, rem1;
- Bit64u term0, term1;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
- bSig = extractFloat64Frac(b);
- bExp = extractFloat64Exp(b);
- bSign = extractFloat64Sign(b);
- zSign = aSign ^ bSign;
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- if (bExp == 0) bSig = 0;
- }
-
- if (aExp == 0x7FF) {
- if (aSig) return propagateFloat64NaN(a, b, status);
- if (bExp == 0x7FF) {
- if (bSig) return propagateFloat64NaN(a, b, status);
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat64(zSign, 0x7FF, 0);
- }
- if (bExp == 0x7FF) {
- if (bSig) return propagateFloat64NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloat64(zSign, 0, 0);
- }
- if (bExp == 0) {
- if (bSig == 0) {
- if ((aExp | aSig) == 0) {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- float_raise(status, float_flag_divbyzero);
- return packFloat64(zSign, 0x7FF, 0);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(bSig, &bExp, &bSig);
- }
- if (aExp == 0) {
- if (aSig == 0) return packFloat64(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(aSig, &aExp, &aSig);
- }
- zExp = aExp - bExp + 0x3FD;
- aSig = (aSig | BX_CONST64(0x0010000000000000))<<10;
- bSig = (bSig | BX_CONST64(0x0010000000000000))<<11;
- if (bSig <= (aSig + aSig)) {
- aSig >>= 1;
- ++zExp;
- }
- zSig = estimateDiv128To64(aSig, 0, bSig);
- if ((zSig & 0x1FF) <= 2) {
- mul64To128(bSig, zSig, &term0, &term1);
- sub128(aSig, 0, term0, term1, &rem0, &rem1);
- while ((Bit64s) rem0 < 0) {
- --zSig;
- add128(rem0, rem1, 0, bSig, &rem0, &rem1);
- }
- zSig |= (rem1 != 0);
- }
- return roundAndPackFloat64(zSign, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the square root of the double-precision floating-point value `a'.
-| The operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_sqrt(float64 a, struct float_status_t *status)
-{
- int aSign;
- Bit16s aExp, zExp;
- Bit64u aSig, zSig, doubleZSig;
- Bit64u rem0, rem1, term0, term1;
-
- aSig = extractFloat64Frac(a);
- aExp = extractFloat64Exp(a);
- aSign = extractFloat64Sign(a);
-
- if (aExp == 0x7FF) {
- if (aSig) return propagateFloat64NaNOne(a, status);
- if (! aSign) return a;
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
-
- if (get_denormals_are_zeros(status)) {
- if (aExp == 0) aSig = 0;
- }
-
- if (aSign) {
- if ((aExp | aSig) == 0) return packFloat64(aSign, 0, 0);
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
- if (aExp == 0) {
- if (aSig == 0) return 0;
- float_raise(status, float_flag_denormal);
- normalizeFloat64Subnormal(aSig, &aExp, &aSig);
- }
- zExp = ((aExp - 0x3FF)>>1) + 0x3FE;
- aSig |= BX_CONST64(0x0010000000000000);
- zSig = estimateSqrt32(aExp, (Bit32u)(aSig>>21));
- aSig <<= 9 - (aExp & 1);
- zSig = estimateDiv128To64(aSig, 0, zSig<<32) + (zSig<<30);
- if ((zSig & 0x1FF) <= 5) {
- doubleZSig = zSig<<1;
- mul64To128(zSig, zSig, &term0, &term1);
- sub128(aSig, 0, term0, term1, &rem0, &rem1);
- while ((Bit64s) rem0 < 0) {
- --zSig;
- doubleZSig -= 2;
- add128(rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1);
- }
- zSig |= ((rem0 | rem1) != 0);
- }
- return roundAndPackFloat64(0, zExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Determine double-precision floating-point number class
-*----------------------------------------------------------------------------*/
-
-float_class_t float64_class(float64 a)
-{
- Bit16s aExp = extractFloat64Exp(a);
- Bit64u aSig = extractFloat64Frac(a);
- int aSign = extractFloat64Sign(a);
-
- if(aExp == 0x7FF) {
- if (aSig == 0)
- return (aSign) ? float_negative_inf : float_positive_inf;
-
- return (aSig & BX_CONST64(0x0008000000000000)) ? float_QNaN : float_SNaN;
- }
-
- if(aExp == 0) {
- if (aSig == 0)
- return float_zero;
- return float_denormal;
- }
-
- return float_normalized;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two double precision floating point numbers. Returns
-| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
-| the value 'a' is less than the corresponding value `b',
-| 'float_relation_greater' if the value 'a' is greater than the corresponding
-| value `b', or 'float_relation_unordered' otherwise.
-*----------------------------------------------------------------------------*/
-
-int float64_compare(float64 a, float64 b, int quiet, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float64_denormal_to_zero(a);
- b = float64_denormal_to_zero(b);
- }
-
- float_class_t aClass = float64_class(a);
- float_class_t bClass = float64_class(b);
-
- if (aClass == float_SNaN || bClass == float_SNaN) {
- float_raise(status, float_flag_invalid);
- return float_relation_unordered;
- }
-
- if (aClass == float_QNaN || bClass == float_QNaN) {
- if (! quiet) float_raise(status, float_flag_invalid);
- return float_relation_unordered;
- }
-
- if (aClass == float_denormal || bClass == float_denormal) {
- float_raise(status, float_flag_denormal);
- }
-
- if ((a == b) || ((Bit64u) ((a | b)<<1) == 0)) return float_relation_equal;
-
- int aSign = extractFloat64Sign(a);
- int bSign = extractFloat64Sign(b);
- if (aSign != bSign)
- return (aSign) ? float_relation_less : float_relation_greater;
-
- if (aSign ^ (a < b)) return float_relation_less;
- return float_relation_greater;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two double precision floating point numbers and return the
-| smaller of them.
-*----------------------------------------------------------------------------*/
-
-float64 float64_min(float64 a, float64 b, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float64_denormal_to_zero(a);
- b = float64_denormal_to_zero(b);
- }
-
- return (float64_compare_two(a, b, status) == float_relation_less) ? a : b;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two double precision floating point numbers and return the
-| larger of them.
-*----------------------------------------------------------------------------*/
-
-float64 float64_max(float64 a, float64 b, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float64_denormal_to_zero(a);
- b = float64_denormal_to_zero(b);
- }
-
- return (float64_compare_two(a, b, status) == float_relation_greater) ? a : b;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two double precision floating point numbers and return the
-| smaller/larger of them. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 float64_minmax(float64 a, float64 b, int is_max, int is_abs, struct float_status_t *status)
-{
- if (get_denormals_are_zeros(status)) {
- a = float64_denormal_to_zero(a);
- b = float64_denormal_to_zero(b);
- }
-
- if (float64_is_nan(a) || float64_is_nan(b)) {
- if (float64_is_signaling_nan(a)) {
- return propagateFloat64NaNOne(a, status);
- }
- if (float64_is_signaling_nan(b)) {
- return propagateFloat64NaNOne(b, status);
- }
- if (! float64_is_nan(b)) {
- if (float64_is_denormal(b))
- float_raise(status, float_flag_denormal);
- return b;
- }
- if (! float64_is_nan(a)) {
- if (float64_is_denormal(a))
- float_raise(status, float_flag_denormal);
- return a;
- }
- return propagateFloat64NaN(a, b, status);
- }
-
- float64 tmp_a = a, tmp_b = b;
- if (is_abs) {
- tmp_a &= ~BX_CONST64(0x8000000000000000); // clear the sign bit
- tmp_b &= ~BX_CONST64(0x8000000000000000);
- }
-
- int aSign = extractFloat64Sign(tmp_a);
- int bSign = extractFloat64Sign(tmp_b);
-
- if (float64_is_denormal(a) || float64_is_denormal(b))
- float_raise(status, float_flag_denormal);
-
- if (aSign != bSign) {
- if (! is_max) {
- return aSign ? a : b;
- } else {
- return aSign ? b : a;
- }
- } else {
- if (! is_max) {
- return (aSign ^ (tmp_a < tmp_b)) ? a : b;
- } else {
- return (aSign ^ (tmp_a < tmp_b)) ? b : a;
- }
- }
-}
-
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 32-bit two's complement integer `a'
-| to the extended double-precision floating-point format. The conversion
-| is performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 int32_to_floatx80(Bit32s a)
-{
- if (a == 0) return packFloatx80(0, 0, 0);
- int zSign = (a < 0);
- Bit32u absA = zSign ? -a : a;
- int shiftCount = countLeadingZeros32(absA) + 32;
- Bit64u zSig = absA;
- return packFloatx80(zSign, 0x403E - shiftCount, zSig< 0x401E) {
- float_raise(status, float_flag_invalid);
- return (Bit32s)(int32_indefinite);
- }
- if (aExp < 0x3FFF) {
- if (aExp || aSig) float_raise(status, float_flag_inexact);
- return 0;
- }
- shiftCount = 0x403E - aExp;
- savedASig = aSig;
- aSig >>= shiftCount;
- z = (Bit32s) aSig;
- if (aSign) z = -z;
- if ((z < 0) ^ aSign) {
- float_raise(status, float_flag_invalid);
- return (Bit32s)(int32_indefinite);
- }
- if ((aSig<>(-shiftCount);
- if ((Bit64u) (aSig<<(shiftCount & 63))) {
- float_raise(status, float_flag_inexact);
- }
- if (aSign) z = -z;
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the single-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 floatx80_to_float32(floatx80 a, struct float_status_t *status)
-{
- Bit64u aSig = extractFloatx80Frac(a);
- Bit32s aExp = extractFloatx80Exp(a);
- int aSign = extractFloatx80Sign(a);
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a))
- {
- float_raise(status, float_flag_invalid);
- return float32_default_nan;
- }
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1))
- return commonNaNToFloat32(floatx80ToCommonNaN(a, status));
-
- return packFloat32(aSign, 0xFF, 0);
- }
- aSig = shift64RightJamming(aSig, 33);
- if (aExp || aSig) aExp -= 0x3F81;
- return roundAndPackFloat32(aSign, aExp, (Bit32u) aSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the double-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float64 floatx80_to_float64(floatx80 a, struct float_status_t *status)
-{
- Bit32s aExp;
- Bit64u aSig, zSig;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a))
- {
- float_raise(status, float_flag_invalid);
- return float64_default_nan;
- }
-
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- int aSign = extractFloatx80Sign(a);
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1)) {
- return commonNaNToFloat64(floatx80ToCommonNaN(a, status));
- }
- return packFloat64(aSign, 0x7FF, 0);
- }
- zSig = shift64RightJamming(aSig, 1);
- if (aExp || aSig) aExp -= 0x3C01;
- return roundAndPackFloat64(aSign, aExp, zSig, status);
-}
-
-/*----------------------------------------------------------------------------
-| Rounds the extended double-precision floating-point value `a' to an integer,
-| and returns the result as an extended double-precision floating-point
-| value. The operation is performed according to the IEC/IEEE Standard for
-| Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_round_to_int(floatx80 a, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- int aSign;
- Bit64u lastBitMask, roundBitsMask;
- int roundingMode = get_float_rounding_mode(status);
- floatx80 z;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a))
- {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- Bit32s aExp = extractFloatx80Exp(a);
- Bit64u aSig = extractFloatx80Frac(a);
- if (0x403E <= aExp) {
- if ((aExp == 0x7FFF) && (Bit64u) (aSig<<1)) {
- return propagateFloatx80NaNOne(a, status);
- }
- return a;
- }
- if (aExp < 0x3FFF) {
- if (aExp == 0) {
- if ((aSig<<1) == 0) return a;
- float_raise(status, float_flag_denormal);
- }
- float_raise(status, float_flag_inexact);
- aSign = extractFloatx80Sign(a);
- switch (roundingMode) {
- case float_round_nearest_even:
- if ((aExp == 0x3FFE) && (Bit64u) (aSig<<1)) {
- set_float_rounding_up(status);
- return packFloatx80(aSign, 0x3FFF, BX_CONST64(0x8000000000000000));
- }
- break;
- case float_round_down:
- if (aSign) {
- set_float_rounding_up(status);
- return packFloatx80(1, 0x3FFF, BX_CONST64(0x8000000000000000));
- }
- else {
- return packFloatx80(0, 0, 0);
- }
- case float_round_up:
- if (aSign) {
- return packFloatx80(1, 0, 0);
- }
- else {
- set_float_rounding_up(status);
- return packFloatx80(0, 0x3FFF, BX_CONST64(0x8000000000000000));
- }
- }
- return packFloatx80(aSign, 0, 0);
- }
- lastBitMask = 1;
- lastBitMask <<= 0x403E - aExp;
- roundBitsMask = lastBitMask - 1;
- z = a;
- if (roundingMode == float_round_nearest_even) {
- z.fraction += lastBitMask>>1;
- if ((z.fraction & roundBitsMask) == 0) z.fraction &= ~lastBitMask;
- }
- else if (roundingMode != float_round_to_zero) {
- if (extractFloatx80Sign(z) ^ (roundingMode == float_round_up))
- z.fraction += roundBitsMask;
- }
- z.fraction &= ~roundBitsMask;
- if (z.fraction == 0) {
- z.exp++;
- z.fraction = BX_CONST64(0x8000000000000000);
- }
- if (z.fraction != a.fraction) {
- float_raise(status, float_flag_inexact);
- if (z.fraction > a.fraction || z.exp > a.exp)
- set_float_rounding_up(status);
- }
- return z;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the extended double-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is
-| negated before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static floatx80 addFloatx80Sigs(floatx80 a, floatx80 b, int zSign, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- Bit32s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig0, zSig1;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
- {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- bSig = extractFloatx80Frac(b);
- bExp = extractFloatx80Exp(b);
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
- return propagateFloatx80NaN(a, b, status);
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return a;
- }
- if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (aExp == 0) {
- if (aSig == 0) {
- if ((bExp == 0) && bSig) {
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
- }
- return roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, bExp, bSig, 0, status);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- if (bSig == 0)
- return roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, aExp, aSig, 0, status);
-
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
- }
- Bit32s expDiff = aExp - bExp;
- zExp = aExp;
- if (0 < expDiff) {
- shift64ExtraRightJamming(bSig, 0, expDiff, &bSig, &zSig1);
- }
- else if (expDiff < 0) {
- shift64ExtraRightJamming(aSig, 0, -expDiff, &aSig, &zSig1);
- zExp = bExp;
- }
- else {
- zSig0 = aSig + bSig;
- zSig1 = 0;
- goto shiftRight1;
- }
- zSig0 = aSig + bSig;
- if ((Bit64s) zSig0 < 0) goto roundAndPack;
- shiftRight1:
- shift64ExtraRightJamming(zSig0, zSig1, 1, &zSig0, &zSig1);
- zSig0 |= BX_CONST64(0x8000000000000000);
- zExp++;
- roundAndPack:
- return
- roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, zExp, zSig0, zSig1, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the extended
-| double-precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static floatx80 subFloatx80Sigs(floatx80 a, floatx80 b, int zSign, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- Bit32s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig0, zSig1;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
- {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- bSig = extractFloatx80Frac(b);
- bExp = extractFloatx80Exp(b);
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1)) return propagateFloatx80NaN(a, b, status);
- if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return a;
- }
- if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloatx80(zSign ^ 1, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (aExp == 0) {
- if (aSig == 0) {
- if (bExp == 0) {
- if (bSig) {
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
- return roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign ^ 1, bExp, bSig, 0, status);
- }
- return packFloatx80(get_float_rounding_mode(status) == float_round_down, 0, 0);
- }
- return roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign ^ 1, bExp, bSig, 0, status);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- if (bSig == 0)
- return roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, aExp, aSig, 0, status);
-
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
- }
- Bit32s expDiff = aExp - bExp;
- if (0 < expDiff) {
- shift128RightJamming(bSig, 0, expDiff, &bSig, &zSig1);
- goto aBigger;
- }
- if (expDiff < 0) {
- shift128RightJamming(aSig, 0, -expDiff, &aSig, &zSig1);
- goto bBigger;
- }
- zSig1 = 0;
- if (bSig < aSig) goto aBigger;
- if (aSig < bSig) goto bBigger;
- return packFloatx80(get_float_rounding_mode(status) == float_round_down, 0, 0);
- bBigger:
- sub128(bSig, 0, aSig, zSig1, &zSig0, &zSig1);
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aBigger:
- sub128(aSig, 0, bSig, zSig1, &zSig0, &zSig1);
- zExp = aExp;
- normalizeRoundAndPack:
- return
- normalizeRoundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, zExp, zSig0, zSig1, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the extended double-precision floating-point
-| values `a' and `b'. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_add(floatx80 a, floatx80 b, struct float_status_t *status)
-{
- int aSign = extractFloatx80Sign(a);
- int bSign = extractFloatx80Sign(b);
-
- if (aSign == bSign)
- return addFloatx80Sigs(a, b, aSign, status);
- else
- return subFloatx80Sigs(a, b, aSign, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the extended double-precision floating-
-| point values `a' and `b'. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_sub(floatx80 a, floatx80 b, struct float_status_t *status)
-{
- int aSign = extractFloatx80Sign(a);
- int bSign = extractFloatx80Sign(b);
-
- if (aSign == bSign)
- return subFloatx80Sigs(a, b, aSign, status);
- else
- return addFloatx80Sigs(a, b, aSign, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the extended double-precision floating-
-| point values `a' and `b'. The operation is performed according to the
-| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_mul(floatx80 a, floatx80 b, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- int aSign, bSign, zSign;
- Bit32s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig0, zSig1;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
- {
- invalid:
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- aSign = extractFloatx80Sign(a);
- bSig = extractFloatx80Frac(b);
- bExp = extractFloatx80Exp(b);
- bSign = extractFloatx80Sign(b);
- zSign = aSign ^ bSign;
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1))) {
- return propagateFloatx80NaN(a, b, status);
- }
- if (bExp == 0) {
- if (bSig == 0) goto invalid;
- float_raise(status, float_flag_denormal);
- }
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- if (aExp == 0) {
- if (aSig == 0) goto invalid;
- float_raise(status, float_flag_denormal);
- }
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (aExp == 0) {
- if (aSig == 0) {
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloatx80(zSign, 0, 0);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- if (bSig == 0) return packFloatx80(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
- }
- zExp = aExp + bExp - 0x3FFE;
- mul64To128(aSig, bSig, &zSig0, &zSig1);
- if (0 < (Bit64s) zSig0) {
- shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
- --zExp;
- }
- return
- roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, zExp, zSig0, zSig1, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the extended double-precision floating-point
-| value `a' by the corresponding value `b'. The operation is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_div(floatx80 a, floatx80 b, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- int aSign, bSign, zSign;
- Bit32s aExp, bExp, zExp;
- Bit64u aSig, bSig, zSig0, zSig1;
- Bit64u rem0, rem1, rem2, term0, term1, term2;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
- {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- aSign = extractFloatx80Sign(a);
- bSig = extractFloatx80Frac(b);
- bExp = extractFloatx80Exp(b);
- bSign = extractFloatx80Sign(b);
-
- zSign = aSign ^ bSign;
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1)) return propagateFloatx80NaN(a, b, status);
- if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- return packFloatx80(zSign, 0, 0);
- }
- if (bExp == 0) {
- if (bSig == 0) {
- if ((aExp | aSig) == 0) {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
- float_raise(status, float_flag_divbyzero);
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
- }
- if (aExp == 0) {
- if (aSig == 0) return packFloatx80(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
- }
- zExp = aExp - bExp + 0x3FFE;
- rem1 = 0;
- if (bSig <= aSig) {
- shift128Right(aSig, 0, 1, &aSig, &rem1);
- ++zExp;
- }
- zSig0 = estimateDiv128To64(aSig, rem1, bSig);
- mul64To128(bSig, zSig0, &term0, &term1);
- sub128(aSig, rem1, term0, term1, &rem0, &rem1);
- while ((Bit64s) rem0 < 0) {
- --zSig0;
- add128(rem0, rem1, 0, bSig, &rem0, &rem1);
- }
- zSig1 = estimateDiv128To64(rem1, 0, bSig);
- if ((Bit64u) (zSig1<<1) <= 8) {
- mul64To128(bSig, zSig1, &term1, &term2);
- sub128(rem1, 0, term1, term2, &rem1, &rem2);
- while ((Bit64s) rem1 < 0) {
- --zSig1;
- add128(rem1, rem2, 0, bSig, &rem1, &rem2);
- }
- zSig1 |= ((rem1 | rem2) != 0);
- }
- return
- roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, zExp, zSig0, zSig1, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the square root of the extended double-precision floating-point
-| value `a'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_sqrt(floatx80 a, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- int aSign;
- Bit32s aExp, zExp;
- Bit64u aSig0, aSig1, zSig0, zSig1, doubleZSig0;
- Bit64u rem0, rem1, rem2, rem3, term0, term1, term2, term3;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a))
- {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- aSig0 = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- aSign = extractFloatx80Sign(a);
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig0<<1)) return propagateFloatx80NaNOne(a, status);
- if (! aSign) return a;
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
- if (aSign) {
- if ((aExp | aSig0) == 0) return a;
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
- if (aExp == 0) {
- if (aSig0 == 0) return packFloatx80(0, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
- }
- zExp = ((aExp - 0x3FFF)>>1) + 0x3FFF;
- zSig0 = estimateSqrt32(aExp, aSig0>>32);
- shift128Right(aSig0, 0, 2 + (aExp & 1), &aSig0, &aSig1);
- zSig0 = estimateDiv128To64(aSig0, aSig1, zSig0<<32) + (zSig0<<30);
- doubleZSig0 = zSig0<<1;
- mul64To128(zSig0, zSig0, &term0, &term1);
- sub128(aSig0, aSig1, term0, term1, &rem0, &rem1);
- while ((Bit64s) rem0 < 0) {
- --zSig0;
- doubleZSig0 -= 2;
- add128(rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1);
- }
- zSig1 = estimateDiv128To64(rem1, 0, doubleZSig0);
- if ((zSig1 & BX_CONST64(0x3FFFFFFFFFFFFFFF)) <= 5) {
- if (zSig1 == 0) zSig1 = 1;
- mul64To128(doubleZSig0, zSig1, &term1, &term2);
- sub128(rem1, 0, term1, term2, &rem1, &rem2);
- mul64To128(zSig1, zSig1, &term2, &term3);
- sub192(rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3);
- while ((Bit64s) rem1 < 0) {
- --zSig1;
- shortShift128Left(0, zSig1, 1, &term2, &term3);
- term3 |= 1;
- term2 |= doubleZSig0;
- add192(rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3);
- }
- zSig1 |= ((rem1 | rem2 | rem3) != 0);
- }
- shortShift128Left(0, zSig1, 1, &zSig0, &zSig1);
- zSig0 |= doubleZSig0;
- return
- roundAndPackFloatx80(get_float_rounding_precision(status),
- 0, zExp, zSig0, zSig1, status);
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the quadruple-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 floatx80_to_float128(floatx80 a, struct float_status_t *status)
-{
- Bit64u zSig0, zSig1;
-
- Bit64u aSig = extractFloatx80Frac(a);
- Bit32s aExp = extractFloatx80Exp(a);
- int aSign = extractFloatx80Sign(a);
-
- if ((aExp == 0x7FFF) && (Bit64u) (aSig<<1))
- return commonNaNToFloat128(floatx80ToCommonNaN(a, status));
-
- shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
- return packFloat128Four(aSign, aExp, zSig0, zSig1);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the quadruple-precision floating-point
-| value `a' to the extended double-precision floating-point format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 float128_to_floatx80(float128 a, struct float_status_t *status)
-{
- Bit32s aExp;
- Bit64u aSig0, aSig1;
-
- aSig1 = extractFloat128Frac1(a);
- aSig0 = extractFloat128Frac0(a);
- aExp = extractFloat128Exp(a);
- int aSign = extractFloat128Sign(a);
-
- if (aExp == 0x7FFF) {
- if (aSig0 | aSig1)
- return commonNaNToFloatx80(float128ToCommonNaN(a, status));
-
- return packFloatx80(aSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
-
- if (aExp == 0) {
- if ((aSig0 | aSig1) == 0) return packFloatx80(aSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat128Subnormal(aSig0, aSig1, &aExp, &aSig0, &aSig1);
- }
- else aSig0 |= BX_CONST64(0x0001000000000000);
-
- shortShift128Left(aSig0, aSig1, 15, &aSig0, &aSig1);
- return roundAndPackFloatx80(80, aSign, aExp, aSig0, aSig1, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the extended double-precision floating-
-| point value `a' and quadruple-precision floating point value `b'. The
-| operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_128_mul(floatx80 a, float128 b, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- Bit32s aExp, bExp, zExp;
- Bit64u aSig, bSig0, bSig1, zSig0, zSig1, zSig2;
- int aSign, bSign, zSign;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a))
- {
- invalid:
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- aSign = extractFloatx80Sign(a);
- bSig0 = extractFloat128Frac0(b);
- bSig1 = extractFloat128Frac1(b);
- bExp = extractFloat128Exp(b);
- bSign = extractFloat128Sign(b);
-
- zSign = aSign ^ bSign;
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1)
- || ((bExp == 0x7FFF) && (bSig0 | bSig1)))
- {
- floatx80 r = commonNaNToFloatx80(float128ToCommonNaN(b, status));
- return propagateFloatx80NaN(a, r, status);
- }
- if (bExp == 0) {
- if ((bSig0 | bSig1) == 0) goto invalid;
- float_raise(status, float_flag_denormal);
- }
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (bExp == 0x7FFF) {
- if (bSig0 | bSig1) {
- floatx80 r = commonNaNToFloatx80(float128ToCommonNaN(b, status));
- return propagateFloatx80NaN(a, r, status);
- }
- if (aExp == 0) {
- if (aSig == 0) goto invalid;
- float_raise(status, float_flag_denormal);
- }
- return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (aExp == 0) {
- if (aSig == 0) {
- if ((bExp == 0) && (bSig0 | bSig1)) float_raise(status, float_flag_denormal);
- return packFloatx80(zSign, 0, 0);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
- }
- if (bExp == 0) {
- if ((bSig0 | bSig1) == 0) return packFloatx80(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat128Subnormal(bSig0, bSig1, &bExp, &bSig0, &bSig1);
- }
- else bSig0 |= BX_CONST64(0x0001000000000000);
-
- zExp = aExp + bExp - 0x3FFE;
- shortShift128Left(bSig0, bSig1, 15, &bSig0, &bSig1);
- mul128By64To192(bSig0, bSig1, aSig, &zSig0, &zSig1, &zSig2);
- if (0 < (Bit64s) zSig0) {
- shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
- --zExp;
- }
- return
- roundAndPackFloatx80(get_float_rounding_precision(status),
- zSign, zExp, zSig0, zSig1, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the absolute values of the quadruple-precision
-| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
-| before being returned. `zSign' is ignored if the result is a NaN.
-| The addition is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float128 addFloat128Sigs(float128 a, float128 b, int zSign, struct float_status_t *status)
-{
- Bit32s aExp, bExp, zExp;
- Bit64u aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
- Bit32s expDiff;
-
- aSig1 = extractFloat128Frac1(a);
- aSig0 = extractFloat128Frac0(a);
- aExp = extractFloat128Exp(a);
- bSig1 = extractFloat128Frac1(b);
- bSig0 = extractFloat128Frac0(b);
- bExp = extractFloat128Exp(b);
- expDiff = aExp - bExp;
-
- if (0 < expDiff) {
- if (aExp == 0x7FFF) {
- if (aSig0 | aSig1) return propagateFloat128NaN(a, b, status);
- return a;
- }
- if (bExp == 0) --expDiff;
- else bSig0 |= BX_CONST64(0x0001000000000000);
- shift128ExtraRightJamming(bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2);
- zExp = aExp;
- }
- else if (expDiff < 0) {
- if (bExp == 0x7FFF) {
- if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status);
- return packFloat128Four(zSign, 0x7FFF, 0, 0);
- }
- if (aExp == 0) ++expDiff;
- else aSig0 |= BX_CONST64(0x0001000000000000);
- shift128ExtraRightJamming(aSig0, aSig1, 0, -expDiff, &aSig0, &aSig1, &zSig2);
- zExp = bExp;
- }
- else {
- if (aExp == 0x7FFF) {
- if (aSig0 | aSig1 | bSig0 | bSig1)
- return propagateFloat128NaN(a, b, status);
-
- return a;
- }
- add128(aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1);
- if (aExp == 0) return packFloat128Four(zSign, 0, zSig0, zSig1);
- zSig2 = 0;
- zSig0 |= BX_CONST64(0x0002000000000000);
- zExp = aExp;
- goto shiftRight1;
- }
- aSig0 |= BX_CONST64(0x0001000000000000);
- add128(aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1);
- --zExp;
- if (zSig0 < BX_CONST64(0x0002000000000000)) goto roundAndPack;
- ++zExp;
- shiftRight1:
- shift128ExtraRightJamming(zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2);
- roundAndPack:
- return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the absolute values of the quadruple-
-| precision floating-point values `a' and `b'. If `zSign' is 1, the
-| difference is negated before being returned. `zSign' is ignored if the
-| result is a NaN. The subtraction is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-static float128 subFloat128Sigs(float128 a, float128 b, int zSign, struct float_status_t *status)
-{
- Bit32s aExp, bExp, zExp;
- Bit64u aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
- Bit32s expDiff;
-
- aSig1 = extractFloat128Frac1(a);
- aSig0 = extractFloat128Frac0(a);
- aExp = extractFloat128Exp(a);
- bSig1 = extractFloat128Frac1(b);
- bSig0 = extractFloat128Frac0(b);
- bExp = extractFloat128Exp(b);
-
- expDiff = aExp - bExp;
- shortShift128Left(aSig0, aSig1, 14, &aSig0, &aSig1);
- shortShift128Left(bSig0, bSig1, 14, &bSig0, &bSig1);
- if (0 < expDiff) goto aExpBigger;
- if (expDiff < 0) goto bExpBigger;
- if (aExp == 0x7FFF) {
- if (aSig0 | aSig1 | bSig0 | bSig1)
- return propagateFloat128NaN(a, b, status);
-
- float_raise(status, float_flag_invalid);
- return float128_default_nan;
- }
- if (aExp == 0) {
- aExp = 1;
- bExp = 1;
- }
- if (bSig0 < aSig0) goto aBigger;
- if (aSig0 < bSig0) goto bBigger;
- if (bSig1 < aSig1) goto aBigger;
- if (aSig1 < bSig1) goto bBigger;
- return packFloat128(0, 0);
-
- bExpBigger:
- if (bExp == 0x7FFF) {
- if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status);
- return packFloat128Four(zSign ^ 1, 0x7FFF, 0, 0);
- }
- if (aExp == 0) ++expDiff;
- else {
- aSig0 |= BX_CONST64(0x4000000000000000);
- }
- shift128RightJamming(aSig0, aSig1, - expDiff, &aSig0, &aSig1);
- bSig0 |= BX_CONST64(0x4000000000000000);
- bBigger:
- sub128(bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1);
- zExp = bExp;
- zSign ^= 1;
- goto normalizeRoundAndPack;
- aExpBigger:
- if (aExp == 0x7FFF) {
- if (aSig0 | aSig1) return propagateFloat128NaN(a, b, status);
- return a;
- }
- if (bExp == 0) --expDiff;
- else {
- bSig0 |= BX_CONST64(0x4000000000000000);
- }
- shift128RightJamming(bSig0, bSig1, expDiff, &bSig0, &bSig1);
- aSig0 |= BX_CONST64(0x4000000000000000);
- aBigger:
- sub128(aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1);
- zExp = aExp;
- normalizeRoundAndPack:
- --zExp;
- return normalizeRoundAndPackFloat128(zSign, zExp - 14, zSig0, zSig1, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of adding the quadruple-precision floating-point values
-| `a' and `b'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_add(float128 a, float128 b, struct float_status_t *status)
-{
- int aSign = extractFloat128Sign(a);
- int bSign = extractFloat128Sign(b);
-
- if (aSign == bSign) {
- return addFloat128Sigs(a, b, aSign, status);
- }
- else {
- return subFloat128Sigs(a, b, aSign, status);
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of subtracting the quadruple-precision floating-point
-| values `a' and `b'. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_sub(float128 a, float128 b, struct float_status_t *status)
-{
- int aSign = extractFloat128Sign(a);
- int bSign = extractFloat128Sign(b);
-
- if (aSign == bSign) {
- return subFloat128Sigs(a, b, aSign, status);
- }
- else {
- return addFloat128Sigs(a, b, aSign, status);
- }
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of multiplying the quadruple-precision floating-point
-| values `a' and `b'. The operation is performed according to the IEC/IEEE
-| Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_mul(float128 a, float128 b, struct float_status_t *status)
-{
- int aSign, bSign, zSign;
- Bit32s aExp, bExp, zExp;
- Bit64u aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
-
- aSig1 = extractFloat128Frac1(a);
- aSig0 = extractFloat128Frac0(a);
- aExp = extractFloat128Exp(a);
- aSign = extractFloat128Sign(a);
- bSig1 = extractFloat128Frac1(b);
- bSig0 = extractFloat128Frac0(b);
- bExp = extractFloat128Exp(b);
- bSign = extractFloat128Sign(b);
-
- zSign = aSign ^ bSign;
- if (aExp == 0x7FFF) {
- if ((aSig0 | aSig1) || ((bExp == 0x7FFF) && (bSig0 | bSig1))) {
- return propagateFloat128NaN(a, b, status);
- }
- if ((bExp | bSig0 | bSig1) == 0) {
- float_raise(status, float_flag_invalid);
- return float128_default_nan;
- }
- return packFloat128Four(zSign, 0x7FFF, 0, 0);
- }
- if (bExp == 0x7FFF) {
- if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status);
- if ((aExp | aSig0 | aSig1) == 0) {
- float_raise(status, float_flag_invalid);
- return float128_default_nan;
- }
- return packFloat128Four(zSign, 0x7FFF, 0, 0);
- }
- if (aExp == 0) {
- if ((aSig0 | aSig1) == 0) return packFloat128Four(zSign, 0, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat128Subnormal(aSig0, aSig1, &aExp, &aSig0, &aSig1);
- }
- if (bExp == 0) {
- if ((bSig0 | bSig1) == 0) return packFloat128Four(zSign, 0, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat128Subnormal(bSig0, bSig1, &bExp, &bSig0, &bSig1);
- }
- zExp = aExp + bExp - 0x4000;
- aSig0 |= BX_CONST64(0x0001000000000000);
- shortShift128Left(bSig0, bSig1, 16, &bSig0, &bSig1);
- mul128To256(aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3);
- add128(zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1);
- zSig2 |= (zSig3 != 0);
- if (BX_CONST64(0x0002000000000000) <= zSig0) {
- shift128ExtraRightJamming(zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2);
- ++zExp;
- }
- return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of dividing the quadruple-precision floating-point value
-| `a' by the corresponding value `b'. The operation is performed according to
-| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 float128_div(float128 a, float128 b, struct float_status_t *status)
-{
- int aSign, bSign, zSign;
- Bit32s aExp, bExp, zExp;
- Bit64u aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
- Bit64u rem0, rem1, rem2, rem3, term0, term1, term2, term3;
-
- aSig1 = extractFloat128Frac1(a);
- aSig0 = extractFloat128Frac0(a);
- aExp = extractFloat128Exp(a);
- aSign = extractFloat128Sign(a);
- bSig1 = extractFloat128Frac1(b);
- bSig0 = extractFloat128Frac0(b);
- bExp = extractFloat128Exp(b);
- bSign = extractFloat128Sign(b);
-
- zSign = aSign ^ bSign;
- if (aExp == 0x7FFF) {
- if (aSig0 | aSig1) return propagateFloat128NaN(a, b, status);
- if (bExp == 0x7FFF) {
- if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status);
- float_raise(status, float_flag_invalid);
- return float128_default_nan;
- }
- return packFloat128Four(zSign, 0x7FFF, 0, 0);
- }
- if (bExp == 0x7FFF) {
- if (bSig0 | bSig1) return propagateFloat128NaN(a, b, status);
- return packFloat128Four(zSign, 0, 0, 0);
- }
- if (bExp == 0) {
- if ((bSig0 | bSig1) == 0) {
- if ((aExp | aSig0 | aSig1) == 0) {
- float_raise(status, float_flag_invalid);
- return float128_default_nan;
- }
- float_raise(status, float_flag_divbyzero);
- return packFloat128Four(zSign, 0x7FFF, 0, 0);
- }
- float_raise(status, float_flag_denormal);
- normalizeFloat128Subnormal(bSig0, bSig1, &bExp, &bSig0, &bSig1);
- }
- if (aExp == 0) {
- if ((aSig0 | aSig1) == 0) return packFloat128Four(zSign, 0, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat128Subnormal(aSig0, aSig1, &aExp, &aSig0, &aSig1);
- }
- zExp = aExp - bExp + 0x3FFD;
- shortShift128Left(
- aSig0 | BX_CONST64(0x0001000000000000), aSig1, 15, &aSig0, &aSig1);
- shortShift128Left(
- bSig0 | BX_CONST64(0x0001000000000000), bSig1, 15, &bSig0, &bSig1);
- if (le128(bSig0, bSig1, aSig0, aSig1)) {
- shift128Right(aSig0, aSig1, 1, &aSig0, &aSig1);
- ++zExp;
- }
- zSig0 = estimateDiv128To64(aSig0, aSig1, bSig0);
- mul128By64To192(bSig0, bSig1, zSig0, &term0, &term1, &term2);
- sub192(aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2);
- while ((Bit64s) rem0 < 0) {
- --zSig0;
- add192(rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2);
- }
- zSig1 = estimateDiv128To64(rem1, rem2, bSig0);
- if ((zSig1 & 0x3FFF) <= 4) {
- mul128By64To192(bSig0, bSig1, zSig1, &term1, &term2, &term3);
- sub192(rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3);
- while ((Bit64s) rem1 < 0) {
- --zSig1;
- add192(rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3);
- }
- zSig1 |= ((rem1 | rem2 | rem3) != 0);
- }
- shift128ExtraRightJamming(zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2);
- return roundAndPackFloat128(zSign, zExp, zSig0, zSig1, zSig2, status);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the 64-bit two's complement integer `a' to
-| the quadruple-precision floating-point format. The conversion is performed
-| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float128 int64_to_float128(Bit64s a)
-{
- Bit64u zSig0, zSig1;
-
- if (a == 0) return packFloat128Four(0, 0, 0, 0);
- int zSign = (a < 0);
- Bit64u absA = zSign ? - a : a;
- Bit8u shiftCount = countLeadingZeros64(absA) + 49;
- Bit32s zExp = 0x406E - shiftCount;
- if (64 <= shiftCount) {
- zSig1 = 0;
- zSig0 = absA;
- shiftCount -= 64;
- }
- else {
- zSig1 = absA;
- zSig0 = 0;
- }
- shortShift128Left(zSig0, zSig1, shiftCount, &zSig0, &zSig1);
- return packFloat128Four(zSign, zExp, zSig0, zSig1);
-}
-
-#endif
diff --git a/src/cpu/softfloat/softfloat.h b/src/cpu/softfloat/softfloat.h
deleted file mode 100644
index 1d1b0f08f..000000000
--- a/src/cpu/softfloat/softfloat.h
+++ /dev/null
@@ -1,488 +0,0 @@
-/*============================================================================
-This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#include "config.h" /* generated by configure script from config.h.in */
-
-#ifndef _SOFTFLOAT_H_
-#define _SOFTFLOAT_H_
-
-#define FLOAT16
-#define FLOATX80
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point types.
-*----------------------------------------------------------------------------*/
-#ifdef FLOAT16
-typedef Bit16u float16;
-#endif
-typedef Bit32u float32;
-typedef Bit64u float64;
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point class.
-*----------------------------------------------------------------------------*/
-typedef enum {
- float_zero,
- float_SNaN,
- float_QNaN,
- float_negative_inf,
- float_positive_inf,
- float_denormal,
- float_normalized
-} float_class_t;
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point NaN operands handling mode.
-*----------------------------------------------------------------------------*/
-enum float_nan_handling_mode_t {
- float_larger_significand_nan = 0, // this mode used by x87 FPU
- float_first_operand_nan = 1 // this mode used by SSE
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point rounding mode.
-*----------------------------------------------------------------------------*/
-enum float_round_t {
- float_round_nearest_even = 0,
- float_round_down = 1,
- float_round_up = 2,
- float_round_to_zero = 3
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point exception flags.
-*----------------------------------------------------------------------------*/
-enum float_exception_flag_t {
- float_flag_invalid = 0x01,
- float_flag_denormal = 0x02,
- float_flag_divbyzero = 0x04,
- float_flag_overflow = 0x08,
- float_flag_underflow = 0x10,
- float_flag_inexact = 0x20
-};
-
-extern const unsigned float_all_exceptions_mask;
-
-#ifdef FLOATX80
-#define RAISE_SW_C1 0x0200
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point ordering relations
-*----------------------------------------------------------------------------*/
-enum {
- float_relation_less = -1,
- float_relation_equal = 0,
- float_relation_greater = 1,
- float_relation_unordered = 2
-};
-
-/*----------------------------------------------------------------------------
-| Options to indicate which negations to perform in float*_muladd()
-| Using these differs from negating an input or output before calling
-| the muladd function in that this means that a NaN doesn't have its
-| sign bit inverted before it is propagated.
-*----------------------------------------------------------------------------*/
-enum {
- float_muladd_negate_c = 1,
- float_muladd_negate_product = 2,
- float_muladd_negate_result = float_muladd_negate_c | float_muladd_negate_product
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point status structure.
-*----------------------------------------------------------------------------*/
-struct float_status_t
-{
-#ifdef FLOATX80
- int float_rounding_precision; /* floatx80 only */
-#endif
- int float_rounding_mode;
- int float_exception_flags;
- int float_exception_masks;
- int float_suppress_exception;
- int float_nan_handling_mode; /* flag register */
- int flush_underflow_to_zero; /* flag register */
- int denormals_are_zeros; /* flag register */
-};
-
-/*----------------------------------------------------------------------------
-| Routine to raise any or all of the software IEC/IEEE floating-point
-| exception flags.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE void float_raise(struct float_status_t *status, int flags)
-{
- status->float_exception_flags |= flags;
-}
-
-/*----------------------------------------------------------------------------
-| Returns raised IEC/IEEE floating-point exception flags.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int get_exception_flags(const struct float_status_t *status)
-{
- return status->float_exception_flags & ~status->float_suppress_exception;
-}
-
-/*----------------------------------------------------------------------------
-| Routine to check if any or all of the software IEC/IEEE floating-point
-| exceptions are masked.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int float_exception_masked(const struct float_status_t *status, int flag)
-{
- return status->float_exception_masks & flag;
-}
-
-/*----------------------------------------------------------------------------
-| Returns current floating point rounding mode specified by status word.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int get_float_rounding_mode(const struct float_status_t *status)
-{
- return status->float_rounding_mode;
-}
-
-/*----------------------------------------------------------------------------
-| Returns current floating point precision (floatx80 only).
-*----------------------------------------------------------------------------*/
-
-#ifdef FLOATX80
-BX_CPP_INLINE int get_float_rounding_precision(const struct float_status_t *status)
-{
- return status->float_rounding_precision;
-}
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns current floating point NaN operands handling mode specified
-| by status word.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int get_float_nan_handling_mode(const struct float_status_t *status)
-{
- return status->float_nan_handling_mode;
-}
-
-/*----------------------------------------------------------------------------
-| Raise floating point precision lost up flag (floatx80 only).
-*----------------------------------------------------------------------------*/
-
-#ifdef FLOATX80
-BX_CPP_INLINE void set_float_rounding_up(struct float_status_t *status)
-{
- status->float_exception_flags |= RAISE_SW_C1;
-}
-#endif
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the feature is supported;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int get_denormals_are_zeros(const struct float_status_t *status)
-{
- return status->denormals_are_zeros;
-}
-
-/*----------------------------------------------------------------------------
-| Returns 1 if the feature is supported;
-| otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-BX_CPP_INLINE int get_flush_underflow_to_zero(const struct float_status_t *status)
-{
- return status->flush_underflow_to_zero;
-}
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE integer-to-floating-point conversion routines.
-*----------------------------------------------------------------------------*/
-float32 int32_to_float32(Bit32s, struct float_status_t *status);
-float64 int32_to_float64(Bit32s);
-float32 int64_to_float32(Bit64s, struct float_status_t *status);
-float64 int64_to_float64(Bit64s, struct float_status_t *status);
-
-float32 uint32_to_float32(Bit32u, struct float_status_t *status);
-float64 uint32_to_float64(Bit32u);
-float32 uint64_to_float32(Bit64u, struct float_status_t *status);
-float64 uint64_to_float64(Bit64u, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision conversion routines.
-*----------------------------------------------------------------------------*/
-Bit32s float32_to_int32(float32, struct float_status_t *status);
-Bit32s float32_to_int32_round_to_zero(float32, struct float_status_t *status);
-Bit64s float32_to_int64(float32, struct float_status_t *status);
-Bit64s float32_to_int64_round_to_zero(float32, struct float_status_t *status);
-Bit32u float32_to_uint32(float32, struct float_status_t *status);
-Bit32u float32_to_uint32_round_to_zero(float32, struct float_status_t *status);
-Bit64u float32_to_uint64(float32, struct float_status_t *status);
-Bit64u float32_to_uint64_round_to_zero(float32, struct float_status_t *status);
-float64 float32_to_float64(float32, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision operations.
-*----------------------------------------------------------------------------*/
-float32 float32_round_to_int(float32, Bit8u scale, struct float_status_t *status);
-float32 float32_add(float32, float32, struct float_status_t *status);
-float32 float32_sub(float32, float32, struct float_status_t *status);
-float32 float32_mul(float32, float32, struct float_status_t *status);
-float32 float32_div(float32, float32, struct float_status_t *status);
-float32 float32_sqrt(float32, struct float_status_t *status);
-float32 float32_frc(float32, struct float_status_t *status);
-float32 float32_muladd(float32, float32, float32, int flags, struct float_status_t *status);
-float32 float32_scalef(float32, float32, struct float_status_t *status);
-int float32_compare(float32, float32, int quiet, struct float_status_t *status);
-
-BX_CPP_INLINE float32 float32_round_to_int_one(float32 a, struct float_status_t *status)
-{
- return float32_round_to_int(a, 0, status);
-}
-
-BX_CPP_INLINE float32 float32_fmadd(float32 a, float32 b, float32 c, struct float_status_t *status)
-{
- return float32_muladd(a, b, c, 0, status);
-}
-
-BX_CPP_INLINE float32 float32_fmsub(float32 a, float32 b, float32 c, struct float_status_t *status)
-{
- return float32_muladd(a, b, c, float_muladd_negate_c, status);
-}
-
-BX_CPP_INLINE float32 float32_fnmadd(float32 a, float32 b, float32 c, struct float_status_t *status)
-{
- return float32_muladd(a, b, c, float_muladd_negate_product, status);
-}
-
-BX_CPP_INLINE float32 float32_fnmsub(float32 a, float32 b, float32 c, struct float_status_t *status)
-{
- return float32_muladd(a, b, c, float_muladd_negate_result, status);
-}
-
-BX_CPP_INLINE int float32_compare_two(float32 a, float32 b, struct float_status_t *status)
-{
- return float32_compare(a, b, 0, status);
-}
-
-BX_CPP_INLINE int float32_compare_quiet(float32 a, float32 b, struct float_status_t *status)
-{
- return float32_compare(a, b, 1, status);
-}
-
-float_class_t float32_class(float32);
-
-float32 float32_min(float32 a, float32 b, struct float_status_t *status);
-float32 float32_max(float32 a, float32 b, struct float_status_t *status);
-
-float32 float32_minmax(float32 a, float32 b, int is_max, int is_abs, struct float_status_t *status);
-float32 float32_getexp(float32 a, struct float_status_t *status);
-float32 float32_getmant(float32 a, struct float_status_t *status, int sign_ctrl, int interv);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-Bit32s float64_to_int32(float64, struct float_status_t *status);
-Bit32s float64_to_int32_round_to_zero(float64, struct float_status_t *status);
-Bit64s float64_to_int64(float64, struct float_status_t *status);
-Bit64s float64_to_int64_round_to_zero(float64, struct float_status_t *status);
-Bit32u float64_to_uint32(float64, struct float_status_t *status);
-Bit32u float64_to_uint32_round_to_zero(float64, struct float_status_t *status);
-Bit64u float64_to_uint64(float64, struct float_status_t *status);
-Bit64u float64_to_uint64_round_to_zero(float64, struct float_status_t *status);
-float32 float64_to_float32(float64, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision operations.
-*----------------------------------------------------------------------------*/
-float64 float64_round_to_int(float64, Bit8u scale, struct float_status_t *status);
-float64 float64_add(float64, float64, struct float_status_t *status);
-float64 float64_sub(float64, float64, struct float_status_t *status);
-float64 float64_mul(float64, float64, struct float_status_t *status);
-float64 float64_div(float64, float64, struct float_status_t *status);
-float64 float64_sqrt(float64, struct float_status_t *status);
-float64 float64_frc(float64, struct float_status_t *status);
-float64 float64_muladd(float64, float64, float64, int flags, struct float_status_t *status);
-float64 float64_scalef(float64, float64, struct float_status_t *status);
-int float64_compare(float64, float64, int quiet, struct float_status_t *status);
-
-BX_CPP_INLINE float64 float64_round_to_int_one(float64 a, struct float_status_t *status)
-{
- return float64_round_to_int(a, 0, status);
-}
-
-BX_CPP_INLINE float64 float64_fmadd(float64 a, float64 b, float64 c, struct float_status_t *status)
-{
- return float64_muladd(a, b, c, 0, status);
-}
-
-BX_CPP_INLINE float64 float64_fmsub(float64 a, float64 b, float64 c, struct float_status_t *status)
-{
- return float64_muladd(a, b, c, float_muladd_negate_c, status);
-}
-
-BX_CPP_INLINE float64 float64_fnmadd(float64 a, float64 b, float64 c, struct float_status_t *status)
-{
- return float64_muladd(a, b, c, float_muladd_negate_product, status);
-}
-
-BX_CPP_INLINE float64 float64_fnmsub(float64 a, float64 b, float64 c, struct float_status_t *status)
-{
- return float64_muladd(a, b, c, float_muladd_negate_result, status);
-}
-
-BX_CPP_INLINE int float64_compare_two(float64 a, float64 b, struct float_status_t *status)
-{
- return float64_compare(a, b, 0, status);
-}
-
-BX_CPP_INLINE int float64_compare_quiet(float64 a, float64 b, struct float_status_t *status)
-{
- return float64_compare(a, b, 1, status);
-}
-
-float_class_t float64_class(float64);
-
-float64 float64_min(float64 a, float64 b, struct float_status_t *status);
-float64 float64_max(float64 a, float64 b, struct float_status_t *status);
-
-float64 float64_minmax(float64 a, float64 b, int is_max, int is_abs, struct float_status_t *status);
-float64 float64_getexp(float64 a, struct float_status_t *status);
-float64 float64_getmant(float64 a, struct float_status_t *status, int sign_ctrl, int interv);
-
-#ifdef FLOAT16
-float32 float16_to_float32(float16, struct float_status_t *status);
-float16 float32_to_float16(float32, struct float_status_t *status);
-
-float_class_t float16_class(float16);
-#endif
-
-#ifdef FLOATX80
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point types.
-*----------------------------------------------------------------------------*/
-
-#ifdef BX_BIG_ENDIAN
-typedef struct floatx80 { // leave alignment to compiler
- Bit16u exp;
- Bit64u fraction;
-}; floatx80
-#else
-typedef struct floatx80 {
- Bit64u fraction;
- Bit16u exp;
-} floatx80;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE integer-to-floating-point conversion routines.
-*----------------------------------------------------------------------------*/
-floatx80 int32_to_floatx80(Bit32s);
-floatx80 int64_to_floatx80(Bit64s);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-floatx80 float32_to_floatx80(float32, struct float_status_t *status);
-floatx80 float64_to_floatx80(float64, struct float_status_t *status);
-
-Bit32s floatx80_to_int32(floatx80, struct float_status_t *status);
-Bit32s floatx80_to_int32_round_to_zero(floatx80, struct float_status_t *status);
-Bit64s floatx80_to_int64(floatx80, struct float_status_t *status);
-Bit64s floatx80_to_int64_round_to_zero(floatx80, struct float_status_t *status);
-
-float32 floatx80_to_float32(floatx80, struct float_status_t *status);
-float64 floatx80_to_float64(floatx80, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision operations.
-*----------------------------------------------------------------------------*/
-floatx80 floatx80_round_to_int(floatx80, struct float_status_t *status);
-floatx80 floatx80_add(floatx80, floatx80, struct float_status_t *status);
-floatx80 floatx80_sub(floatx80, floatx80, struct float_status_t *status);
-floatx80 floatx80_mul(floatx80, floatx80, struct float_status_t *status);
-floatx80 floatx80_div(floatx80, floatx80, struct float_status_t *status);
-floatx80 floatx80_sqrt(floatx80, struct float_status_t *status);
-
-float_class_t floatx80_class(floatx80);
-#ifdef __cplusplus
-}
-#endif
-#endif /* FLOATX80 */
-
-#ifdef FLOAT128
-
-#ifdef BX_BIG_ENDIAN
-typedef struct float128 {
- Bit64u hi, lo;
-} float128;
-#else
-typedef struct float128 {
- Bit64u lo, hi;
-} float128;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE quadruple-precision conversion routines.
-*----------------------------------------------------------------------------*/
-float128 floatx80_to_float128(floatx80 a, struct float_status_t *status);
-floatx80 float128_to_floatx80(float128 a, struct float_status_t *status);
-
-float128 int64_to_float128(Bit64s a);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision operations.
-*----------------------------------------------------------------------------*/
-floatx80 floatx80_128_mul(floatx80 a, float128 b, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE quadruple-precision operations.
-*----------------------------------------------------------------------------*/
-float128 float128_add(float128 a, float128 b, struct float_status_t *status);
-float128 float128_sub(float128 a, float128 b, struct float_status_t *status);
-float128 float128_mul(float128 a, float128 b, struct float_status_t *status);
-float128 float128_div(float128 a, float128 b, struct float_status_t *status);
-#ifdef __cplusplus
-}
-#endif
-#endif /* FLOAT128 */
-
-#endif
diff --git a/src/cpu/softfloat/softfloat16.cc b/src/cpu/softfloat/softfloat16.cc
deleted file mode 100644
index 8c17d3a86..000000000
--- a/src/cpu/softfloat/softfloat16.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-/*============================================================================
-This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * Adapted for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#include "softfloat.h"
-
-#ifdef FLOAT16
-
-#include "softfloat-round-pack.h"
-#include "softfloat-specialize.h"
-#include "softfloat-macros.h"
-
-/*----------------------------------------------------------------------------
-| Determine half-precision floating-point number class
-*----------------------------------------------------------------------------*/
-
-float_class_t float16_class(float16 a)
-{
- Bit16s aExp = extractFloat16Exp(a);
- Bit16u aSig = extractFloat16Frac(a);
- int aSign = extractFloat16Sign(a);
-
- if(aExp == 0x1F) {
- if (aSig == 0)
- return (aSign) ? float_negative_inf : float_positive_inf;
-
- return (aSig & 0x200) ? float_QNaN : float_SNaN;
- }
-
- if(aExp == 0) {
- if (aSig == 0) return float_zero;
- return float_denormal;
- }
-
- return float_normalized;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the half-precision floating-point value
-| `a' to the single-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float32 float16_to_float32(float16 a, struct float_status_t *status)
-{
- Bit16u aSig = extractFloat16Frac(a);
- Bit16s aExp = extractFloat16Exp(a);
- int aSign = extractFloat16Sign(a);
-
- if (aExp == 0x1F) {
- if (aSig) return commonNaNToFloat32(float16ToCommonNaN(a, status));
- return packFloat32(aSign, 0xFF, 0);
- }
- if (aExp == 0) {
- // ignore denormals_are_zeros flag
- if (aSig == 0) return packFloat32(aSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloat16Subnormal(aSig, &aExp, &aSig);
- --aExp;
- }
-
- return packFloat32(aSign, aExp + 0x70, ((Bit32u) aSig)<<13);
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the single-precision floating-point value
-| `a' to the half-precision floating-point format. The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic.
-*----------------------------------------------------------------------------*/
-
-float16 float32_to_float16(float32 a, struct float_status_t *status)
-{
- Bit32u aSig = extractFloat32Frac(a);
- Bit16s aExp = extractFloat32Exp(a);
- int aSign = extractFloat32Sign(a);
-
- if (aExp == 0xFF) {
- if (aSig) return commonNaNToFloat16(float32ToCommonNaN(a, status));
- return packFloat16(aSign, 0x1F, 0);
- }
- if (aExp == 0) {
- if (get_denormals_are_zeros(status)) aSig = 0;
- if (aSig == 0) return packFloat16(aSign, 0, 0);
- float_raise(status, float_flag_denormal);
- }
-
- aSig = shift32RightJamming(aSig, 9);
- Bit16u zSig = (Bit16u) aSig;
- if (aExp || zSig) {
- zSig |= 0x4000;
- aExp -= 0x71;
- }
-
- return roundAndPackFloat16(aSign, aExp, zSig, status);
-}
-
-#endif
diff --git a/src/cpu/softfloat/softfloatx80.cc b/src/cpu/softfloat/softfloatx80.cc
deleted file mode 100644
index fc2409601..000000000
--- a/src/cpu/softfloat/softfloatx80.cc
+++ /dev/null
@@ -1,384 +0,0 @@
-/*============================================================================
-This source file is an extension to the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
-floating point emulation.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * Written for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#include
-#include
-#include <86box/86box.h>
-#include "../cpu.h"
-
-#include "softfloatx80.h"
-#include "softfloat-round-pack.h"
-#include "softfloat-macros.h"
-
-const floatx80 Const_QNaN = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-const floatx80 Const_Z = packFloatx80(0, 0x0000, 0);
-const floatx80 Const_1 = packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000));
-const floatx80 Const_L2T = packFloatx80(0, 0x4000, BX_CONST64(0xd49a784bcd1b8afe));
-const floatx80 Const_L2E = packFloatx80(0, 0x3fff, BX_CONST64(0xb8aa3b295c17f0bc));
-const floatx80 Const_PI = packFloatx80(0, 0x4000, BX_CONST64(0xc90fdaa22168c235));
-const floatx80 Const_LG2 = packFloatx80(0, 0x3ffd, BX_CONST64(0x9a209a84fbcff799));
-const floatx80 Const_LN2 = packFloatx80(0, 0x3ffe, BX_CONST64(0xb17217f7d1cf79ac));
-const floatx80 Const_INF = packFloatx80(0, 0x7fff, BX_CONST64(0x8000000000000000));
-
-/*----------------------------------------------------------------------------
-| Commonly used single-precision floating point constants
-*----------------------------------------------------------------------------*/
-const float32 float32_negative_inf = 0xff800000;
-const float32 float32_positive_inf = 0x7f800000;
-const float32 float32_negative_zero = 0x80000000;
-const float32 float32_positive_zero = 0x00000000;
-const float32 float32_negative_one = 0xbf800000;
-const float32 float32_positive_one = 0x3f800000;
-const float32 float32_max_float = 0x7f7fffff;
-const float32 float32_min_float = 0xff7fffff;
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated single-precision NaN.
-*----------------------------------------------------------------------------*/
-const float32 float32_default_nan = 0xffc00000;
-
-/*----------------------------------------------------------------------------
-| Commonly used single-precision floating point constants
-*----------------------------------------------------------------------------*/
-const float64 float64_negative_inf = BX_CONST64(0xfff0000000000000);
-const float64 float64_positive_inf = BX_CONST64(0x7ff0000000000000);
-const float64 float64_negative_zero = BX_CONST64(0x8000000000000000);
-const float64 float64_positive_zero = BX_CONST64(0x0000000000000000);
-const float64 float64_negative_one = BX_CONST64(0xbff0000000000000);
-const float64 float64_positive_one = BX_CONST64(0x3ff0000000000000);
-const float64 float64_max_float = BX_CONST64(0x7fefffffffffffff);
-const float64 float64_min_float = BX_CONST64(0xffefffffffffffff);
-
-/*----------------------------------------------------------------------------
-| The pattern for a default generated double-precision NaN.
-*----------------------------------------------------------------------------*/
-const float64 float64_default_nan = BX_CONST64(0xFFF8000000000000);
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the 16-bit two's complement integer format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic - which means in particular that the conversion
-| is rounded according to the current rounding mode. If `a' is a NaN or the
-| conversion overflows, the integer indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit16s floatx80_to_int16(floatx80 a, struct float_status_t *status)
-{
- if (floatx80_is_unsupported(a)) {
- float_raise(status, float_flag_invalid);
- return int16_indefinite;
- }
-
- Bit32s v32 = floatx80_to_int32(a, status);
-
- if ((v32 > 32767) || (v32 < -32768)) {
- status->float_exception_flags = float_flag_invalid; // throw away other flags
- return int16_indefinite;
- }
-
- return (Bit16s) v32;
-}
-
-/*----------------------------------------------------------------------------
-| Returns the result of converting the extended double-precision floating-
-| point value `a' to the 16-bit two's complement integer format. The
-| conversion is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic, except that the conversion is always rounded
-| toward zero. If `a' is a NaN or the conversion overflows, the integer
-| indefinite value is returned.
-*----------------------------------------------------------------------------*/
-
-Bit16s floatx80_to_int16_round_to_zero(floatx80 a, struct float_status_t *status)
-{
- if (floatx80_is_unsupported(a)) {
- float_raise(status, float_flag_invalid);
- return int16_indefinite;
- }
-
- Bit32s v32 = floatx80_to_int32_round_to_zero(a, status);
-
- if ((v32 > 32767) || (v32 < -32768)) {
- status->float_exception_flags = float_flag_invalid; // throw away other flags
- return int16_indefinite;
- }
-
- return (Bit16s) v32;
-}
-
-/*----------------------------------------------------------------------------
-| Separate the source extended double-precision floating point value `a'
-| into its exponent and significand, store the significant back to the
-| 'a' and return the exponent. The operation performed is a superset of
-| the IEC/IEEE recommended logb(x) function.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_extract(floatx80 *a, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- Bit64u aSig = extractFloatx80Frac(*a);
- Bit32s aExp = extractFloatx80Exp(*a);
- int aSign = extractFloatx80Sign(*a);
-
- if (floatx80_is_unsupported(*a))
- {
- float_raise(status, float_flag_invalid);
- *a = floatx80_default_nan;
- return *a;
- }
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1))
- {
- *a = propagateFloatx80NaNOne(*a, status);
- return *a;
- }
- return packFloatx80(0, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (aExp == 0)
- {
- if (aSig == 0) {
- float_raise(status, float_flag_divbyzero);
- *a = packFloatx80(aSign, 0, 0);
- return packFloatx80(1, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
- }
-
- a->exp = (aSign << 15) + 0x3FFF;
- a->fraction = aSig;
- return int32_to_floatx80(aExp - 0x3FFF);
-}
-
-/*----------------------------------------------------------------------------
-| Scales extended double-precision floating-point value in operand `a' by
-| value `b'. The function truncates the value in the second operand 'b' to
-| an integral value and adds that value to the exponent of the operand 'a'.
-| The operation performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_scale(floatx80 a, floatx80 b, struct float_status_t *status)
-{
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
-
- Bit32s aExp, bExp;
- Bit64u aSig, bSig;
-
- // handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
- {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
-
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- int aSign = extractFloatx80Sign(a);
- bSig = extractFloatx80Frac(b);
- bExp = extractFloatx80Exp(b);
- int bSign = extractFloatx80Sign(b);
-
- if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
- {
- return propagateFloatx80NaN(a, b, status);
- }
- if ((bExp == 0x7FFF) && bSign) {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- return a;
- }
- if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- if ((aExp | aSig) == 0) {
- if (! bSign) {
- float_raise(status, float_flag_invalid);
- return floatx80_default_nan;
- }
- return a;
- }
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
- if (bSign) return packFloatx80(aSign, 0, 0);
- return packFloatx80(aSign, 0x7FFF, BX_CONST64(0x8000000000000000));
- }
- if (aExp == 0) {
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
- if (aSig == 0) return a;
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
- if (bExp < 0x3FFF)
- return normalizeRoundAndPackFloatx80(80, aSign, aExp, aSig, 0, status);
- }
- if (bExp == 0) {
- if (bSig == 0) return a;
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
- }
-
- if (bExp > 0x400E) {
- /* generate appropriate overflow/underflow */
- return roundAndPackFloatx80(80, aSign,
- bSign ? -0x3FFF : 0x7FFF, aSig, 0, status);
- }
-
- if (bExp < 0x3FFF) return a;
-
- int shiftCount = 0x403E - bExp;
- bSig >>= shiftCount;
- Bit32s scale = (Bit32s) bSig;
- if (bSign) scale = -scale; /* -32768..32767 */
- return
- roundAndPackFloatx80(80, aSign, aExp+scale, aSig, 0, status);
-}
-
-/*----------------------------------------------------------------------------
-| Determine extended-precision floating-point number class.
-*----------------------------------------------------------------------------*/
-
-float_class_t floatx80_class(floatx80 a)
-{
- Bit32s aExp = extractFloatx80Exp(a);
- Bit64u aSig = extractFloatx80Frac(a);
-
- if(aExp == 0) {
- if (aSig == 0)
- return float_zero;
-
- /* denormal or pseudo-denormal */
- return float_denormal;
- }
-
- /* valid numbers have the MS bit set */
- if (!(aSig & BX_CONST64(0x8000000000000000)))
- return float_SNaN; /* report unsupported as SNaNs */
-
- if(aExp == 0x7fff) {
- int aSign = extractFloatx80Sign(a);
-
- if (((Bit64u) (aSig<< 1)) == 0)
- return (aSign) ? float_negative_inf : float_positive_inf;
-
- return (aSig & BX_CONST64(0x4000000000000000)) ? float_QNaN : float_SNaN;
- }
-
- return float_normalized;
-}
-
-/*----------------------------------------------------------------------------
-| Compare between two extended precision floating point numbers. Returns
-| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
-| the value 'a' is less than the corresponding value `b',
-| 'float_relation_greater' if the value 'a' is greater than the corresponding
-| value `b', or 'float_relation_unordered' otherwise.
-*----------------------------------------------------------------------------*/
-
-int floatx80_compare(floatx80 a, floatx80 b, int quiet, struct float_status_t *status)
-{
- float_class_t aClass = floatx80_class(a);
- float_class_t bClass = floatx80_class(b);
-
- if (fpu_type < FPU_287XL) {
- if ((aClass == float_positive_inf) && (bClass == float_negative_inf))
- {
- return float_relation_equal;
- }
-
- if ((aClass == float_negative_inf) && (bClass == float_positive_inf))
- {
- return float_relation_equal;
- }
- }
-
- if (aClass == float_SNaN || bClass == float_SNaN)
- {
- /* unsupported reported as SNaN */
- float_raise(status, float_flag_invalid);
- return float_relation_unordered;
- }
-
- if (aClass == float_QNaN || bClass == float_QNaN) {
- if (! quiet) float_raise(status, float_flag_invalid);
- return float_relation_unordered;
- }
-
- if (aClass == float_denormal || bClass == float_denormal) {
- float_raise(status, float_flag_denormal);
- }
-
- int aSign = extractFloatx80Sign(a);
- int bSign = extractFloatx80Sign(b);
-
- if (aClass == float_zero) {
- if (bClass == float_zero) return float_relation_equal;
- return bSign ? float_relation_greater : float_relation_less;
- }
-
- if (bClass == float_zero || aSign != bSign) {
- return aSign ? float_relation_less : float_relation_greater;
- }
-
- Bit64u aSig = extractFloatx80Frac(a);
- Bit32s aExp = extractFloatx80Exp(a);
- Bit64u bSig = extractFloatx80Frac(b);
- Bit32s bExp = extractFloatx80Exp(b);
-
- if (aClass == float_denormal)
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
-
- if (bClass == float_denormal)
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
-
- if (aExp == bExp && aSig == bSig)
- return float_relation_equal;
-
- int less_than =
- aSign ? ((bExp < aExp) || ((bExp == aExp) && (bSig < aSig)))
- : ((aExp < bExp) || ((aExp == bExp) && (aSig < bSig)));
-
- if (less_than) return float_relation_less;
- return float_relation_greater;
-}
-
-
-int floatx80_compare_two(floatx80 a, floatx80 b, struct float_status_t *status)
-{
- return floatx80_compare(a, b, 0, status);
-}
-
-int floatx80_compare_quiet(floatx80 a, floatx80 b, struct float_status_t *status)
-{
- return floatx80_compare(a, b, 1, status);
-}
diff --git a/src/cpu/softfloat/softfloatx80.h b/src/cpu/softfloat/softfloatx80.h
deleted file mode 100644
index 1f96141b4..000000000
--- a/src/cpu/softfloat/softfloatx80.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*============================================================================
-This source file is an extension to the SoftFloat IEC/IEEE Floating-point
-Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
-floating point emulation.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-=============================================================================*/
-
-/*============================================================================
- * Written for Bochs (x86 achitecture simulator) by
- * Stanislav Shwartsman [sshwarts at sourceforge net]
- * ==========================================================================*/
-
-#ifndef _SOFTFLOATX80_EXTENSIONS_H_
-#define _SOFTFLOATX80_EXTENSIONS_H_
-
-#include "softfloat.h"
-#include "softfloat-specialize.h"
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE integer-to-floating-point conversion routines.
-*----------------------------------------------------------------------------*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-Bit16s floatx80_to_int16(floatx80, struct float_status_t *status);
-Bit16s floatx80_to_int16_round_to_zero(floatx80, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision operations.
-*----------------------------------------------------------------------------*/
-
-floatx80 floatx80_extract(floatx80 *a, struct float_status_t *status);
-floatx80 floatx80_scale(floatx80 a, floatx80 b, struct float_status_t *status);
-int floatx80_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, struct float_status_t *status);
-int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, struct float_status_t *status);
-floatx80 f2xm1(floatx80 a, struct float_status_t *status);
-floatx80 fyl2x(floatx80 a, floatx80 b, struct float_status_t *status);
-floatx80 fyl2xp1(floatx80 a, floatx80 b, struct float_status_t *status);
-floatx80 fpatan(floatx80 a, floatx80 b, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision trigonometric functions.
-*----------------------------------------------------------------------------*/
-
-int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t *status);
-int fsin(floatx80 *a, struct float_status_t *status);
-int fcos(floatx80 *a, struct float_status_t *status);
-int ftan(floatx80 *a, struct float_status_t *status);
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision compare.
-*----------------------------------------------------------------------------*/
-
-int floatx80_compare(floatx80, floatx80, int quiet, struct float_status_t *status);
-int floatx80_compare_two(floatx80 a, floatx80 b, struct float_status_t *status);
-int floatx80_compare_quiet(floatx80 a, floatx80 b, struct float_status_t *status);
-
-#ifdef __cplusplus
-}
-#endif
-
-/*-----------------------------------------------------------------------------
-| Calculates the absolute value of the extended double-precision floating-point
-| value `a'. The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-#ifdef __cplusplus
-BX_CPP_INLINE floatx80& floatx80_abs(floatx80 ®)
-#else
-BX_CPP_INLINE floatx80 floatx80_abs(floatx80 reg)
-#endif
-{
- reg.exp &= 0x7FFF;
- return reg;
-}
-
-/*-----------------------------------------------------------------------------
-| Changes the sign of the extended double-precision floating-point value 'a'.
-| The operation is performed according to the IEC/IEEE Standard for Binary
-| Floating-Point Arithmetic.
-*----------------------------------------------------------------------------*/
-
-#ifdef __cplusplus
-BX_CPP_INLINE floatx80& floatx80_chs(floatx80 ®)
-#else
-BX_CPP_INLINE floatx80 floatx80_chs(floatx80 reg)
-#endif
-{
- reg.exp ^= 0x8000;
- return reg;
-}
-
-/*-----------------------------------------------------------------------------
-| Commonly used extended double-precision floating-point constants.
-*----------------------------------------------------------------------------*/
-
-extern const floatx80 Const_Z;
-extern const floatx80 Const_1;
-extern const floatx80 Const_L2T;
-extern const floatx80 Const_L2E;
-extern const floatx80 Const_PI;
-extern const floatx80 Const_LG2;
-extern const floatx80 Const_LN2;
-extern const floatx80 Const_INF;
-#endif
diff --git a/src/cpu/softfloat3e/CMakeLists.txt b/src/cpu/softfloat3e/CMakeLists.txt
new file mode 100644
index 000000000..5565460c8
--- /dev/null
+++ b/src/cpu/softfloat3e/CMakeLists.txt
@@ -0,0 +1,56 @@
+#
+# 86Box A hypervisor and IBM PC system emulator that specializes in
+# running old operating systems and software designed for IBM
+# PC systems and compatibles from 1981 through fairly recent
+# system designs based on the PCI bus.
+#
+# This file is part of the 86Box distribution.
+#
+# CMake build script.
+#
+# Authors: David Hrdlička,
+#
+# Copyright 2020-2021 David Hrdlička.
+#
+
+add_library(softfloat3e OBJECT extF80_addsub.cc extF80_class.cc extF80_compare.cc
+ extF80_div.cc extF80_extract.cc extF80_mul.cc extF80_rem.cc extF80_roundToInt.cc
+ extF80_scale.cc extF80_sqrt.cc extF80_to_f16.cc extF80_to_f32.cc extF80_to_f64.cc
+ extF80_to_f128.cc extF80_to_i32.cc extF80_to_i32_r_minMag.cc extF80_to_i64.cc
+ extF80_to_i64_r_minMag.cc extF80_to_ui32.cc extF80_to_ui32_r_minMag.cc extF80_to_ui64.cc
+ extF80_to_ui64_r_minMag.cc f16_addsub.c f16_class.c f16_compare.c f16_div.c f16_getExp.c
+ f16_getMant.c f16_minmax.c f16_mul.c f16_mulAdd.c f16_range.c f16_roundToInt.c
+ f16_sqrt.c f16_to_extF80.cc f16_to_f32.c f16_to_f64.c f16_to_i32.c f16_to_i32_r_minMag.c
+ f16_to_i64.c f16_to_i64_r_minMag.c f16_to_ui32.c f16_to_ui32_r_minMag.c f16_to_ui64.c
+ f16_to_ui64_r_minMag.c f32_addsub.c f32_class.c f32_compare.c f32_div.c f32_frc.c
+ f32_getExp.c f32_getMant.c f32_minmax.c f32_mul.c f32_mulAdd.c f32_range.c
+ f32_roundToInt.c f32_scalef.c f32_sqrt.c f32_to_extF80.cc f32_to_f16.c f32_to_f64.c
+ f32_to_f128.cc f32_to_i32.c f32_to_i32_r_minMag.c f32_to_i64.c f32_to_i64_r_minMag.c
+ f32_to_ui32.c f32_to_ui32_r_minMag.c f32_to_ui64.c f32_to_ui64_r_minMag.c f64_addsub.c
+ f64_class.c f64_compare.c f64_div.c f64_frc.c f64_getExp.c f64_getMant.c f64_minmax.c
+ f64_mul.c f64_mulAdd.c f64_range.c f64_roundToInt.c f64_scalef.c f64_sqrt.c f64_to_extF80.cc
+ f64_to_f16.c f64_to_f32.c f64_to_f128.cc f64_to_i32.c f64_to_i32_r_minMag.c f64_to_i64.c
+ f64_to_i64_r_minMag.c f64_to_ui32.c f64_to_ui32_r_minMag.c f64_to_ui64.c f64_to_ui64_r_minMag.c
+ f128_addsub.cc f128_div.cc f128_mul.cc f128_mulAdd.cc f128_roundToInt.cc f128_to_extF80.cc
+ f128_to_f32.cc f128_to_f64.cc f128_to_i32.cc f128_to_i32_r_minMag.cc f128_to_i64.cc
+ f128_to_i64_r_minMag.cc f128_to_ui32.cc f128_to_ui32_r_minMag.cc f128_to_ui64.cc
+ f128_to_ui64_r_minMag.cc i32_to_extF80.cc i32_to_f16.c i32_to_f32.c i32_to_f64.c
+ i32_to_f128.cc i64_to_extF80.cc i64_to_f16.c i64_to_f32.c i64_to_f64.c i64_to_f128.cc
+ isNaN.cc isSignalingNaN.cc s_add128.cc s_add256M.c s_addMagsExtF80.cc s_addMagsF16.c
+ s_addMagsF32.c s_addMagsF64.c s_addMagsF128.cc s_approxRecip_1Ks.c s_approxRecipSqrt_1Ks.c
+ s_approxRecipSqrt32_1.c s_commonNaNToExtF80UI.cc s_commonNaNToF16UI.c s_commonNaNToF32UI.c
+ s_commonNaNToF64UI.c s_commonNaNToF128UI.cc s_countLeadingZeros8.c s_countLeadingZeros16.c
+ s_countLeadingZeros32.c s_countLeadingZeros64.c s_eq128.c s_le128.c s_lt128.c
+ s_mul64ByShifted32To128.cc s_mul64To128.cc s_mul128By32.cc s_mul128To256M.cc
+ s_normRoundPackToExtF80.cc s_normRoundPackToF16.c s_normRoundPackToF32.c s_normRoundPackToF64.c
+ s_normRoundPackToF128.cc s_normSubnormalExtF80Sig.cc s_normSubnormalF16Sig.c
+ s_normSubnormalF32Sig.c s_normSubnormalF64Sig.c s_normSubnormalF128Sig.cc s_packToExtF80.cc
+ s_propagateNaNExtF80UI.cc s_propagateNaNF16UI.c s_propagateNaNF32UI.c s_propagateNaNF64UI.c
+ s_propagateNaNF128UI.cc s_roundPackToExtF80.cc s_roundPackToF16.c s_roundPackToF32.c
+ s_roundPackToF64.c s_roundPackToF128.cc s_roundToI32.c s_roundToI64.c s_roundToUI32.c
+ s_roundToUI64.c s_shiftRightJam32.c s_shiftRightJam64.c s_shiftRightJam64Extra.c
+ s_shiftRightJam256M.c s_shortShiftLeft128.cc s_shortShiftRight128.cc s_shortShiftRightJam64.c
+ s_shortShiftRightJam64Extra.c s_sub128.cc s_sub256M.c s_subMagsExtF80.cc s_subMagsF16.c
+ s_subMagsF32.c s_subMagsF64.c s_subMagsF128.cc ui32_to_extF80.cc ui32_to_f16.c ui32_to_f32.c
+ ui32_to_f64.c ui32_to_f128.cc ui64_to_extF80.cc ui64_to_f16.c ui64_to_f32.c ui64_to_f64.c
+ ui64_to_f128.cc f2xm1.cc fpatan.cc fprem.cc fsincos.cc fyl2x.cc poly.cc consts.cc)
\ No newline at end of file
diff --git a/src/cpu/softfloat3e/COPYING.txt b/src/cpu/softfloat3e/COPYING.txt
new file mode 100644
index 000000000..b5690face
--- /dev/null
+++ b/src/cpu/softfloat3e/COPYING.txt
@@ -0,0 +1,37 @@
+
+License for Berkeley SoftFloat Release 3e
+
+John R. Hauser
+2018 January 20
+
+The following applies to the whole of SoftFloat Release 3e as well as to
+each source file individually.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+
diff --git a/src/cpu/softfloat3e/README.html b/src/cpu/softfloat3e/README.html
new file mode 100644
index 000000000..e695c2bd8
--- /dev/null
+++ b/src/cpu/softfloat3e/README.html
@@ -0,0 +1,49 @@
+
+
+
+
+Berkeley SoftFloat Package Overview
+
+
+
+
+Package Overview for Berkeley SoftFloat Release 3e
+
+
+John R. Hauser
+2018 January 20
+
+
+
+Berkeley SoftFloat is a software implementation of binary floating-point that
+conforms to the IEEE Standard for Floating-Point Arithmetic.
+SoftFloat is distributed in the form of C source code.
+Building the SoftFloat sources generates a library file (typically
+softfloat.a or libsoftfloat.a) containing the
+floating-point subroutines.
+
+
+
+The SoftFloat package is documented in the following files in the
+doc subdirectory:
+
+
+
+Other files in the package comprise the source code for SoftFloat.
+
+
+
+
diff --git a/src/cpu/softfloat3e/README.txt b/src/cpu/softfloat3e/README.txt
new file mode 100644
index 000000000..1613c7671
--- /dev/null
+++ b/src/cpu/softfloat3e/README.txt
@@ -0,0 +1,21 @@
+
+Package Overview for Berkeley SoftFloat Release 3e
+
+John R. Hauser
+2018 January 20
+
+Berkeley SoftFloat is a software implementation of binary floating-point
+that conforms to the IEEE Standard for Floating-Point Arithmetic. SoftFloat
+is distributed in the form of C source code. Building the SoftFloat sources
+generates a library file (typically "softfloat.a" or "libsoftfloat.a")
+containing the floating-point subroutines.
+
+The SoftFloat package is documented in the following files in the "doc"
+subdirectory:
+
+ SoftFloat.html Documentation for using the SoftFloat functions.
+ SoftFloat-source.html Documentation for building SoftFloat.
+ SoftFloat-history.html History of the major changes to SoftFloat.
+
+Other files in the package comprise the source code for SoftFloat.
+
diff --git a/src/cpu/softfloat3e/config.h b/src/cpu/softfloat3e/config.h
new file mode 100644
index 000000000..9febce242
--- /dev/null
+++ b/src/cpu/softfloat3e/config.h
@@ -0,0 +1,14 @@
+#ifndef EMU_SF_CONFIG_H
+#define EMU_SF_CONFIG_H
+
+/*----------------------------------------------------------------------------
+| The `LIT64' macro takes as its argument a textual integer literal and
+| if necessary ``marks'' the literal as having a 64-bit integer type.
+| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
+| appended with the letters `LL' standing for `long long', which is `gcc's
+| name for the 64-bit integer type. Some compilers may allow `LIT64' to be
+| defined as the identity macro: `#define LIT64( a ) a'.
+*----------------------------------------------------------------------------*/
+#define BX_CONST64(a) a##LL
+
+#endif /*EMU_SF_CONFIG_H*/
diff --git a/src/cpu/softfloat3e/consts.cc b/src/cpu/softfloat3e/consts.cc
new file mode 100644
index 000000000..235a03996
--- /dev/null
+++ b/src/cpu/softfloat3e/consts.cc
@@ -0,0 +1,51 @@
+/*============================================================================
+
+This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include <86box/86box.h>
+#include "../cpu.h"
+
+#include "softfloat-specialize.h"
+
+const floatx80 Const_QNaN = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
+const floatx80 Const_Z = packFloatx80(0, 0x0000, 0);
+const floatx80 Const_1 = packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000));
+const floatx80 Const_L2T = packFloatx80(0, 0x4000, BX_CONST64(0xd49a784bcd1b8afe));
+const floatx80 Const_L2E = packFloatx80(0, 0x3fff, BX_CONST64(0xb8aa3b295c17f0bc));
+const floatx80 Const_PI = packFloatx80(0, 0x4000, BX_CONST64(0xc90fdaa22168c235));
+const floatx80 Const_LG2 = packFloatx80(0, 0x3ffd, BX_CONST64(0x9a209a84fbcff799));
+const floatx80 Const_LN2 = packFloatx80(0, 0x3ffe, BX_CONST64(0xb17217f7d1cf79ac));
+const floatx80 Const_INF = packFloatx80(0, 0x7fff, BX_CONST64(0x8000000000000000));
diff --git a/src/cpu/softfloat3e/doc/SoftFloat-history.html b/src/cpu/softfloat3e/doc/SoftFloat-history.html
new file mode 100644
index 000000000..d81c6bc5a
--- /dev/null
+++ b/src/cpu/softfloat3e/doc/SoftFloat-history.html
@@ -0,0 +1,258 @@
+
+
+
+
+Berkeley SoftFloat History
+
+
+
+
+History of Berkeley SoftFloat, to Release 3e
+
+
+John R. Hauser
+2018 January 20
+
+
+
+Release 3e (2018 January)
+
+
+
+-
+Changed the default numeric code for optional rounding mode
odd
+(round to odd, also known as jamming) from 5 to 6.
+
+ -
+Modified the behavior of rounding mode
odd when rounding to an
+integer value (either conversion to an integer format or a
+‘roundToInt’ function).
+Previously, for those cases only, rounding mode odd acted the same
+as rounding to minimum magnitude.
+Now all operations are rounded consistently.
+
+ -
+Fixed some errors in the specialization code modeling Intel x86 floating-point,
+specifically the integers returned on invalid operations and the propagation of
+NaN payloads in a few rare cases.
+
+
-
+Added specialization code modeling ARM floating-point, conforming to VFPv2 or
+later.
+
+
-
+Added an example target for ARM processors.
+
+
-
+Fixed a minor bug whereby function
f16_to_ui64 might return a
+different integer than expected in the case that the floating-point operand is
+negative.
+
+ -
+Added example target-specific optimization for GCC, employing GCC instrinsics
+and support for 128-bit integer arithmetic.
+
+
-
+Made other minor improvements.
+
+
+
+
+Release 3d (2017 August)
+
+
+
+-
+Fixed bugs in the square root functions for 64-bit
+double-precision, 80-bit double-extended-precision, and
+128-bit quadruple-precision.
+For 64-bit double-precision (
f64_sqrt), the result
+could sometimes be off by 1 unit in the last place
+(1 ulp) from what it should be.
+For the larger formats, the square root could be wrong in a large portion of
+the less-significant bits.
+(A bug in f128_sqrt was first reported by Alexei Sibidanov.)
+
+
+
+
+Release 3c (2017 February)
+
+
+
+-
+Added optional rounding mode
odd (round to odd, also known as
+jamming).
+
+ -
+Corrected the documentation concerning non-canonical representations in
+80-bit double-extended-precision.
+
+
+
+
+Release 3b (2016 July)
+
+
+
+-
+Implemented the common 16-bit “half-precision”
+floating-point format (
float16_t).
+
+ -
+Made the integer values returned on invalid conversions to integer formats
+be determined by the port-specific specialization instead of being the same for
+all ports.
+
+
-
+Added preprocessor macro
THREAD_LOCAL to allow the floating-point
+state (modes and exception flags) to be made per-thread.
+
+ -
+Modified the provided Makefiles to allow some options to be overridden from the
+
make command.
+
+ -
+Made other minor improvements.
+
+
+
+
+Release 3a (2015 October)
+
+
+
+-
+Replaced the license text supplied by the University of California, Berkeley.
+
+
+
+
+Release 3 (2015 February)
+
+
+
+-
+Complete rewrite, funded by the University of California, Berkeley, and
+consequently having a different use license than earlier releases.
+Major changes included renaming most types and functions, upgrading some
+algorithms, restructuring the source files, and making SoftFloat into a true
+library.
+
+
-
+Added functions to convert between floating-point and unsigned integers, both
+32-bit and 64-bit (
uint32_t and
+uint64_t).
+
+ -
+Added functions for fused multiply-add, for all supported floating-point
+formats except 80-bit double-extended-precision.
+
+
-
+Added support for a fifth rounding mode,
near_maxMag (round to
+nearest, with ties to maximum magnitude, away from zero).
+
+ -
+Dropped the
timesoftfloat program (now part of the Berkeley
+TestFloat package).
+
+
+
+
+Release 2c (2015 January)
+
+
+
+-
+Fixed mistakes affecting some 64-bit processors.
+
+
-
+Further improved the documentation and the wording for the legal restrictions
+on using SoftFloat releases through 2c (not applicable to
+Release 3 or later).
+
+
+
+
+Release 2b (2002 May)
+
+
+
+-
+Made minor updates to the documentation, including improved wording for the
+legal restrictions on using SoftFloat.
+
+
+
+
+Release 2a (1998 December)
+
+
+
+-
+Added functions to convert between 64-bit integers
+(
int64) and all supported floating-point formats.
+
+ -
+Fixed a bug in all 64-bit-version square root functions except
+
float32_sqrt that caused the result sometimes to be off by
+1 unit in the last place (1 ulp) from what it should
+be.
+(Bug discovered by Paul Donahue.)
+
+ -
+Improved the Makefiles.
+
+
+
+Release 2 (1997 June)
+
+
+
+-
+Created the 64-bit (
bits64) version, adding the
+floatx80 and float128 formats.
+
+ -
+Changed the source directory structure, splitting the sources into a
+
bits32 and a bits64 version.
+Renamed environment.h to milieu.h to avoid confusion
+with environment variables.
+
+ -
+Fixed a small error that caused
float64_round_to_int often to
+round the wrong way in nearest/even mode when the operand was between
+220 and 221 and halfway between two integers.
+
+
+
+
+Release 1a (1996 July)
+
+
+
+-
+Corrected a mistake that caused borderline underflow cases not to raise the
+underflow flag when they should have.
+(Problem reported by Doug Priest.)
+
+
-
+Added the
float_detect_tininess variable to control whether
+tininess is detected before or after rounding.
+
+
+
+
+Release 1 (1996 July)
+
+
+
+-
+Original release, based on work done for the International Computer Science
+Institute (ICSI) in Berkeley, California.
+
+
+
+
+
+
diff --git a/src/cpu/softfloat3e/doc/SoftFloat-source.html b/src/cpu/softfloat3e/doc/SoftFloat-source.html
new file mode 100644
index 000000000..4ff9d4c45
--- /dev/null
+++ b/src/cpu/softfloat3e/doc/SoftFloat-source.html
@@ -0,0 +1,686 @@
+
+
+
+
+Berkeley SoftFloat Source Documentation
+
+
+
+
+Berkeley SoftFloat Release 3e: Source Documentation
+
+
+John R. Hauser
+2018 January 20
+
+
+
+Contents
+
+
+
+
+
+| 1. Introduction |
+| 2. Limitations |
+| 3. Acknowledgments and License |
+| 4. SoftFloat Package Directory Structure |
+| 5. Issues for Porting SoftFloat to a New Target |
+
+ |
+ 5.1. Standard Headers <stdbool.h> and
+ <stdint.h> |
+
+ | 5.2. Specializing Floating-Point Behavior |
+ | 5.3. Macros for Build Options |
+ | 5.4. Adapting a Template Target Directory |
+
+ | 5.5. Target-Specific Optimization of Primitive Functions |
+
+| 6. Testing SoftFloat |
+
+ | 7. Providing SoftFloat as a Common Library for Applications |
+
+| 8. Contact Information |
+
+
+
+
+1. Introduction
+
+
+This document gives information needed for compiling and/or porting Berkeley
+SoftFloat, a library of C functions implementing binary floating-point
+conforming to the IEEE Standard for Floating-Point Arithmetic.
+For basic documentation about SoftFloat refer to
+SoftFloat.html.
+
+
+
+The source code for SoftFloat is intended to be relatively machine-independent
+and should be compilable with any ISO-Standard C compiler that also supports
+64-bit integers.
+SoftFloat has been successfully compiled with the GNU C Compiler
+(gcc) for several platforms.
+
+
+
+Release 3 of SoftFloat was a complete rewrite relative to
+Release 2 or earlier.
+Changes to the interface of SoftFloat functions are documented in
+SoftFloat.html.
+The current version of SoftFloat is Release 3e.
+
+
+
+2. Limitations
+
+
+SoftFloat assumes the computer has an addressable byte size of either 8 or
+16 bits.
+(Nearly all computers in use today have 8-bit bytes.)
+
+
+
+SoftFloat is written in C and is designed to work with other C code.
+The C compiler used must conform at a minimum to the 1989 ANSI standard for the
+C language (same as the 1990 ISO standard) and must in addition support basic
+arithmetic on 64-bit integers.
+Earlier releases of SoftFloat included implementations of 32-bit
+single-precision and 64-bit double-precision floating-point that
+did not require 64-bit integers, but this option is not supported
+starting with Release 3.
+Since 1999, ISO standards for C have mandated compiler support for
+64-bit integers.
+A compiler conforming to the 1999 C Standard or later is recommended but not
+strictly required.
+
+
+
+C Standard header files <stdbool.h> and
+<stdint.h> are required for defining standard Boolean and
+integer types.
+If these headers are not supplied with the C compiler, minimal substitutes must
+be provided.
+SoftFloat’s dependence on these headers is detailed later in
+section 5.1, Standard Headers <stdbool.h>
+and <stdint.h>.
+
+
+
+3. Acknowledgments and License
+
+
+The SoftFloat package was written by me, John R. Hauser.
+Release 3 of SoftFloat was a completely new implementation
+supplanting earlier releases.
+The project to create Release 3 (now through 3e) was
+done in the employ of the University of California, Berkeley, within the
+Department of Electrical Engineering and Computer Sciences, first for the
+Parallel Computing Laboratory (Par Lab) and then for the ASPIRE Lab.
+The work was officially overseen by Prof. Krste Asanovic, with funding provided
+by these sources:
+
+
+
+
+
+
+| Par Lab: |
+ |
+
+Microsoft (Award #024263), Intel (Award #024894), and U.C. Discovery
+(Award #DIG07-10227), with additional support from Par Lab affiliates Nokia,
+NVIDIA, Oracle, and Samsung.
+ |
+
+
+| ASPIRE Lab: |
+ |
+
+DARPA PERFECT program (Award #HR0011-12-2-0016), with additional support from
+ASPIRE industrial sponsor Intel and ASPIRE affiliates Google, Nokia, NVIDIA,
+Oracle, and Samsung.
+ |
+
+
+
+
+
+
+The following applies to the whole of SoftFloat Release 3e as well
+as to each source file individually.
+
+
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
+University of California.
+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 University 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 REGENTS 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 REGENTS 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.
+
+
+
+4. SoftFloat Package Directory Structure
+
+
+Because SoftFloat is targeted to multiple platforms, its source code is
+slightly scattered between target-specific and target-independent directories
+and files.
+The supplied directory structure is as follows:
+
+
+doc
+source
+ include
+ 8086
+ 8086-SSE
+ ARM-VFPv2
+ ARM-VFPv2-defaultNaN
+build
+ template-FAST_INT64
+ template-not-FAST_INT64
+ Linux-386-GCC
+ Linux-386-SSE2-GCC
+ Linux-x86_64-GCC
+ Linux-ARM-VFPv2-GCC
+ Win32-MinGW
+ Win32-SSE2-MinGW
+ Win64-MinGW-w64
+
+
+The majority of the SoftFloat sources are provided in the source
+directory.
+The include subdirectory contains several header files
+(unsurprisingly), while the other subdirectories of source contain
+source files that specialize the floating-point behavior to match particular
+processor families:
+
+
+8086
+-
+Intel’s older, 8087-derived floating-point, extended to all supported
+floating-point types
+
+8086-SSE
+-
+Intel’s x86 processors with Streaming SIMD Extensions (SSE) and later
+compatible extensions, having 8087 behavior for 80-bit
+double-extended-precision (
extFloat80_t) and SSE behavior for
+other floating-point types
+
+ARM-VFPv2
+-
+ARM’s VFPv2 or later floating-point, with NaN payload propagation
+
+ARM-VFPv2-defaultNaN
+-
+ARM’s VFPv2 or later floating-point, with the “default NaN”
+option
+
+
+
+If other specializations are attempted, these would be expected to be other
+subdirectories of source alongside the ones listed above.
+Specialization is covered later, in section 5.2, Specializing
+Floating-Point Behavior.
+
+
+
+The build directory is intended to contain a subdirectory for each
+target platform for which a build of the SoftFloat library may be created.
+For each build target, the target’s subdirectory is where all derived
+object files and the completed SoftFloat library (typically
+softfloat.a or libsoftfloat.a) are created.
+The two template subdirectories are not actual build targets but
+contain sample files for creating new target directories.
+(The meaning of FAST_INT64 will be explained later.)
+
+
+
+Ignoring the template directories, the supplied target directories
+are intended to follow a naming system of
+<execution-environment>-<compiler>.
+For the example targets,
+<execution-environment> is
+Linux-386, Linux-386-SSE2,
+Linux-x86_64,
+Linux-ARM-VFPv2, Win32,
+Win32-SSE2, or Win64, and
+<compiler> is GCC,
+MinGW, or MinGW-w64.
+
+
+
+All of the supplied target directories are merely examples that may or may not
+be correct for compiling on any particular system.
+Despite requests, there are currently no plans to include and maintain in the
+SoftFloat package the build files needed for a great many users’
+compilation environments, which can span a huge range of operating systems,
+compilers, and other tools.
+
+
+
+As supplied, each target directory contains two files:
+
+
+Makefile
+platform.h
+
+
+The provided Makefile is written for GNU make.
+A build of SoftFloat for the specific target is begun by executing the
+make command with the target directory as the current directory.
+A completely different build tool can be used if an appropriate
+Makefile equivalent is created.
+
+
+
+The platform.h header file exists to provide a location for
+additional C declarations specific to the build target.
+Every C source file of SoftFloat contains a #include for
+platform.h.
+In many cases, the contents of platform.h can be as simple as one
+or two lines of code.
+At the other extreme, to get maximal performance from SoftFloat, it may be
+desirable to include in header platform.h (directly or via
+#include) declarations for numerous target-specific optimizations.
+Such possibilities are discussed in the next section, Issues for Porting
+SoftFloat to a New Target.
+If the target’s compiler or library has bugs or other shortcomings,
+workarounds for these issues may also be possible with target-specific
+declarations in platform.h, avoiding the need to modify the main
+SoftFloat sources.
+
+
+
+5. Issues for Porting SoftFloat to a New Target
+
+5.1. Standard Headers <stdbool.h> and <stdint.h>
+
+
+The SoftFloat sources make use of standard headers
+<stdbool.h> and <stdint.h>, which have
+been part of the ISO C Standard Library since 1999.
+With any recent compiler, these standard headers are likely to be supported,
+even if the compiler does not claim complete conformance to the latest ISO C
+Standard.
+For older or nonstandard compilers, substitutes for
+<stdbool.h> and <stdint.h> may need to be
+created.
+SoftFloat depends on these names from <stdbool.h>:
+
+
+bool
+true
+false
+
+
+and on these names from <stdint.h>:
+
+
+uint16_t
+uint32_t
+uint64_t
+int32_t
+int64_t
+UINT64_C
+INT64_C
+uint_least8_t
+uint_fast8_t
+uint_fast16_t
+uint_fast32_t
+uint_fast64_t
+int_fast8_t
+int_fast16_t
+int_fast32_t
+int_fast64_t
+
+
+
+
+
+5.2. Specializing Floating-Point Behavior
+
+
+The IEEE Floating-Point Standard allows for some flexibility in a conforming
+implementation, particularly concerning NaNs.
+The SoftFloat source directory is supplied with some
+specialization subdirectories containing possible definitions for this
+implementation-specific behavior.
+For example, the 8086 and 8086-SSE
+subdirectories have source files that specialize SoftFloat’s behavior to
+match that of Intel’s x86 line of processors.
+The files in a specialization subdirectory must determine:
+
+-
+whether tininess for underflow is detected before or after rounding by default;
+
-
+how signaling NaNs are distinguished from quiet NaNs;
+
-
+what (if anything) special happens when exceptions are raised;
+
-
+the default generated quiet NaNs;
+
-
+how NaNs are propagated from function inputs to output; and
+
-
+the integer results returned when conversions to integer type raise the
+invalid exception.
+
+
+
+
+As provided, the build process for a target expects to involve exactly
+one specialization directory that defines all of these
+implementation-specific details for the target.
+A specialization directory such as 8086 is expected to contain a
+header file called specialize.h, together with whatever other
+source files are needed to complete the specialization.
+
+
+
+A new build target may use an existing specialization, such as the ones
+provided by the 8086 and 8086-SSE
+subdirectories.
+If a build target needs a new specialization, different from any existing ones,
+it is recommended that a new specialization directory be created for this
+purpose.
+The specialize.h header file from any of the provided
+specialization subdirectories can be used as a model for what definitions are
+needed.
+
+
+
+5.3. Macros for Build Options
+
+
+The SoftFloat source files adapt the floating-point implementation according to
+several C preprocessor macros:
+
+
+LITTLEENDIAN
+-
+Must be defined for little-endian machines; must not be defined for big-endian
+machines.
+
INLINE
+-
+Specifies the sequence of tokens used to indicate that a C function should be
+inlined.
+If macro
INLINE_LEVEL is defined with a value of 1 or higher, this
+macro must be defined; otherwise, this macro is ignored and need not be
+defined.
+For compilers that conform to the C Standard’s rules for inline
+functions, this macro can be defined as the single keyword inline.
+For other compilers that follow a convention pre-dating the standardization of
+inline, this macro may need to be defined to extern
+inline.
+ THREAD_LOCAL
+-
+Can be defined to a sequence of tokens that, when appearing at the start of a
+variable declaration, indicates to the C compiler that the variable is
+per-thread, meaning that each execution thread gets its own separate
+instance of the variable.
+This macro is used in header
softfloat.h in the declarations of
+variables softfloat_roundingMode,
+softfloat_detectTininess, extF80_roundingPrecision,
+and softfloat_exceptionFlags.
+If macro THREAD_LOCAL is left undefined, these variables will
+default to being ordinary global variables.
+Depending on the compiler, possible valid definitions of this macro include
+_Thread_local and __thread.
+
+
+SOFTFLOAT_ROUND_ODD
+-
+Can be defined to enable support for optional rounding mode
+
softfloat_round_odd.
+
+
+INLINE_LEVEL
+-
+Can be defined to an integer to determine the degree of inlining requested of
+the compiler.
+Larger numbers request that more inlining be done.
+If this macro is not defined or is defined to a value less than 1
+(zero or negative), no inlining is requested.
+The maximum effective value is no higher than 5.
+Defining this macro to a value greater than 5 is the same as defining it
+to 5.
+
SOFTFLOAT_FAST_INT64
+-
+Can be defined to indicate that the build target’s implementation of
+64-bit arithmetic is efficient.
+For newer 64-bit processors, this macro should usually be defined.
+For very small microprocessors whose buses and registers are 8-bit
+or 16-bit in size, this macro should usually not be defined.
+Whether this macro should be defined for a 32-bit processor may
+depend on the target machine and the applications that will use SoftFloat.
+
SOFTFLOAT_FAST_DIV32TO16
+-
+Can be defined to indicate that the target’s division operator
+in C (written as
/) is reasonably efficient for
+dividing a 32-bit unsigned integer by a 16-bit
+unsigned integer.
+Setting this macro may affect the performance of function f16_div.
+ SOFTFLOAT_FAST_DIV64TO32
+-
+Can be defined to indicate that the target’s division operator
+in C (written as
/) is reasonably efficient for
+dividing a 64-bit unsigned integer by a 32-bit
+unsigned integer.
+Setting this macro may affect the performance of division, remainder, and
+square root operations other than f16_div.
+
+
+
+
+
+Following the usual custom for C, for most of these macros (all
+except INLINE, THREAD_LOCAL, and
+INLINE_LEVEL), the content of any definition is irrelevant;
+what matters is a macro’s effect on #ifdef directives.
+
+
+
+It is recommended that any definitions of macros LITTLEENDIAN,
+INLINE, and THREAD_LOCAL be made in a build
+target’s platform.h header file, because these macros are
+expected to be determined inflexibly by the target machine and compiler.
+The other five macros select options and control optimization, and thus might
+be better located in the target’s Makefile (or its equivalent).
+
+
+
+5.4. Adapting a Template Target Directory
+
+
+In the build directory, two template subdirectories
+provide models for new target directories.
+Two different templates exist because different functions are needed in the
+SoftFloat library depending on whether macro SOFTFLOAT_FAST_INT64
+is defined.
+If macro SOFTFLOAT_FAST_INT64 will be defined,
+template-FAST_INT64 is the template to use;
+otherwise, template-not-FAST_INT64 is the appropriate
+template.
+A new target directory can be created by copying the correct template directory
+and editing the files inside.
+To avoid confusion, it would be wise to refrain from editing the files within a
+template directory directly.
+
+
+
+5.5. Target-Specific Optimization of Primitive Functions
+
+
+Header file primitives.h (in directory
+source/include) declares macros and functions for numerous
+underlying arithmetic operations upon which many of SoftFloat’s
+floating-point functions are ultimately built.
+The SoftFloat sources include implementations of all of these functions/macros,
+written as standard C code, so a complete and correct SoftFloat library can be
+created using only the supplied code for all functions.
+However, for many targets, SoftFloat’s performance can be improved by
+substituting target-specific implementations of some of the functions/macros
+declared in primitives.h.
+
+
+
+For example, primitives.h declares a function called
+softfloat_countLeadingZeros32 that takes an unsigned
+32-bit integer as an argument and returns the number of the
+integer’s most-significant bits that are zeros.
+While the SoftFloat sources include an implementation of this function written
+in standard C, many processors can perform this same function
+directly in only one or two machine instructions.
+An alternative, target-specific implementation that maps to those instructions
+is likely to be more efficient than the generic C code from the SoftFloat
+package.
+
+
+
+A build target can replace the supplied version of any function or macro of
+primitives.h by defining a macro with the same name in the
+target’s platform.h header file.
+For this purpose, it may be helpful for platform.h to
+#include header file primitiveTypes.h, which defines
+types used for arguments and results of functions declared in
+primitives.h.
+When a desired replacement implementation is a function, not a macro, it is
+sufficient for platform.h to include the line
+
+
+#define <function-name> <function-name>
+
+
+where <function-name> is the name of the
+function.
+This technically defines <function-name>
+as a macro, but one that resolves to the same name, which may then be a
+function.
+(A preprocessor that conforms to the C Standard is required to limit recursive
+macro expansion from being applied more than once.)
+
+
+
+The supplied header file opts-GCC.h (in directory
+source/include) provides an example of target-specific
+optimization for the GCC compiler.
+Each GCC target example in the build directory has
+
+#include "opts-GCC.h"
+
+in its platform.h header file.
+Before opts-GCC.h is included, the following macros must be
+defined (or not) to control which features are invoked:
+
+
+SOFTFLOAT_BUILTIN_CLZ
+-
+If defined, SoftFloat’s internal
+‘
countLeadingZeros’ functions use intrinsics
+__builtin_clz and __builtin_clzll.
+
+SOFTFLOAT_INTRINSIC_INT128
+-
+If defined, SoftFloat makes use of GCC’s nonstandard 128-bit
+integer type
__int128.
+
+
+
+On some machines, these improvements are observed to increase the speeds of
+f64_mul and f128_mul by around 20 to 25%, although
+other functions receive less dramatic boosts, or none at all.
+Results can vary greatly across different platforms.
+
+
+
+6. Testing SoftFloat
+
+
+SoftFloat can be tested using the testsoftfloat program by the
+same author.
+This program is part of the Berkeley TestFloat package available at the Web
+page
+http://www.jhauser.us/arithmetic/TestFloat.html.
+The TestFloat package also has a program called timesoftfloat that
+measures the speed of SoftFloat’s floating-point functions.
+
+
+
+7. Providing SoftFloat as a Common Library for Applications
+
+
+Header file softfloat.h defines the SoftFloat interface as seen by
+clients.
+If the SoftFloat library will be made a common library for programs on a
+system, the supplied softfloat.h has a couple of deficiencies for
+this purpose:
+
+-
+As supplied,
softfloat.h depends on another header,
+softfloat_types.h, that is not intended for public use but which
+must also be visible to the programmer’s compiler.
+ -
+More troubling, at the time
softfloat.h is included in a C source
+file, macros SOFTFLOAT_FAST_INT64 and THREAD_LOCAL
+must be defined, or not defined, consistent with how these macro were defined
+when the SoftFloat library was built.
+
+In the situation that new programs may regularly #include header
+file softfloat.h, it is recommended that a custom, self-contained
+version of this header file be created that eliminates these issues.
+
+
+
+8. Contact Information
+
+
+At the time of this writing, the most up-to-date information about SoftFloat
+and the latest release can be found at the Web page
+http://www.jhauser.us/arithmetic/SoftFloat.html.
+
+
+
+
+
diff --git a/src/cpu/softfloat3e/doc/SoftFloat.html b/src/cpu/softfloat3e/doc/SoftFloat.html
new file mode 100644
index 000000000..b72b407f4
--- /dev/null
+++ b/src/cpu/softfloat3e/doc/SoftFloat.html
@@ -0,0 +1,1527 @@
+
+
+
+
+Berkeley SoftFloat Library Interface
+
+
+
+
+Berkeley SoftFloat Release 3e: Library Interface
+
+
+John R. Hauser
+2018 January 20
+
+
+
+Contents
+
+
+
+
+
+| 1. Introduction |
+| 2. Limitations |
+| 3. Acknowledgments and License |
+| 4. Types and Functions |
+ | 4.1. Boolean and Integer Types |
+ | 4.2. Floating-Point Types |
+ | 4.3. Supported Floating-Point Functions |
+
+ |
+ 4.4. Non-canonical Representations in extFloat80_t |
+
+ | 4.5. Conventions for Passing Arguments and Results |
+| 5. Reserved Names |
+| 6. Mode Variables |
+ | 6.1. Rounding Mode |
+ | 6.2. Underflow Detection |
+
+ |
+ 6.3. Rounding Precision for the 80-Bit Extended Format |
+
+| 7. Exceptions and Exception Flags |
+| 8. Function Details |
+ | 8.1. Conversions from Integer to Floating-Point |
+ | 8.2. Conversions from Floating-Point to Integer |
+ | 8.3. Conversions Among Floating-Point Types |
+ | 8.4. Basic Arithmetic Functions |
+ | 8.5. Fused Multiply-Add Functions |
+ | 8.6. Remainder Functions |
+ | 8.7. Round-to-Integer Functions |
+ | 8.8. Comparison Functions |
+ | 8.9. Signaling NaN Test Functions |
+ | 8.10. Raise-Exception Function |
+| 9. Changes from SoftFloat Release 2 |
+ | 9.1. Name Changes |
+ | 9.2. Changes to Function Arguments |
+ | 9.3. Added Capabilities |
+ | 9.4. Better Compatibility with the C Language |
+ | 9.5. New Organization as a Library |
+ | 9.6. Optimization Gains (and Losses) |
+| 10. Future Directions |
+| 11. Contact Information |
+
+
+
+
+1. Introduction
+
+
+Berkeley SoftFloat is a software implementation of binary floating-point that
+conforms to the IEEE Standard for Floating-Point Arithmetic.
+The current release supports five binary formats: 16-bit
+half-precision, 32-bit single-precision, 64-bit
+double-precision, 80-bit double-extended-precision, and
+128-bit quadruple-precision.
+The following functions are supported for each format:
+
+-
+addition, subtraction, multiplication, division, and square root;
+
-
+fused multiply-add as defined by the IEEE Standard, except for
+80-bit double-extended-precision;
+
-
+remainder as defined by the IEEE Standard;
+
-
+round to integral value;
+
-
+comparisons;
+
-
+conversions to/from other supported formats; and
+
-
+conversions to/from 32-bit and 64-bit integers,
+signed and unsigned.
+
+All operations required by the original 1985 version of the IEEE Floating-Point
+Standard are implemented, except for conversions to and from decimal.
+
+
+
+This document gives information about the types defined and the routines
+implemented by SoftFloat.
+It does not attempt to define or explain the IEEE Floating-Point Standard.
+Information about the standard is available elsewhere.
+
+
+
+The current version of SoftFloat is Release 3e.
+This release modifies the behavior of the rarely used odd rounding mode
+(round to odd, also known as jamming), and also adds some new
+specialization and optimization examples for those compiling SoftFloat.
+
+
+
+The previous Release 3d fixed bugs that were found in the square
+root functions for the 64-bit, 80-bit, and
+128-bit floating-point formats.
+(Thanks to Alexei Sibidanov at the University of Victoria for reporting an
+incorrect result.)
+The bugs affected all prior Release-3 versions of SoftFloat
+through 3c.
+The flaw in the 64-bit floating-point square root function was of
+very minor impact, causing a 1-ulp error (1 unit in
+the last place) a few times out of a billion.
+The bugs in the 80-bit and 128-bit square root
+functions were more serious.
+Although incorrect results again occurred only a few times out of a billion,
+when they did occur a large portion of the less-significant bits could be
+wrong.
+
+
+
+Among earlier releases, 3b was notable for adding support for the
+16-bit half-precision format.
+For more about the evolution of SoftFloat releases, see
+SoftFloat-history.html.
+
+
+
+The functional interface of SoftFloat Release 3 and later differs
+in many details from the releases that came before.
+For specifics of these differences, see section 9 below,
+Changes from SoftFloat Release 2.
+
+
+
+2. Limitations
+
+
+SoftFloat assumes the computer has an addressable byte size of 8 or
+16 bits.
+(Nearly all computers in use today have 8-bit bytes.)
+
+
+
+SoftFloat is written in C and is designed to work with other C code.
+The C compiler used must conform at a minimum to the 1989 ANSI standard for the
+C language (same as the 1990 ISO standard) and must in addition support basic
+arithmetic on 64-bit integers.
+Earlier releases of SoftFloat included implementations of 32-bit
+single-precision and 64-bit double-precision floating-point that
+did not require 64-bit integers, but this option is not supported
+starting with Release 3.
+Since 1999, ISO standards for C have mandated compiler support for
+64-bit integers.
+A compiler conforming to the 1999 C Standard or later is recommended but not
+strictly required.
+
+
+
+Most operations not required by the original 1985 version of the IEEE
+Floating-Point Standard but added in the 2008 version are not yet supported in
+SoftFloat Release 3e.
+
+
+
+3. Acknowledgments and License
+
+
+The SoftFloat package was written by me, John R. Hauser.
+Release 3 of SoftFloat was a completely new implementation
+supplanting earlier releases.
+The project to create Release 3 (now through 3e) was
+done in the employ of the University of California, Berkeley, within the
+Department of Electrical Engineering and Computer Sciences, first for the
+Parallel Computing Laboratory (Par Lab) and then for the ASPIRE Lab.
+The work was officially overseen by Prof. Krste Asanovic, with funding provided
+by these sources:
+
+
+
+
+
+
+| Par Lab: |
+ |
+
+Microsoft (Award #024263), Intel (Award #024894), and U.C. Discovery
+(Award #DIG07-10227), with additional support from Par Lab affiliates Nokia,
+NVIDIA, Oracle, and Samsung.
+ |
+
+
+| ASPIRE Lab: |
+ |
+
+DARPA PERFECT program (Award #HR0011-12-2-0016), with additional support from
+ASPIRE industrial sponsor Intel and ASPIRE affiliates Google, Nokia, NVIDIA,
+Oracle, and Samsung.
+ |
+
+
+
+
+
+
+The following applies to the whole of SoftFloat Release 3e as well
+as to each source file individually.
+
+
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
+University of California.
+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 University 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 REGENTS 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 REGENTS 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.
+
+
+
+4. Types and Functions
+
+
+The types and functions of SoftFloat are declared in header file
+softfloat.h.
+
+
+4.1. Boolean and Integer Types
+
+
+Header file softfloat.h depends on standard headers
+<stdbool.h> and <stdint.h> to define type
+bool and several integer types.
+These standard headers have been part of the ISO C Standard Library since 1999.
+With any recent compiler, they are likely to be supported, even if the compiler
+does not claim complete conformance to the latest ISO C Standard.
+For older or nonstandard compilers, a port of SoftFloat may have substitutes
+for these headers.
+Header softfloat.h depends only on the name bool from
+<stdbool.h> and on these type names from
+<stdint.h>:
+
+
+uint16_t
+uint32_t
+uint64_t
+int32_t
+int64_t
+uint_fast8_t
+uint_fast32_t
+uint_fast64_t
+int_fast32_t
+int_fast64_t
+
+
+
+
+
+4.2. Floating-Point Types
+
+
+The softfloat.h header defines five floating-point types:
+
+
+
+float16_t |
+16-bit half-precision binary format |
+
+
+float32_t |
+32-bit single-precision binary format |
+
+
+float64_t |
+64-bit double-precision binary format |
+
+
+extFloat80_t |
+80-bit double-extended-precision binary format (old Intel or
+Motorola format) |
+
+
+float128_t |
+128-bit quadruple-precision binary format |
+
+
+
+The non-extended types are each exactly the size specified:
+16 bits for float16_t, 32 bits for
+float32_t, 64 bits for float64_t, and
+128 bits for float128_t.
+Aside from these size requirements, the definitions of all these types may
+differ for different ports of SoftFloat to specific systems.
+A given port of SoftFloat may or may not define some of the floating-point
+types as aliases for the C standard types float,
+double, and long double.
+
+
+
+Header file softfloat.h also defines a structure,
+struct extFloat80M, for the representation of
+80-bit double-extended-precision floating-point values in memory.
+This structure is the same size as type extFloat80_t and contains
+at least these two fields (not necessarily in this order):
+
+
+uint16_t signExp;
+uint64_t signif;
+
+
+Field signExp contains the sign and exponent of the floating-point
+value, with the sign in the most significant bit (bit 15) and the
+encoded exponent in the other 15 bits.
+Field signif is the complete 64-bit significand of
+the floating-point value.
+(In the usual encoding for 80-bit extended floating-point, the
+leading 1 bit of normalized numbers is not implicit but is stored
+in the most significant bit of the significand.)
+
+
+4.3. Supported Floating-Point Functions
+
+
+SoftFloat implements these arithmetic operations for its floating-point types:
+
+-
+conversions between any two floating-point formats;
+
-
+for each floating-point format, conversions to and from signed and unsigned
+32-bit and 64-bit integers;
+
-
+for each format, the usual addition, subtraction, multiplication, division, and
+square root operations;
+
-
+for each format except
extFloat80_t, the fused multiply-add
+operation defined by the IEEE Standard;
+ -
+for each format, the floating-point remainder operation defined by the IEEE
+Standard;
+
-
+for each format, a “round to integer” operation that rounds to the
+nearest integer value in the same format; and
+
-
+comparisons between two values in the same floating-point format.
+
+
+
+
+The following operations required by the 2008 IEEE Floating-Point Standard are
+not supported in SoftFloat Release 3e:
+
+-
+nextUp, nextDown, minNum, maxNum, minNumMag,
+maxNumMag, scaleB, and logB;
+
-
+conversions between floating-point formats and decimal or hexadecimal character
+sequences;
+
-
+all “quiet-computation” operations (copy, negate,
+abs, and copySign, which all involve only simple copying and/or
+manipulation of the floating-point sign bit); and
+
-
+all “non-computational” operations other than isSignaling
+(which is supported).
+
+
+
+4.4. Non-canonical Representations in extFloat80_t
+
+
+Because the 80-bit double-extended-precision format,
+extFloat80_t, stores an explicit leading significand bit, many
+finite floating-point numbers are encodable in this type in multiple equivalent
+forms.
+Of these multiple encodings, there is always a unique one with the least
+encoded exponent value, and this encoding is considered the canonical
+representation of the floating-point number.
+Any other equivalent representations (having a higher encoded exponent value)
+are non-canonical.
+For a value in the subnormal range (including zero), the canonical
+representation always has an encoded exponent of zero and a leading significand
+bit of 0.
+For finite values outside the subnormal range, the canonical representation
+always has an encoded exponent that is nonzero and a leading significand bit
+of 1.
+
+
+
+For an infinity or NaN, the leading significand bit is similarly expected to
+be 1.
+An infinity or NaN with a leading significand bit of 0 is again
+considered non-canonical.
+Hence, altogether, to be canonical, a value of type extFloat80_t
+must have a leading significand bit of 1, unless the value is
+subnormal or zero, in which case the leading significand bit and the encoded
+exponent must both be zero.
+
+
+
+SoftFloat’s functions are not guaranteed to operate as expected when
+inputs of type extFloat80_t are non-canonical.
+Assuming all of a function’s extFloat80_t inputs (if any)
+are canonical, function outputs of type extFloat80_t will always
+be canonical.
+
+
+4.5. Conventions for Passing Arguments and Results
+
+
+Values that are at most 64 bits in size (i.e., not the
+80-bit or 128-bit floating-point formats) are in all
+cases passed as function arguments by value.
+Likewise, when an output of a function is no more than 64 bits, it
+is always returned directly as the function result.
+Thus, for example, the SoftFloat function for adding two 64-bit
+floating-point values has this simple signature:
+
+float64_t f64_add( float64_t, float64_t );
+
+
+
+
+The story is more complex when function inputs and outputs are
+80-bit and 128-bit floating-point.
+For these types, SoftFloat always provides a function that passes these larger
+values into or out of the function indirectly, via pointers.
+For example, for adding two 128-bit floating-point values,
+SoftFloat supplies this function:
+
+void f128M_add( const float128_t *, const float128_t *, float128_t * );
+
+The first two arguments point to the values to be added, and the last argument
+points to the location where the sum will be stored.
+The M in the name f128M_add is mnemonic for the fact
+that the 128-bit inputs and outputs are “in memory”,
+pointed to by pointer arguments.
+
+
+
+All ports of SoftFloat implement these pass-by-pointer functions for
+types extFloat80_t and float128_t.
+At the same time, SoftFloat ports may also implement alternate versions of
+these same functions that pass extFloat80_t and
+float128_t by value, like the smaller formats.
+Thus, besides the function with name f128M_add shown above, a
+SoftFloat port may also supply an equivalent function with this signature:
+
+float128_t f128_add( float128_t, float128_t );
+
+
+
+
+As a general rule, on computers where the machine word size is
+32 bits or smaller, only the pass-by-pointer versions of functions
+(e.g., f128M_add) are provided for types extFloat80_t
+and float128_t, because passing such large types directly can have
+significant extra cost.
+On computers where the word size is 64 bits or larger, both
+function versions (f128M_add and f128_add) are
+provided, because the cost of passing by value is then more reasonable.
+Applications that must be portable accross both classes of computers must use
+the pointer-based functions, as these are always implemented.
+However, if it is known that SoftFloat includes the by-value functions for all
+platforms of interest, programmers can use whichever version they prefer.
+
+
+
+5. Reserved Names
+
+
+In addition to the variables and functions documented here, SoftFloat defines
+some symbol names for its own private use.
+These private names always begin with the prefix
+‘softfloat_’.
+When a program includes header softfloat.h or links with the
+SoftFloat library, all names with prefix ‘softfloat_’
+are reserved for possible use by SoftFloat.
+Applications that use SoftFloat should not define their own names with this
+prefix, and should reference only such names as are documented.
+
+
+
+6. Mode Variables
+
+
+The following global variables control rounding mode, underflow detection, and
+the 80-bit extended format’s rounding precision:
+
+softfloat_roundingMode
+softfloat_detectTininess
+extF80_roundingPrecision
+
+These mode variables are covered in the next several subsections.
+For some SoftFloat ports, these variables may be per-thread (declared
+thread_local), meaning that different execution threads have their
+own separate copies of the variables.
+
+
+6.1. Rounding Mode
+
+
+All five rounding modes defined by the 2008 IEEE Floating-Point Standard are
+implemented for all operations that require rounding.
+Some ports of SoftFloat may also implement the round-to-odd mode.
+
+
+
+The rounding mode is selected by the global variable
+
+uint_fast8_t softfloat_roundingMode;
+
+This variable may be set to one of the values
+
+
+
+softfloat_round_near_even |
+round to nearest, with ties to even |
+
+
+softfloat_round_near_maxMag |
+round to nearest, with ties to maximum magnitude (away from zero) |
+
+
+softfloat_round_minMag |
+round to minimum magnitude (toward zero) |
+
+
+softfloat_round_min |
+round to minimum (down) |
+
+
+softfloat_round_max |
+round to maximum (up) |
+
+
+softfloat_round_odd |
+round to odd (jamming), if supported by the SoftFloat port |
+
+
+
+Variable softfloat_roundingMode is initialized to
+softfloat_round_near_even.
+
+
+
+When softfloat_round_odd is the rounding mode for a function that
+rounds to an integer value (either conversion to an integer format or a
+‘roundToInt’ function), if the input is not already an
+integer, the rounded result is the closest odd integer.
+For other operations, this rounding mode acts as though the floating-point
+result is first rounded to minimum magnitude, the same as
+softfloat_round_minMag, and then, if the result is inexact, the
+least-significant bit of the result is set to 1.
+Rounding to odd is also known as jamming.
+
+
+6.2. Underflow Detection
+
+
+In the terminology of the IEEE Standard, SoftFloat can detect tininess for
+underflow either before or after rounding.
+The choice is made by the global variable
+
+uint_fast8_t softfloat_detectTininess;
+
+which can be set to either
+
+softfloat_tininess_beforeRounding
+softfloat_tininess_afterRounding
+
+Detecting tininess after rounding is usually better because it results in fewer
+spurious underflow signals.
+The other option is provided for compatibility with some systems.
+Like most systems (and as required by the newer 2008 IEEE Standard), SoftFloat
+always detects loss of accuracy for underflow as an inexact result.
+
+
+6.3. Rounding Precision for the 80-Bit Extended Format
+
+
+For extFloat80_t only, the rounding precision of the basic
+arithmetic operations is controlled by the global variable
+
+uint_fast8_t extF80_roundingPrecision;
+
+The operations affected are:
+
+extF80_add
+extF80_sub
+extF80_mul
+extF80_div
+extF80_sqrt
+
+When extF80_roundingPrecision is set to its default value of 80,
+these operations are rounded to the full precision of the 80-bit
+double-extended-precision format, like occurs for other formats.
+Setting extF80_roundingPrecision to 32 or to 64 causes the
+operations listed to be rounded to 32-bit precision (equivalent to
+float32_t) or to 64-bit precision (equivalent to
+float64_t), respectively.
+When rounding to reduced precision, additional bits in the result significand
+beyond the rounding point are set to zero.
+The consequences of setting extF80_roundingPrecision to a value
+other than 32, 64, or 80 is not specified.
+Operations other than the ones listed above are not affected by
+extF80_roundingPrecision.
+
+
+
+7. Exceptions and Exception Flags
+
+
+All five exception flags required by the IEEE Floating-Point Standard are
+implemented.
+Each flag is stored as a separate bit in the global variable
+
+uint_fast8_t softfloat_exceptionFlags;
+
+The positions of the exception flag bits within this variable are determined by
+the bit masks
+
+softfloat_flag_inexact
+softfloat_flag_underflow
+softfloat_flag_overflow
+softfloat_flag_infinite
+softfloat_flag_invalid
+
+Variable softfloat_exceptionFlags is initialized to all zeros,
+meaning no exceptions.
+
+
+
+For some SoftFloat ports, softfloat_exceptionFlags may be
+per-thread (declared thread_local), meaning that different
+execution threads have their own separate instances of it.
+
+
+
+An individual exception flag can be cleared with the statement
+
+softfloat_exceptionFlags &= ~softfloat_flag_<exception>;
+
+where <exception> is the appropriate name.
+To raise a floating-point exception, function softfloat_raiseFlags
+should normally be used.
+
+
+
+When SoftFloat detects an exception other than inexact, it calls
+softfloat_raiseFlags.
+The default version of this function simply raises the corresponding exception
+flags.
+Particular ports of SoftFloat may support alternate behavior, such as exception
+traps, by modifying the default softfloat_raiseFlags.
+A program may also supply its own softfloat_raiseFlags function to
+override the one from the SoftFloat library.
+
+
+
+Because inexact results occur frequently under most circumstances (and thus are
+hardly exceptional), SoftFloat does not ordinarily call
+softfloat_raiseFlags for inexact exceptions.
+It does always raise the inexact exception flag as required.
+
+
+
+8. Function Details
+
+
+In this section, <float> appears in function names as
+a substitute for one of these abbreviations:
+
+
+
+f16 |
+indicates float16_t, passed by value |
+
+
+f32 |
+indicates float32_t, passed by value |
+
+
+f64 |
+indicates float64_t, passed by value |
+
+
+extF80M |
+indicates extFloat80_t, passed indirectly via pointers |
+
+
+extF80 |
+indicates extFloat80_t, passed by value |
+
+
+f128M |
+indicates float128_t, passed indirectly via pointers |
+
+
+f128 |
+indicates float128_t, passed by value |
+
+
+
+The circumstances under which values of floating-point types
+extFloat80_t and float128_t may be passed either by
+value or indirectly via pointers was discussed earlier in
+section 4.5, Conventions for Passing Arguments and Results.
+
+
+8.1. Conversions from Integer to Floating-Point
+
+
+All conversions from a 32-bit or 64-bit integer,
+signed or unsigned, to a floating-point format are supported.
+Functions performing these conversions have these names:
+
+ui32_to_<float>
+ui64_to_<float>
+i32_to_<float>
+i64_to_<float>
+
+Conversions from 32-bit integers to 64-bit
+double-precision and larger formats are always exact, and likewise conversions
+from 64-bit integers to 80-bit
+double-extended-precision and 128-bit quadruple-precision are also
+always exact.
+
+
+
+Each conversion function takes one input of the appropriate type and generates
+one output.
+The following illustrates the signatures of these functions in cases when the
+floating-point result is passed either by value or via pointers:
+
+
+float64_t i32_to_f64( int32_t a );
+
+
+void i32_to_f128M( int32_t a, float128_t *destPtr );
+
+
+
+
+8.2. Conversions from Floating-Point to Integer
+
+
+Conversions from a floating-point format to a 32-bit or
+64-bit integer, signed or unsigned, are supported with these
+functions:
+
+<float>_to_ui32
+<float>_to_ui64
+<float>_to_i32
+<float>_to_i64
+
+The functions have signatures as follows, depending on whether the
+floating-point input is passed by value or via pointers:
+
+
+int_fast32_t f64_to_i32( float64_t a, uint_fast8_t roundingMode, bool exact );
+
+
+int_fast32_t
+ f128M_to_i32( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact );
+
+
+
+
+
+The roundingMode argument specifies the rounding mode for
+the conversion.
+The variable that usually indicates rounding mode,
+softfloat_roundingMode, is ignored.
+Argument exact determines whether the inexact
+exception flag is raised if the conversion is not exact.
+If exact is true, the inexact flag may
+be raised;
+otherwise, it will not be, even if the conversion is inexact.
+
+
+
+A conversion from floating-point to integer format raises the invalid
+exception if the source value cannot be rounded to a representable integer of
+the desired size (32 or 64 bits).
+In such circumstances, the integer result returned is determined by the
+particular port of SoftFloat, although typically this value will be either the
+maximum or minimum value of the integer format.
+The functions that convert to integer types never raise the floating-point
+overflow exception.
+
+
+
+Because languages such as C require that conversions to integers
+be rounded toward zero, the following functions are provided for improved speed
+and convenience:
+
+<float>_to_ui32_r_minMag
+<float>_to_ui64_r_minMag
+<float>_to_i32_r_minMag
+<float>_to_i64_r_minMag
+
+These functions round only toward zero (to minimum magnitude).
+The signatures for these functions are the same as above without the redundant
+roundingMode argument:
+
+
+int_fast32_t f64_to_i32_r_minMag( float64_t a, bool exact );
+
+
+int_fast32_t f128M_to_i32_r_minMag( const float128_t *aPtr, bool exact );
+
+
+
+
+8.3. Conversions Among Floating-Point Types
+
+
+Conversions between floating-point formats are done by functions with these
+names:
+
+<float>_to_<float>
+
+All combinations of source and result type are supported where the source and
+result are different formats.
+There are four different styles of signature for these functions, depending on
+whether the input and the output floating-point values are passed by value or
+via pointers:
+
+
+float32_t f64_to_f32( float64_t a );
+
+
+float32_t f128M_to_f32( const float128_t *aPtr );
+
+
+void f32_to_f128M( float32_t a, float128_t *destPtr );
+
+
+void extF80M_to_f128M( const extFloat80_t *aPtr, float128_t *destPtr );
+
+
+
+
+
+Conversions from a smaller to a larger floating-point format are always exact
+and so require no rounding.
+
+
+8.4. Basic Arithmetic Functions
+
+
+The following basic arithmetic functions are provided:
+
+<float>_add
+<float>_sub
+<float>_mul
+<float>_div
+<float>_sqrt
+
+Each floating-point operation takes two operands, except for sqrt
+(square root) which takes only one.
+The operands and result are all of the same floating-point format.
+Signatures for these functions take the following forms:
+
+
+float64_t f64_add( float64_t a, float64_t b );
+
+
+void
+ f128M_add(
+ const float128_t *aPtr, const float128_t *bPtr, float128_t *destPtr );
+
+
+float64_t f64_sqrt( float64_t a );
+
+
+void f128M_sqrt( const float128_t *aPtr, float128_t *destPtr );
+
+
+When floating-point values are passed indirectly through pointers, arguments
+aPtr and bPtr point to the input
+operands, and the last argument, destPtr, points to the
+location where the result is stored.
+
+
+
+Rounding of the 80-bit double-extended-precision
+(extFloat80_t) functions is affected by variable
+extF80_roundingPrecision, as explained earlier in
+section 6.3,
+Rounding Precision for the 80-Bit Extended Format.
+
+
+8.5. Fused Multiply-Add Functions
+
+
+The 2008 version of the IEEE Floating-Point Standard defines a fused
+multiply-add operation that does a combined multiplication and addition
+with only a single rounding.
+SoftFloat implements fused multiply-add with functions
+
+<float>_mulAdd
+
+Unlike other operations, fused multiple-add is not supported for the
+80-bit double-extended-precision format,
+extFloat80_t.
+
+
+
+Depending on whether floating-point values are passed by value or via pointers,
+the fused multiply-add functions have signatures of these forms:
+
+
+float64_t f64_mulAdd( float64_t a, float64_t b, float64_t c );
+
+
+void
+ f128M_mulAdd(
+ const float128_t *aPtr,
+ const float128_t *bPtr,
+ const float128_t *cPtr,
+ float128_t *destPtr
+ );
+
+
+The functions compute
+(a × b)
+ + c
+with a single rounding.
+When floating-point values are passed indirectly through pointers, arguments
+aPtr, bPtr, and
+cPtr point to operands a,
+b, and c respectively, and
+destPtr points to the location where the result is stored.
+
+
+
+If one of the multiplication operands a and
+b is infinite and the other is zero, these functions raise
+the invalid exception even if operand c is a quiet NaN.
+
+
+8.6. Remainder Functions
+
+
+For each format, SoftFloat implements the remainder operation defined by the
+IEEE Floating-Point Standard.
+The remainder functions have names
+
+<float>_rem
+
+Each remainder operation takes two floating-point operands of the same format
+and returns a result in the same format.
+Depending on whether floating-point values are passed by value or via pointers,
+the remainder functions have signatures of these forms:
+
+
+float64_t f64_rem( float64_t a, float64_t b );
+
+
+void
+ f128M_rem(
+ const float128_t *aPtr, const float128_t *bPtr, float128_t *destPtr );
+
+
+When floating-point values are passed indirectly through pointers, arguments
+aPtr and bPtr point to operands
+a and b respectively, and
+destPtr points to the location where the result is stored.
+
+
+
+The IEEE Standard remainder operation computes the value
+a
+ − n × b,
+where n is the integer closest to
+a ÷ b.
+If a ÷ b is exactly
+halfway between two integers, n is the even integer closest to
+a ÷ b.
+The IEEE Standard’s remainder operation is always exact and so requires
+no rounding.
+
+
+
+Depending on the relative magnitudes of the operands, the remainder
+functions can take considerably longer to execute than the other SoftFloat
+functions.
+This is an inherent characteristic of the remainder operation itself and is not
+a flaw in the SoftFloat implementation.
+
+
+8.7. Round-to-Integer Functions
+
+
+For each format, SoftFloat implements the round-to-integer operation specified
+by the IEEE Floating-Point Standard.
+These functions are named
+
+<float>_roundToInt
+
+Each round-to-integer operation takes a single floating-point operand.
+This operand is rounded to an integer according to a specified rounding mode,
+and the resulting integer value is returned in the same floating-point format.
+(Note that the result is not an integer type.)
+
+
+
+The signatures of the round-to-integer functions are similar to those for
+conversions to an integer type:
+
+
+float64_t f64_roundToInt( float64_t a, uint_fast8_t roundingMode, bool exact );
+
+
+void
+ f128M_roundToInt(
+ const float128_t *aPtr,
+ uint_fast8_t roundingMode,
+ bool exact,
+ float128_t *destPtr
+ );
+
+
+When floating-point values are passed indirectly through pointers,
+aPtr points to the input operand and
+destPtr points to the location where the result is stored.
+
+
+
+The roundingMode argument specifies the rounding mode to
+apply.
+The variable that usually indicates rounding mode,
+softfloat_roundingMode, is ignored.
+Argument exact determines whether the inexact
+exception flag is raised if the conversion is not exact.
+If exact is true, the inexact flag may
+be raised;
+otherwise, it will not be, even if the conversion is inexact.
+
+
+8.8. Comparison Functions
+
+
+For each format, the following floating-point comparison functions are
+provided:
+
+<float>_eq
+<float>_le
+<float>_lt
+
+Each comparison takes two operands of the same type and returns a Boolean.
+The abbreviation eq stands for “equal” (=);
+le stands for “less than or equal” (≤);
+and lt stands for “less than” (<).
+Depending on whether the floating-point operands are passed by value or via
+pointers, the comparison functions have signatures of these forms:
+
+
+bool f64_eq( float64_t a, float64_t b );
+
+
+bool f128M_eq( const float128_t *aPtr, const float128_t *bPtr );
+
+
+
+
+
+The usual greater-than (>), greater-than-or-equal (≥), and not-equal
+(≠) comparisons are easily obtained from the functions provided.
+The not-equal function is just the logical complement of the equal function.
+The greater-than-or-equal function is identical to the less-than-or-equal
+function with the arguments in reverse order, and likewise the greater-than
+function is identical to the less-than function with the arguments reversed.
+
+
+
+The IEEE Floating-Point Standard specifies that the less-than-or-equal and
+less-than comparisons by default raise the invalid exception if either
+operand is any kind of NaN.
+Equality comparisons, on the other hand, are defined by default to raise the
+invalid exception only for signaling NaNs, not quiet NaNs.
+For completeness, SoftFloat provides these complementary functions:
+
+<float>_eq_signaling
+<float>_le_quiet
+<float>_lt_quiet
+
+The signaling equality comparisons are identical to the default
+equality comparisons except that the invalid exception is raised for any
+NaN input, not just for signaling NaNs.
+Similarly, the quiet comparison functions are identical to their
+default counterparts except that the invalid exception is not raised for
+quiet NaNs.
+
+
+8.9. Signaling NaN Test Functions
+
+
+Functions for testing whether a floating-point value is a signaling NaN are
+provided with these names:
+
+<float>_isSignalingNaN
+
+The functions take one floating-point operand and return a Boolean indicating
+whether the operand is a signaling NaN.
+Accordingly, the functions have the forms
+
+
+bool f64_isSignalingNaN( float64_t a );
+
+
+bool f128M_isSignalingNaN( const float128_t *aPtr );
+
+
+
+
+8.10. Raise-Exception Function
+
+
+SoftFloat provides a single function for raising floating-point exceptions:
+
+
+void softfloat_raiseFlags( uint_fast8_t exceptions );
+
+
+The exceptions argument is a mask indicating the set of
+exceptions to raise.
+(See earlier section 7, Exceptions and Exception Flags.)
+In addition to setting the specified exception flags in variable
+softfloat_exceptionFlags, the softfloat_raiseFlags
+function may cause a trap or abort appropriate for the current system.
+
+
+
+9. Changes from SoftFloat Release 2
+
+
+Apart from a change in the legal use license, Release 3 of
+SoftFloat introduced numerous technical differences compared to earlier
+releases.
+
+
+9.1. Name Changes
+
+
+The most obvious and pervasive difference compared to Release 2
+is that the names of most functions and variables have changed, even when the
+behavior has not.
+First, the floating-point types, the mode variables, the exception flags
+variable, the function to raise exceptions, and various associated constants
+have been renamed as follows:
+
+
+
+| old name, Release 2: |
+new name, Release 3: |
+
+
+float32 |
+float32_t |
+
+
+float64 |
+float64_t |
+
+
+floatx80 |
+extFloat80_t |
+
+
+float128 |
+float128_t |
+
+
+float_rounding_mode |
+softfloat_roundingMode |
+
+
+float_round_nearest_even |
+softfloat_round_near_even |
+
+
+float_round_to_zero |
+softfloat_round_minMag |
+
+
+float_round_down |
+softfloat_round_min |
+
+
+float_round_up |
+softfloat_round_max |
+
+
+float_detect_tininess |
+softfloat_detectTininess |
+
+
+float_tininess_before_rounding |
+softfloat_tininess_beforeRounding |
+
+
+float_tininess_after_rounding |
+softfloat_tininess_afterRounding |
+
+
+floatx80_rounding_precision |
+extF80_roundingPrecision |
+
+
+float_exception_flags |
+softfloat_exceptionFlags |
+
+
+float_flag_inexact |
+softfloat_flag_inexact |
+
+
+float_flag_underflow |
+softfloat_flag_underflow |
+
+
+float_flag_overflow |
+softfloat_flag_overflow |
+
+
+float_flag_divbyzero |
+softfloat_flag_infinite |
+
+
+float_flag_invalid |
+softfloat_flag_invalid |
+
+
+float_raise |
+softfloat_raiseFlags |
+
+
+
+
+
+
+Furthermore, Release 3 adopted the following new abbreviations for
+function names:
+
+
+
+used in names in Release 2: |
+used in names in Release 3: |
+
+ int32 | i32 |
+ int64 | i64 |
+ float32 | f32 |
+ float64 | f64 |
+ floatx80 | extF80 |
+ float128 | f128 |
+
+
+Thus, for example, the function to add two 32-bit floating-point
+numbers, previously called float32_add in Release 2,
+is now f32_add.
+Lastly, there have been a few other changes to function names:
+
+
+
+used in names in Release 2: |
+used in names in Release 3: |
+relevant functions: |
+
+
+_round_to_zero |
+_r_minMag |
+conversions from floating-point to integer (section 8.2) |
+
+
+round_to_int |
+roundToInt |
+round-to-integer functions (section 8.7) |
+
+
+is_signaling_nan |
+isSignalingNaN |
+signaling NaN test functions (section 8.9) |
+
+
+
+
+
+9.2. Changes to Function Arguments
+
+
+Besides simple name changes, some operations were given a different interface
+in Release 3 than they had in Release 2:
+
+
+-
+
+Since Release 3, integer arguments and results of functions have
+standard types from header <stdint.h>, such as
+uint32_t, whereas previously their types could be defined
+differently for each port of SoftFloat, usually using traditional C types such
+as unsigned int.
+Likewise, functions in Release 3 and later pass Booleans as
+standard type bool from <stdbool.h>, whereas
+previously these were again passed as a port-specific type (usually
+int).
+
+
+ -
+
+As explained earlier in section 4.5, Conventions for Passing
+Arguments and Results, SoftFloat functions in Release 3 and
+later may pass 80-bit and 128-bit floating-point
+values through pointers, meaning that functions take pointer arguments and then
+read or write floating-point values at the locations indicated by the pointers.
+In Release 2, floating-point arguments and results were always
+passed by value, regardless of their size.
+
+
+ -
+
+Functions that round to an integer have additional
+roundingMode and exact arguments that
+they did not have in Release 2.
+Refer to sections 8.2 and 8.7 for descriptions of these functions
+since Release 3.
+For Release 2, the rounding mode, when needed, was taken from the
+same global variable that affects the basic arithmetic operations (now called
+softfloat_roundingMode but previously known as
+float_rounding_mode).
+Also, for Release 2, if the original floating-point input was not
+an exact integer value, and if the invalid exception was not raised by
+the function, the inexact exception was always raised.
+Release 2 had no option to suppress raising inexact in this
+case.
+Applications using SoftFloat Release 3 or later can get the same
+effect as Release 2 by passing variable
+softfloat_roundingMode for argument
+roundingMode and true for argument
+exact.
+
+
+
+
+
+9.3. Added Capabilities
+
+
+With Release 3, some new features have been added that were not
+present in Release 2:
+
+
+-
+
+A port of SoftFloat can now define any of the floating-point types
+float32_t, float64_t, extFloat80_t, and
+float128_t as aliases for C’s standard floating-point types
+float, double, and long
+double, using either #define or typedef.
+This potential convenience was not supported under Release 2.
+
+
+
+(Note, however, that there may be a performance cost to defining
+SoftFloat’s floating-point types this way, depending on the platform and
+the applications using SoftFloat.
+Ports of SoftFloat may choose to forgo the convenience in favor of better
+speed.)
+
+
+
+
-
+As of Release 3b, 16-bit half-precision,
+
float16_t, is supported.
+
+
+
+
-
+Functions have been added for converting between the floating-point types and
+unsigned integers.
+Release 2 supported only signed integers, not unsigned.
+
+
+
+
-
+Fused multiply-add functions have been added for all floating-point formats
+except 80-bit double-extended-precision,
+
extFloat80_t.
+
+
+
+
-
+New rounding modes are supported:
+
softfloat_round_near_maxMag (round to nearest, with ties to
+maximum magnitude, away from zero), and, as of Release 3c,
+optional softfloat_round_odd (round to odd, also known as
+jamming).
+
+
+
+
+
+9.4. Better Compatibility with the C Language
+
+
+Release 3 of SoftFloat was written to conform better to the ISO C
+Standard’s rules for portability.
+For example, older releases of SoftFloat employed type conversions in ways
+that, while commonly practiced, are not fully defined by the C Standard.
+Such problematic type conversions have generally been replaced by the use of
+unions, the behavior around which is more strictly regulated these days.
+
+
+9.5. New Organization as a Library
+
+
+Starting with Release 3, SoftFloat now builds as a library.
+Previously, SoftFloat compiled into a single, monolithic object file containing
+all the SoftFloat functions, with the consequence that a program linking with
+SoftFloat would get every SoftFloat function in its binary file even if only a
+few functions were actually used.
+With SoftFloat in the form of a library, a program that is linked by a standard
+linker will include only those functions of SoftFloat that it needs and no
+others.
+
+
+9.6. Optimization Gains (and Losses)
+
+
+Individual SoftFloat functions have been variously improved in
+Release 3 compared to earlier releases.
+In particular, better, faster algorithms have been deployed for the operations
+of division, square root, and remainder.
+For functions operating on the larger 80-bit and
+128-bit formats, extFloat80_t and
+float128_t, code size has also generally been reduced.
+
+
+
+However, because Release 2 compiled all of SoftFloat together as a
+single object file, compilers could make optimizations across function calls
+when one SoftFloat function calls another.
+Now that the functions of SoftFloat are compiled separately and only afterward
+linked together into a program, there is not usually the same opportunity to
+optimize across function calls.
+Some loss of speed has been observed due to this change.
+
+
+
+10. Future Directions
+
+
+The following improvements are anticipated for future releases of SoftFloat:
+
+-
+more functions from the 2008 version of the IEEE Floating-Point Standard;
+
-
+consistent, defined behavior for non-canonical representations of extended
+format
extFloat80_t (discussed in section 4.4,
+Non-canonical Representations in extFloat80_t).
+
+
+
+
+
+11. Contact Information
+
+
+At the time of this writing, the most up-to-date information about SoftFloat
+and the latest release can be found at the Web page
+http://www.jhauser.us/arithmetic/SoftFloat.html.
+
+
+
+
+
diff --git a/src/cpu/softfloat3e/extF80_addsub.cc b/src/cpu/softfloat3e/extF80_addsub.cc
new file mode 100644
index 000000000..a60d2c6be
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_addsub.cc
@@ -0,0 +1,106 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extern extFloat80_t softfloat_addMagsExtF80(uint16_t, uint64_t, uint16_t, uint64_t, bool, struct softfloat_status_t *);
+extern extFloat80_t softfloat_subMagsExtF80(uint16_t, uint64_t, uint16_t, uint64_t, bool, struct softfloat_status_t *);
+
+extFloat80_t extF80_add(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ uint16_t uiB64;
+ uint64_t uiB0;
+ bool signB;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ a.signExp = defaultNaNExtF80UI64;
+ a.signif = defaultNaNExtF80UI0;
+ return a;
+ }
+
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+
+ uiB64 = b.signExp;
+ uiB0 = b.signif;
+ signB = signExtF80UI64(uiB64);
+
+ if (signA == signB) {
+ return softfloat_addMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status);
+ } else {
+ return softfloat_subMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status);
+ }
+}
+
+extFloat80_t extF80_sub(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ uint16_t uiB64;
+ uint64_t uiB0;
+ bool signB;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ a.signExp = defaultNaNExtF80UI64;
+ a.signif = defaultNaNExtF80UI0;
+ return a;
+ }
+
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+
+ uiB64 = b.signExp;
+ uiB0 = b.signif;
+ signB = signExtF80UI64(uiB64);
+
+ if (signA == signB) {
+ return softfloat_subMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status);
+ } else {
+ return softfloat_addMagsExtF80(uiA64, uiA0, uiB64, uiB0, signA, status);
+ }
+}
diff --git a/src/cpu/softfloat3e/extF80_class.cc b/src/cpu/softfloat3e/extF80_class.cc
new file mode 100644
index 000000000..155dc51a2
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_class.cc
@@ -0,0 +1,71 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "softfloat.h"
+
+softfloat_class_t extF80_class(extFloat80_t a)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+
+ if (! expA) {
+ if (! sigA) return softfloat_zero;
+ return softfloat_denormal; /* denormal or pseudo-denormal */
+ }
+
+ /* valid numbers have the MS bit set */
+ if (!(sigA & UINT64_C(0x8000000000000000)))
+ return softfloat_SNaN; /* report unsupported as SNaNs */
+
+ if (expA == 0x7FFF) {
+ if ((sigA<<1) == 0)
+ return (signA) ? softfloat_negative_inf : softfloat_positive_inf;
+
+ return (sigA & UINT64_C(0x4000000000000000)) ? softfloat_QNaN : softfloat_SNaN;
+ }
+
+ return softfloat_normalized;
+}
diff --git a/src/cpu/softfloat3e/extF80_compare.cc b/src/cpu/softfloat3e/extF80_compare.cc
new file mode 100644
index 000000000..f8a360a41
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_compare.cc
@@ -0,0 +1,147 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include <86box/86box.h>
+#include "../cpu.h"
+
+#include "internals.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Compare between two extended precision floating point numbers. Returns
+| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
+| the value 'a' is less than the corresponding value `b',
+| 'float_relation_greater' if the value 'a' is greater than the corresponding
+| value `b', or 'float_relation_unordered' otherwise.
+*----------------------------------------------------------------------------*/
+
+int extF80_compare(extFloat80_t a, extFloat80_t b, int quiet, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+
+ uint16_t uiB64;
+ uint64_t uiB0;
+ bool signB;
+ int32_t expB;
+ uint64_t sigB;
+
+ struct exp32_sig64 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ softfloat_class_t aClass = extF80_class(a);
+ softfloat_class_t bClass = extF80_class(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (fpu_type < FPU_287XL) {
+ if ((aClass == softfloat_positive_inf) && (bClass == softfloat_negative_inf))
+ {
+ return softfloat_relation_equal;
+ }
+
+ if ((aClass == softfloat_negative_inf) && (bClass == softfloat_positive_inf))
+ {
+ return softfloat_relation_equal;
+ }
+ }
+
+ if (aClass == softfloat_SNaN || bClass == softfloat_SNaN)
+ {
+ /* unsupported reported as SNaN */
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+
+ if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) {
+ if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (aClass == softfloat_denormal || bClass == softfloat_denormal) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+
+ uiB64 = b.signExp;
+ uiB0 = b.signif;
+ signB = signExtF80UI64(uiB64);
+ expB = expExtF80UI64(uiB64);
+ sigB = uiB0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (aClass == softfloat_zero) {
+ if (bClass == softfloat_zero) return softfloat_relation_equal;
+ return signB ? softfloat_relation_greater : softfloat_relation_less;
+ }
+
+ if (bClass == softfloat_zero || signA != signB) {
+ return signA ? softfloat_relation_less : softfloat_relation_greater;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (aClass == softfloat_denormal) {
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA += normExpSig.exp + 1;
+ sigA = normExpSig.sig;
+ }
+ if (bClass == softfloat_denormal) {
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
+ expB += normExpSig.exp + 1;
+ sigB = normExpSig.sig;
+ }
+
+ if (expA == expB && sigA == sigB)
+ return softfloat_relation_equal;
+
+ int less_than =
+ signA ? ((expB < expA) || ((expB == expA) && (sigB < sigA)))
+ : ((expA < expB) || ((expA == expB) && (sigA < sigB)));
+
+ if (less_than) return softfloat_relation_less;
+ return softfloat_relation_greater;
+}
diff --git a/src/cpu/softfloat3e/extF80_div.cc b/src/cpu/softfloat3e/extF80_div.cc
new file mode 100644
index 000000000..e4b1fbb24
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_div.cc
@@ -0,0 +1,188 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t extF80_div(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+ uint16_t uiB64;
+ uint64_t uiB0;
+ bool signB;
+ int32_t expB;
+ uint64_t sigB;
+ bool signZ;
+ struct exp32_sig64 normExpSig;
+ int32_t expZ;
+ struct uint128 rem;
+ uint32_t recip32;
+ uint64_t sigZ;
+ int ix;
+ uint64_t q64;
+ uint32_t q;
+ struct uint128 term;
+ uint64_t sigZExtra;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b))
+ goto invalid;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+ uiB64 = b.signExp;
+ uiB0 = b.signif;
+ signB = signExtF80UI64(uiB64);
+ expB = expExtF80UI64(uiB64);
+ sigB = uiB0;
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if (sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
+ if (expB == 0x7FFF) {
+ if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
+ goto invalid;
+ }
+ if (! expB && sigB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToExtF80(signZ, 0x7FFF, UINT64_C(0x8000000000000000));
+ }
+ if (expB == 0x7FFF) {
+ if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
+ if (! expA && sigA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToExtF80(signZ, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expB) {
+ expB = 1;
+ if (sigB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (! (sigB & UINT64_C(0x8000000000000000))) {
+ if (! sigB) {
+ if (! sigA) goto invalid;
+ softfloat_raiseFlags(status, softfloat_flag_infinite);
+ return packToExtF80(signZ, 0x7FFF, UINT64_C(0x8000000000000000));
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
+ expB += normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ if (! expA) {
+ expA = 1;
+ if (sigA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (! (sigA & UINT64_C(0x8000000000000000))) {
+ if (! sigA) return packToExtF80(signZ, 0, 0);
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA += normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA - expB + 0x3FFF;
+ if (sigA < sigB) {
+ --expZ;
+ rem = softfloat_shortShiftLeft128(0, sigA, 32);
+ } else {
+ rem = softfloat_shortShiftLeft128(0, sigA, 31);
+ }
+ recip32 = softfloat_approxRecip32_1(sigB>>32);
+ sigZ = 0;
+ ix = 2;
+ for (;;) {
+ q64 = (uint64_t) (uint32_t) (rem.v64>>2) * recip32;
+ q = (q64 + 0x80000000)>>32;
+ --ix;
+ if (ix < 0) break;
+ rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
+ term = softfloat_mul64ByShifted32To128(sigB, q);
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ --q;
+ rem = softfloat_add128(rem.v64, rem.v0, sigB>>32, sigB<<32);
+ }
+ sigZ = (sigZ<<29) + q;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (((q + 1) & 0x3FFFFF) < 2) {
+ rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
+ term = softfloat_mul64ByShifted32To128(sigB, q);
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ term = softfloat_shortShiftLeft128(0, sigB, 32);
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ --q;
+ rem = softfloat_add128(rem.v64, rem.v0, term.v64, term.v0);
+ } else if (softfloat_le128(term.v64, term.v0, rem.v64, rem.v0)) {
+ ++q;
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ }
+ if (rem.v64 | rem.v0) q |= 1;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sigZ = (sigZ<<6) + (q>>23);
+ sigZExtra = (uint64_t) ((uint64_t) q<<41);
+ return
+ softfloat_roundPackToExtF80(signZ, expZ, sigZ, sigZExtra, softfloat_extF80_roundingPrecision(status), status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
+}
diff --git a/src/cpu/softfloat3e/extF80_extract.cc b/src/cpu/softfloat3e/extF80_extract.cc
new file mode 100644
index 000000000..692190a47
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_extract.cc
@@ -0,0 +1,97 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Separate the source extended double-precision floating point value `a'
+| into its exponent and significand, store the significant back to the
+| 'a' and return the exponent. The operation performed is a superset of
+| the IEC/IEEE recommended logb(x) function.
+*----------------------------------------------------------------------------*/
+
+extFloat80_t extF80_extract(extFloat80_t *a, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+ struct exp32_sig64 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(*a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ *a = packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
+ return *a;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a->signExp;
+ uiA0 = a->signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if (sigA<<1) {
+ *a = softfloat_propagateNaNExtF80UI(uiA64, uiA0, 0, 0, status);
+ return *a;
+ }
+ return packToExtF80(0, 0x7FFF, BX_CONST64(0x8000000000000000));
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) {
+ softfloat_raiseFlags(status, softfloat_flag_divbyzero);
+ *a = packToExtF80(signA, 0, 0);
+ return packToExtF80(1, 0x7FFF, BX_CONST64(0x8000000000000000));
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA = normExpSig.exp + 1;
+ sigA = normExpSig.sig;
+ }
+
+ *a = packToExtF80(signA, 0x3FFF, sigA);
+ return i32_to_extF80(expA - 0x3FFF);
+}
diff --git a/src/cpu/softfloat3e/extF80_mul.cc b/src/cpu/softfloat3e/extF80_mul.cc
new file mode 100644
index 000000000..d38e97f02
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_mul.cc
@@ -0,0 +1,153 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t extF80_mul(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+ uint16_t uiB64;
+ uint64_t uiB0;
+ bool signB;
+ int32_t expB;
+ uint64_t sigB;
+ bool signZ;
+ uint64_t magBits;
+ struct exp32_sig64 normExpSig;
+ int32_t expZ;
+ struct uint128 sig128Z;
+ uint16_t uiZ64;
+ uint64_t uiZ0;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+ uiB64 = b.signExp;
+ uiB0 = b.signif;
+ signB = signExtF80UI64(uiB64);
+ expB = expExtF80UI64(uiB64);
+ sigB = uiB0;
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if ((sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) || ((expB == 0x7FFF) && (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)))) {
+ goto propagateNaN;
+ }
+ magBits = expB | sigB;
+ goto infArg;
+ }
+ if (expB == 0x7FFF) {
+ if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
+ magBits = expA | sigA;
+ goto infArg;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ expA = 1;
+ if (sigA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (! (sigA & UINT64_C(0x8000000000000000))) {
+ if (! sigA) {
+ if (! expB && sigB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToExtF80(signZ, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA += normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ expB = 1;
+ if (sigB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (! (sigB & UINT64_C(0x8000000000000000))) {
+ if (! sigB) return packToExtF80(signZ, 0, 0);
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
+ expB += normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA + expB - 0x3FFE;
+ sig128Z = softfloat_mul64To128(sigA, sigB);
+ if (sig128Z.v64 < UINT64_C(0x8000000000000000)) {
+ --expZ;
+ sig128Z = softfloat_add128(sig128Z.v64, sig128Z.v0, sig128Z.v64, sig128Z.v0);
+ }
+ return
+ softfloat_roundPackToExtF80(signZ, expZ, sig128Z.v64, sig128Z.v0, softfloat_extF80_roundingPrecision(status), status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infArg:
+ if (! magBits) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ64 = defaultNaNExtF80UI64;
+ uiZ0 = defaultNaNExtF80UI0;
+ } else {
+ if ((! expA && sigA) || (! expB && sigB))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ uiZ64 = packToExtF80UI64(signZ, 0x7FFF);
+ uiZ0 = UINT64_C(0x8000000000000000);
+ }
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+}
diff --git a/src/cpu/softfloat3e/extF80_rem.cc b/src/cpu/softfloat3e/extF80_rem.cc
new file mode 100644
index 000000000..39d233a7e
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_rem.cc
@@ -0,0 +1,199 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t extF80_rem(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+ uint16_t uiB64;
+ uint64_t uiB0;
+ int32_t expB;
+ uint64_t sigB;
+ struct exp32_sig64 normExpSig;
+ int32_t expDiff;
+ struct uint128 rem, shiftedSigB;
+ uint32_t q, recip32;
+ uint64_t q64;
+ struct uint128 term, altRem, meanRem;
+ bool signRem;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b))
+ goto invalid;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+ uiB64 = b.signExp;
+ uiB0 = b.signif;
+ expB = expExtF80UI64(uiB64);
+ sigB = uiB0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if ((sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) || ((expB == 0x7FFF) && (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)))) {
+ goto propagateNaN;
+ }
+ goto invalid;
+ }
+ if (expB == 0x7FFF) {
+ if (sigB & UINT64_C(0x7FFFFFFFFFFFFFFF)) goto propagateNaN;
+ /*--------------------------------------------------------------------
+ | Argument b is an infinity. Doubling `expB' is an easy way to ensure
+ | that `expDiff' later is less than -1, which will result in returning
+ | a canonicalized version of argument a.
+ *--------------------------------------------------------------------*/
+ expB += expB;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expB) {
+ expB = 1;
+ if (sigB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (! (sigB & UINT64_C(0x8000000000000000))) {
+ if (! sigB) goto invalid;
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
+ expB += normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ if (! expA) {
+ expA = 1;
+ if (sigA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (! (sigA & UINT64_C(0x8000000000000000))) {
+ if (! sigA) {
+ expA = 0;
+ goto copyA;
+ }
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA += normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expA - expB;
+ if (expDiff < -1) goto copyA;
+ rem = softfloat_shortShiftLeft128(0, sigA, 32);
+ shiftedSigB = softfloat_shortShiftLeft128(0, sigB, 32);
+ if (expDiff < 1) {
+ if (expDiff) {
+ --expB;
+ shiftedSigB = softfloat_shortShiftLeft128(0, sigB, 33);
+ q = 0;
+ } else {
+ q = (sigB <= sigA);
+ if (q) {
+ rem = softfloat_sub128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0);
+ }
+ }
+ } else {
+ recip32 = softfloat_approxRecip32_1(sigB>>32);
+ expDiff -= 30;
+ for (;;) {
+ q64 = (uint64_t) (uint32_t) (rem.v64>>2) * recip32;
+ if (expDiff < 0) break;
+ q = (q64 + 0x80000000)>>32;
+ rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
+ term = softfloat_mul64ByShifted32To128(sigB, q);
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ rem = softfloat_add128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0);
+ }
+ expDiff -= 29;
+ }
+ /*--------------------------------------------------------------------
+ | (`expDiff' cannot be less than -29 here.)
+ *--------------------------------------------------------------------*/
+ q = (uint32_t) (q64>>32)>>(~expDiff & 31);
+ rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, expDiff + 30);
+ term = softfloat_mul64ByShifted32To128(sigB, q);
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ altRem = softfloat_add128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0);
+ goto selectRem;
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ do {
+ altRem = rem;
+ ++q;
+ rem = softfloat_sub128(rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0);
+ } while (! (rem.v64 & UINT64_C(0x8000000000000000)));
+ selectRem:
+ meanRem = softfloat_add128(rem.v64, rem.v0, altRem.v64, altRem.v0);
+ if ((meanRem.v64 & UINT64_C(0x8000000000000000)) || (! (meanRem.v64 | meanRem.v0) && (q & 1))) {
+ rem = altRem;
+ }
+ signRem = signA;
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ signRem = ! signRem;
+ rem = softfloat_sub128(0, 0, rem.v64, rem.v0);
+ }
+ return softfloat_normRoundPackToExtF80(signRem, rem.v64 | rem.v0 ? expB + 32 : 0, rem.v64, rem.v0, 80, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ copyA:
+ if (expA < 1) {
+ sigA >>= 1 - expA;
+ expA = 0;
+ }
+ return packToExtF80(signA, expA, sigA);
+}
diff --git a/src/cpu/softfloat3e/extF80_roundToInt.cc b/src/cpu/softfloat3e/extF80_roundToInt.cc
new file mode 100644
index 000000000..f71cdfc50
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_roundToInt.cc
@@ -0,0 +1,123 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t
+ extF80_roundToInt(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64, signUI64;
+ int32_t exp;
+ uint64_t sigA;
+ uint16_t uiZ64;
+ uint64_t sigZ;
+ uint64_t lastBitMask, roundBitsMask;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ signUI64 = uiA64 & packToExtF80UI64(1, 0);
+ exp = expExtF80UI64(uiA64);
+ sigA = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (0x403E <= exp) {
+ if ((exp == 0x7FFF) && (uint64_t) (sigA<<1)) {
+ return softfloat_propagateNaNExtF80UI(uiA64, sigA, 0, 0, status);
+ }
+ return a;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp <= 0x3FFE) {
+ if (! exp) {
+ if ((sigA<<1) == 0) return a;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ switch (roundingMode) {
+ case softfloat_round_near_even:
+ if (!(sigA & UINT64_C(0x7FFFFFFFFFFFFFFF))) break;
+ case softfloat_round_near_maxMag:
+ if (exp == 0x3FFE) goto mag1;
+ break;
+ case softfloat_round_min:
+ if (signUI64) goto mag1;
+ break;
+ case softfloat_round_max:
+ if (!signUI64) goto mag1;
+ break;
+ }
+ return packToExtF80(signUI64, 0, 0);
+ mag1:
+ softfloat_setRoundingUp(status);
+ return packToExtF80(signUI64, 0x3FFF, UINT64_C(0x8000000000000000));
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ64 = signUI64 | exp;
+ lastBitMask = (uint64_t) 1<<(0x403E - exp);
+ roundBitsMask = lastBitMask - 1;
+ sigZ = sigA;
+ if (roundingMode == softfloat_round_near_maxMag) {
+ sigZ += lastBitMask>>1;
+ } else if (roundingMode == softfloat_round_near_even) {
+ sigZ += lastBitMask>>1;
+ if (!(sigZ & roundBitsMask)) sigZ &= ~lastBitMask;
+ } else if (roundingMode == (signUI64 ? softfloat_round_min : softfloat_round_max)) {
+ sigZ += roundBitsMask;
+ }
+ sigZ &= ~roundBitsMask;
+ if (!sigZ) {
+ ++uiZ64;
+ sigZ = UINT64_C(0x8000000000000000);
+ softfloat_setRoundingUp(status);
+ }
+ if (sigZ != sigA) {
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ if (sigZ > sigA)
+ softfloat_setRoundingUp(status);
+ }
+ return packToExtF80_twoargs(uiZ64, sigZ);
+}
diff --git a/src/cpu/softfloat3e/extF80_scale.cc b/src/cpu/softfloat3e/extF80_scale.cc
new file mode 100644
index 000000000..48bd53afd
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_scale.cc
@@ -0,0 +1,136 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Scales extended double-precision floating-point value in operand `a' by
+| value `b'. The function truncates the value in the second operand 'b' to
+| an integral value and adds that value to the exponent of the operand 'a'.
+| The operation performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+extFloat80_t extF80_scale(extFloat80_t a, extFloat80_t b, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+ uint16_t uiB64;
+ uint64_t uiB0;
+ bool signB;
+ int32_t expB;
+ uint64_t sigB;
+ struct exp32_sig64 normExpSig;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+ uiB64 = b.signExp;
+ uiB0 = b.signif;
+ signB = signExtF80UI64(uiB64);
+ expB = expExtF80UI64(uiB64);
+ sigB = uiB0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+
+ if (expA == 0x7FFF) {
+ if ((sigA<<1) || ((expB == 0x7FFF) && (sigB<<1))) {
+ return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
+ }
+ if ((expB == 0x7FFF) && signB) goto invalid;
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return a;
+ }
+ if (expB == 0x7FFF) {
+ if (sigB<<1) {
+ return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
+ }
+ if ((expA | sigA) == 0) {
+ if (! signB) goto invalid;
+ return a;
+ }
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ if (signB) return packToExtF80(signA, 0, 0);
+ return packToExtF80(signA, 0x7FFF, BX_CONST64(0x8000000000000000));
+ }
+ if (! expA) {
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ if (! sigA) return a;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA = normExpSig.exp + 1;
+ sigA = normExpSig.sig;
+ if (expB < 0x3FFF)
+ return softfloat_normRoundPackToExtF80(signA, expA, sigA, 0, 80, status);
+ }
+ if (!expB) {
+ if (!sigB) return a;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
+ expB = normExpSig.exp + 1;
+ sigB = normExpSig.sig;
+ }
+
+ if (expB > 0x400E) {
+ /* generate appropriate overflow/underflow */
+ return softfloat_roundPackToExtF80(signA, signB ? -0x3FFF : 0x7FFF, sigA, 0, 80, status);
+ }
+
+ if (expB < 0x3FFF) return a;
+
+ int shiftCount = 0x403E - expB;
+ sigB >>= shiftCount;
+ int32_t scale = (int32_t) sigB;
+ if (signB) scale = -scale; /* -32768..32767 */
+
+ return softfloat_roundPackToExtF80(signA, expA + scale, sigA, 0, 80, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_sqrt.cc b/src/cpu/softfloat3e/extF80_sqrt.cc
new file mode 100644
index 000000000..1a5d52e5d
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_sqrt.cc
@@ -0,0 +1,159 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t extF80_sqrt(extFloat80_t a, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool signA;
+ int32_t expA;
+ uint64_t sigA;
+ struct exp32_sig64 normExpSig;
+ int32_t expZ;
+ uint32_t sig32A, recipSqrt32, sig32Z;
+ struct uint128 rem;
+ uint64_t q, x64, sigZ;
+ struct uint128 y, term;
+ uint64_t sigZExtra;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a))
+ goto invalid;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ signA = signExtF80UI64(uiA64);
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if (sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) {
+ return softfloat_propagateNaNExtF80UI(uiA64, uiA0, 0, 0, status);
+ }
+ if (! signA) return a;
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (signA) {
+ if ((expA | sigA) == 0) return packToExtF80(signA, 0, 0);
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ expA = 1;
+ if (sigA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ if (! (sigA & UINT64_C(0x8000000000000000))) {
+ if (! sigA) return packToExtF80(signA, 0, 0);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA += normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ | (`sig32Z' is guaranteed to be a lower bound on the square root of
+ | `sig32A', which makes `sig32Z' also a lower bound on the square root of
+ | `sigA'.)
+ *------------------------------------------------------------------------*/
+ expZ = ((expA - 0x3FFF)>>1) + 0x3FFF;
+ expA &= 1;
+ sig32A = sigA>>32;
+ recipSqrt32 = softfloat_approxRecipSqrt32_1(expA, sig32A);
+ sig32Z = ((uint64_t) sig32A * recipSqrt32)>>32;
+ if (expA) {
+ sig32Z >>= 1;
+ rem = softfloat_shortShiftLeft128(0, sigA, 61);
+ } else {
+ rem = softfloat_shortShiftLeft128(0, sigA, 62);
+ }
+ rem.v64 -= (uint64_t) sig32Z * sig32Z;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ q = ((uint32_t) (rem.v64>>2) * (uint64_t) recipSqrt32)>>32;
+ x64 = (uint64_t) sig32Z<<32;
+ sigZ = x64 + (q<<3);
+ y = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
+ /*------------------------------------------------------------------------
+ | (Repeating this loop is a rare occurrence.)
+ *------------------------------------------------------------------------*/
+ for (;;) {
+ term = softfloat_mul64ByShifted32To128(x64 + sigZ, q);
+ rem = softfloat_sub128(y.v64, y.v0, term.v64, term.v0);
+ if (! (rem.v64 & UINT64_C(0x8000000000000000))) break;
+ --q;
+ sigZ -= 1<<3;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ q = (((rem.v64>>2) * recipSqrt32)>>32) + 2;
+ x64 = sigZ;
+ sigZ = (sigZ<<1) + (q>>25);
+ sigZExtra = (uint64_t) (q<<39);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((q & 0xFFFFFF) <= 2) {
+ q &= ~(uint64_t) 0xFFFF;
+ sigZExtra = (uint64_t) (q<<39);
+ term = softfloat_mul64ByShifted32To128(x64 + (q>>27), q);
+ x64 = (uint32_t) (q<<5) * (uint64_t) (uint32_t) q;
+ term = softfloat_add128(term.v64, term.v0, 0, x64);
+ rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 28);
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ if (! sigZExtra) --sigZ;
+ --sigZExtra;
+ } else {
+ if (rem.v64 | rem.v0) sigZExtra |= 1;
+ }
+ }
+ return
+ softfloat_roundPackToExtF80(0, expZ, sigZ, sigZExtra, softfloat_extF80_roundingPrecision(status), status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return packToExtF80_twoargs(defaultNaNExtF80UI64, defaultNaNExtF80UI0);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_f128.cc b/src/cpu/softfloat3e/extF80_to_f128.cc
new file mode 100644
index 000000000..24e523cac
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_f128.cc
@@ -0,0 +1,75 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float128_t extF80_to_f128(extFloat80_t a, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ uint16_t exp;
+ uint64_t frac;
+ struct commonNaN commonNaN;
+ struct uint128 uiZ;
+ bool sign;
+ struct uint128 frac128;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ.v64 = defaultNaNF128UI64;
+ uiZ.v0 = defaultNaNF128UI0;
+ return uiZ;
+ }
+
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ exp = expExtF80UI64(uiA64);
+ frac = uiA0 & UINT64_C(0x7FFFFFFFFFFFFFFF);
+ if ((exp == 0x7FFF) && frac) {
+ softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF128UI(&commonNaN);
+ } else {
+ sign = signExtF80UI64(uiA64);
+ frac128 = softfloat_shortShiftLeft128(0, frac, 49);
+ uiZ.v64 = packToF128UI64(sign, exp, frac128.v64);
+ uiZ.v0 = frac128.v0;
+ }
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/extF80_to_f16.cc b/src/cpu/softfloat3e/extF80_to_f16.cc
new file mode 100644
index 000000000..5078e689c
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_f16.cc
@@ -0,0 +1,89 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float16 extF80_to_f16(extFloat80_t a, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig;
+ struct commonNaN commonNaN;
+ uint16_t uiZ, sig16;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF16UI;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ sign = signExtF80UI64(uiA64);
+ exp = expExtF80UI64(uiA64);
+ sig = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FFF) {
+ if (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) {
+ softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF16UI(&commonNaN);
+ } else {
+ uiZ = packToF16UI(sign, 0x1F, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig16 = softfloat_shortShiftRightJam64(sig, 49);
+ if (! (exp | sig16)) {
+ return packToF16UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp -= 0x3FF1;
+ if (sizeof (int16_t) < sizeof (int32_t)) {
+ if (exp < -0x40) exp = -0x40;
+ }
+ return softfloat_roundPackToF16(sign, exp, sig16, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_f32.cc b/src/cpu/softfloat3e/extF80_to_f32.cc
new file mode 100644
index 000000000..558df4c23
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_f32.cc
@@ -0,0 +1,89 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 extF80_to_f32(extFloat80_t a, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig;
+ struct commonNaN commonNaN;
+ uint32_t uiZ, sig32;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ sign = signExtF80UI64(uiA64);
+ exp = expExtF80UI64(uiA64);
+ sig = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FFF) {
+ if (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) {
+ softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF32UI(&commonNaN);
+ } else {
+ uiZ = packToF32UI(sign, 0xFF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig32 = softfloat_shortShiftRightJam64(sig, 33);
+ if (! (exp | sig32)) {
+ return packToF32UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp -= 0x3F81;
+ if (sizeof (int16_t) < sizeof (int32_t)) {
+ if (exp < -0x1000) exp = -0x1000;
+ }
+ return softfloat_roundPackToF32(sign, exp, sig32, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_f64.cc b/src/cpu/softfloat3e/extF80_to_f64.cc
new file mode 100644
index 000000000..4ba4174e3
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_f64.cc
@@ -0,0 +1,89 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 extF80_to_f64(extFloat80_t a, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ uint64_t uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig;
+ struct commonNaN commonNaN;
+ uint64_t uiZ;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ uiA0 = a.signif;
+ sign = signExtF80UI64(uiA64);
+ exp = expExtF80UI64(uiA64);
+ sig = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! (exp | sig)) {
+ return packToF64UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FFF) {
+ if (sig & UINT64_C(0x7FFFFFFFFFFFFFFF)) {
+ softfloat_extF80UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF64UI(&commonNaN);
+ } else {
+ uiZ = packToF64UI(sign, 0x7FF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig = softfloat_shortShiftRightJam64(sig, 1);
+ exp -= 0x3C01;
+ if (sizeof (int16_t) < sizeof (int32_t)) {
+ if (exp < -0x1000) exp = -0x1000;
+ }
+ return softfloat_roundPackToF64(sign, exp, sig, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_i32.cc b/src/cpu/softfloat3e/extF80_to_i32.cc
new file mode 100644
index 000000000..ea6c94484
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_i32.cc
@@ -0,0 +1,82 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t extF80_to_i32(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ bool sign;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i32_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ sign = signExtF80UI64(uiA64);
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow)
+ if ((exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))) {
+#if (i32_fromNaN == i32_fromPosOverflow)
+ sign = 0;
+#elif (i32_fromNaN == i32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x4032 - exp;
+ if (shiftDist <= 0) shiftDist = 1;
+ sig = softfloat_shiftRightJam64(sig, shiftDist);
+ return softfloat_roundToI32(sign, sig, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_i32_r_minMag.cc b/src/cpu/softfloat3e/extF80_to_i32_r_minMag.cc
new file mode 100644
index 000000000..42415c459
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_i32_r_minMag.cc
@@ -0,0 +1,93 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t extF80_to_i32_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+ bool sign;
+ int32_t absZ;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i32_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x403E - exp;
+ if (64 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signExtF80UI64(uiA64);
+ if (shiftDist < 33) {
+ if ((uiA64 == packToExtF80UI64(1, 0x401E)) && (sig < UINT64_C(0x8000000100000000))) {
+ if (exact && (sig & UINT64_C(0x00000000FFFFFFFF))) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return -0x7FFFFFFF - 1;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
+ ? i32_fromNaN
+ : sign ? i32_fromNegOverflow : i32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ absZ = sig>>shiftDist;
+ if (exact && ((uint64_t) (uint32_t) absZ<
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t extF80_to_i64(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ bool sign;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+ uint64_t sigExtra;
+ struct uint64_extra sig64Extra;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i64_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ sign = signExtF80UI64(uiA64);
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x403E - exp;
+ if (shiftDist <= 0) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (shiftDist) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sigExtra = 0;
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig64Extra = softfloat_shiftRightJam64Extra(sig, 0, shiftDist);
+ sig = sig64Extra.v;
+ sigExtra = sig64Extra.extra;
+ }
+ return softfloat_roundToI64(sign, sig, sigExtra, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_i64_r_minMag.cc b/src/cpu/softfloat3e/extF80_to_i64_r_minMag.cc
new file mode 100644
index 000000000..3500b20d2
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_i64_r_minMag.cc
@@ -0,0 +1,90 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t extF80_to_i64_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+ bool sign;
+ int64_t absZ;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i64_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x403E - exp;
+ if (64 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signExtF80UI64(uiA64);
+ if (shiftDist <= 0) {
+ if ((uiA64 == packToExtF80UI64(1, 0x403E)) && (sig == UINT64_C(0x8000000000000000))) {
+ return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ absZ = sig>>shiftDist;
+ if (exact && (uint64_t) (sig<<(-shiftDist & 63))) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return sign ? -absZ : absZ;
+}
diff --git a/src/cpu/softfloat3e/extF80_to_ui32.cc b/src/cpu/softfloat3e/extF80_to_ui32.cc
new file mode 100644
index 000000000..449cafa88
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_ui32.cc
@@ -0,0 +1,83 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t
+ extF80_to_ui32(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ bool sign;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui32_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ sign = signExtF80UI64(uiA64);
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)
+ if ((exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))) {
+#if (ui32_fromNaN == ui32_fromPosOverflow)
+ sign = 0;
+#elif (ui32_fromNaN == ui32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x4032 - exp;
+ if (shiftDist <= 0) shiftDist = 1;
+ sig = softfloat_shiftRightJam64(sig, shiftDist);
+ return softfloat_roundToUI32(sign, sig, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_ui32_r_minMag.cc b/src/cpu/softfloat3e/extF80_to_ui32_r_minMag.cc
new file mode 100644
index 000000000..7ef100139
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_ui32_r_minMag.cc
@@ -0,0 +1,87 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t extF80_to_ui32_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+ bool sign;
+ uint32_t z;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui32_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x403E - exp;
+ if (64 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signExtF80UI64(uiA64);
+ if (sign || (shiftDist < 32)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
+ ? ui32_fromNaN
+ : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ z = sig>>shiftDist;
+ if (exact && ((uint64_t) z<
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t extF80_to_ui64(extFloat80_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ bool sign;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+ uint64_t sigExtra;
+ struct uint64_extra sig64Extra;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui64_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ sign = signExtF80UI64(uiA64);
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x403E - exp;
+ if (shiftDist < 0) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
+ ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sigExtra = 0;
+ if (shiftDist) {
+ sig64Extra = softfloat_shiftRightJam64Extra(sig, 0, shiftDist);
+ sig = sig64Extra.v;
+ sigExtra = sig64Extra.extra;
+ }
+ return softfloat_roundToUI64(sign, sig, sigExtra, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/extF80_to_ui64_r_minMag.cc b/src/cpu/softfloat3e/extF80_to_ui64_r_minMag.cc
new file mode 100644
index 000000000..78b058754
--- /dev/null
+++ b/src/cpu/softfloat3e/extF80_to_ui64_r_minMag.cc
@@ -0,0 +1,87 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t extF80_to_ui64_r_minMag(extFloat80_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint16_t uiA64;
+ int32_t exp;
+ uint64_t sig;
+ int32_t shiftDist;
+ bool sign;
+ uint64_t z;
+
+ // handle unsupported extended double-precision floating encodings
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui64_fromNaN;
+ }
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.signExp;
+ exp = expExtF80UI64(uiA64);
+ sig = a.signif;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x403E - exp;
+ if (64 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signExtF80UI64(uiA64);
+ if (sign || (shiftDist < 0)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig & UINT64_C(0x7FFFFFFFFFFFFFFF))
+ ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ z = sig>>shiftDist;
+ if (exact && (z<
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+extern float128_t
+ softfloat_addMagsF128(uint64_t, uint64_t, uint64_t, uint64_t, bool, struct softfloat_status_t *);
+extern float128_t
+ softfloat_subMagsF128(uint64_t, uint64_t, uint64_t, uint64_t, bool, struct softfloat_status_t *);
+
+float128_t f128_add(float128_t a, float128_t b, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool signA;
+ uint64_t uiB64, uiB0;
+ bool signB;
+
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ signA = signF128UI64(uiA64);
+
+ uiB64 = b.v64;
+ uiB0 = b.v0;
+ signB = signF128UI64(uiB64);
+
+ if (signA == signB) {
+ return softfloat_addMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status);
+ } else {
+ return softfloat_subMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status);
+ }
+}
+
+float128_t f128_sub(float128_t a, float128_t b, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool signA;
+ uint64_t uiB64, uiB0;
+ bool signB;
+
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ signA = signF128UI64(uiA64);
+
+ uiB64 = b.v64;
+ uiB0 = b.v0;
+ signB = signF128UI64(uiB64);
+
+ if (signA == signB) {
+ return softfloat_subMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status);
+ } else {
+ return softfloat_addMagsF128(uiA64, uiA0, uiB64, uiB0, signA, status);
+ }
+}
diff --git a/src/cpu/softfloat3e/f128_div.cc b/src/cpu/softfloat3e/f128_div.cc
new file mode 100644
index 000000000..837eb15aa
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_div.cc
@@ -0,0 +1,187 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float128_t f128_div(float128_t a, float128_t b, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool signA;
+ int32_t expA;
+ struct uint128 sigA;
+ uint64_t uiB64, uiB0;
+ bool signB;
+ int32_t expB;
+ struct uint128 sigB;
+ bool signZ;
+ struct exp32_sig128 normExpSig;
+ int32_t expZ;
+ struct uint128 rem;
+ uint32_t recip32;
+ int ix;
+ uint64_t q64;
+ uint32_t q;
+ struct uint128 term;
+ uint32_t qs[3];
+ uint64_t sigZExtra;
+ struct uint128 sigZ, uiZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ signA = signF128UI64(uiA64);
+ expA = expF128UI64(uiA64);
+ sigA.v64 = fracF128UI64(uiA64);
+ sigA.v0 = uiA0;
+ uiB64 = b.v64;
+ uiB0 = b.v0;
+ signB = signF128UI64(uiB64);
+ expB = expF128UI64(uiB64);
+ sigB.v64 = fracF128UI64(uiB64);
+ sigB.v0 = uiB0;
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if (sigA.v64 | sigA.v0) goto propagateNaN;
+ if (expB == 0x7FFF) {
+ if (sigB.v64 | sigB.v0) goto propagateNaN;
+ goto invalid;
+ }
+ goto infinity;
+ }
+ if (expB == 0x7FFF) {
+ if (sigB.v64 | sigB.v0) goto propagateNaN;
+ goto zero;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expB) {
+ if (! (sigB.v64 | sigB.v0)) {
+ if (! (expA | sigA.v64 | sigA.v0)) goto invalid;
+ softfloat_raiseFlags(status, softfloat_flag_infinite);
+ goto infinity;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(sigB.v64, sigB.v0);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ if (! expA) {
+ if (! (sigA.v64 | sigA.v0)) goto zero;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(sigA.v64, sigA.v0);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA - expB + 0x3FFE;
+ sigA.v64 |= UINT64_C(0x0001000000000000);
+ sigB.v64 |= UINT64_C(0x0001000000000000);
+ rem = sigA;
+ if (softfloat_lt128(sigA.v64, sigA.v0, sigB.v64, sigB.v0)) {
+ --expZ;
+ rem = softfloat_add128(sigA.v64, sigA.v0, sigA.v64, sigA.v0);
+ }
+ recip32 = softfloat_approxRecip32_1(sigB.v64>>17);
+ ix = 3;
+ for (;;) {
+ q64 = (uint64_t) (uint32_t) (rem.v64>>19) * recip32;
+ q = (q64 + 0x80000000)>>32;
+ --ix;
+ if (ix < 0) break;
+ rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
+ term = softfloat_mul128By32(sigB.v64, sigB.v0, q);
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ --q;
+ rem = softfloat_add128(rem.v64, rem.v0, sigB.v64, sigB.v0);
+ }
+ qs[ix] = q;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (((q + 1) & 7) < 2) {
+ rem = softfloat_shortShiftLeft128(rem.v64, rem.v0, 29);
+ term = softfloat_mul128By32(sigB.v64, sigB.v0, q);
+ rem = softfloat_sub128(rem.v64, rem.v0, term.v64, term.v0);
+ if (rem.v64 & UINT64_C(0x8000000000000000)) {
+ --q;
+ rem = softfloat_add128(rem.v64, rem.v0, sigB.v64, sigB.v0);
+ } else if (softfloat_le128(sigB.v64, sigB.v0, rem.v64, rem.v0)) {
+ ++q;
+ rem = softfloat_sub128(rem.v64, rem.v0, sigB.v64, sigB.v0);
+ }
+ if (rem.v64 | rem.v0) q |= 1;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sigZExtra = (uint64_t) ((uint64_t) q<<60);
+ term = softfloat_shortShiftLeft128(0, qs[1], 54);
+ sigZ = softfloat_add128((uint64_t) qs[2]<<19, ((uint64_t) qs[0]<<25) + (q>>4), term.v64, term.v0);
+ return
+ softfloat_roundPackToF128(signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status);
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ.v64 = defaultNaNF128UI64;
+ uiZ.v0 = defaultNaNF128UI0;
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infinity:
+ uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0);
+ uiZ.v0 = 0;
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ uiZ.v64 = packToF128UI64(signZ, 0, 0);
+ uiZ.v0 = 0;
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f128_mul.cc b/src/cpu/softfloat3e/f128_mul.cc
new file mode 100644
index 000000000..fd63a4590
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_mul.cc
@@ -0,0 +1,148 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "primitiveTypes.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float128_t f128_mul(float128_t a, float128_t b, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool signA;
+ int32_t expA;
+ struct uint128 sigA;
+ uint64_t uiB64, uiB0;
+ bool signB;
+ int32_t expB;
+ struct uint128 sigB;
+ bool signZ;
+ uint64_t magBits;
+ struct exp32_sig128 normExpSig;
+ int32_t expZ;
+ uint64_t sig256Z[4];
+ uint64_t sigZExtra;
+ struct uint128 sigZ;
+ struct uint128_extra sig128Extra;
+ struct uint128 uiZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ signA = signF128UI64(uiA64);
+ expA = expF128UI64(uiA64);
+ sigA.v64 = fracF128UI64(uiA64);
+ sigA.v0 = uiA0;
+ uiB64 = b.v64;
+ uiB0 = b.v0;
+ signB = signF128UI64(uiB64);
+ expB = expF128UI64(uiB64);
+ sigB.v64 = fracF128UI64(uiB64);
+ sigB.v0 = uiB0;
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if ((sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))) {
+ goto propagateNaN;
+ }
+ magBits = expB | sigB.v64 | sigB.v0;
+ goto infArg;
+ }
+ if (expB == 0x7FFF) {
+ if (sigB.v64 | sigB.v0) goto propagateNaN;
+ magBits = expA | sigA.v64 | sigA.v0;
+ goto infArg;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! (sigA.v64 | sigA.v0)) goto zero;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(sigA.v64, sigA.v0);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! (sigB.v64 | sigB.v0)) goto zero;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(sigB.v64, sigB.v0);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA + expB - 0x4000;
+ sigA.v64 |= UINT64_C(0x0001000000000000);
+ sigB = softfloat_shortShiftLeft128(sigB.v64, sigB.v0, 16);
+ softfloat_mul128To256M(sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z);
+ sigZExtra = sig256Z[indexWord(4, 1)] | (sig256Z[indexWord(4, 0)] != 0);
+ sigZ = softfloat_add128(sig256Z[indexWord(4, 3)], sig256Z[indexWord(4, 2)], sigA.v64, sigA.v0);
+ if (UINT64_C(0x0002000000000000) <= sigZ.v64) {
+ ++expZ;
+ sig128Extra = softfloat_shortShiftRightJam128Extra(sigZ.v64, sigZ.v0, sigZExtra, 1);
+ sigZ = sig128Extra.v;
+ sigZExtra = sig128Extra.extra;
+ }
+ return
+ softfloat_roundPackToF128(signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status);
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infArg:
+ if (! magBits) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ.v64 = defaultNaNF128UI64;
+ uiZ.v0 = defaultNaNF128UI0;
+ return uiZ;
+ }
+ uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0);
+ uiZ.v0 = 0;
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ uiZ.v64 = packToF128UI64(signZ, 0, 0);
+ uiZ.v0 = 0;
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f128_mulAdd.cc b/src/cpu/softfloat3e/f128_mulAdd.cc
new file mode 100644
index 000000000..749342f5f
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_mulAdd.cc
@@ -0,0 +1,332 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "primitiveTypes.h"
+#include "softfloat.h"
+#include "specialize.h"
+
+float128_t f128_mulAdd(float128_t a, float128_t b, float128_t c, uint8_t op, struct softfloat_status_t *status)
+{
+ bool signA;
+ int32_t expA;
+ struct uint128 sigA;
+ bool signB;
+ int32_t expB;
+ struct uint128 sigB;
+ bool signC;
+ int32_t expC;
+ struct uint128 sigC;
+ bool signZ;
+ uint64_t magBits;
+ struct uint128 uiZ;
+ struct exp32_sig128 normExpSig;
+ int32_t expZ;
+ uint64_t sig256Z[4];
+ struct uint128 sigZ;
+ int32_t shiftDist, expDiff;
+ struct uint128 x128;
+ uint64_t sig256C[4];
+ static uint64_t zero256[4] = INIT_UINTM4(0, 0, 0, 0);
+ uint64_t sigZExtra, sig256Z0;
+ uint64_t uiA64, uiA0;
+ uint64_t uiB64, uiB0;
+ uint64_t uiC64, uiC0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ uiB64 = b.v64;
+ uiB0 = b.v0;
+ uiC64 = c.v64;
+ uiC0 = c.v0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF128UI64(uiA64);
+ expA = expF128UI64(uiA64);
+ sigA.v64 = fracF128UI64(uiA64);
+ sigA.v0 = uiA0;
+ signB = signF128UI64(uiB64);
+ expB = expF128UI64(uiB64);
+ sigB.v64 = fracF128UI64(uiB64);
+ sigB.v0 = uiB0;
+ signC = signF128UI64(uiC64) ^ ((op & softfloat_mulAdd_subC) != 0);
+ expC = expF128UI64(uiC64);
+ sigC.v64 = fracF128UI64(uiC64);
+ sigC.v0 = uiC0;
+ signZ = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if ((sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0))) {
+ goto propagateNaN_ABC;
+ }
+ magBits = expB | sigB.v64 | sigB.v0;
+ goto infProdArg;
+ }
+ if (expB == 0x7FFF) {
+ if (sigB.v64 | sigB.v0) goto propagateNaN_ABC;
+ magBits = expA | sigA.v64 | sigA.v0;
+ goto infProdArg;
+ }
+ if (expC == 0x7FFF) {
+ if (sigC.v64 | sigC.v0) {
+ uiZ.v64 = 0;
+ uiZ.v0 = 0;
+ goto propagateNaN_ZC;
+ }
+ uiZ.v64 = uiC64;
+ uiZ.v0 = uiC0;
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! (sigA.v64 | sigA.v0)) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(sigA.v64, sigA.v0);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! (sigB.v64 | sigB.v0)) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(sigB.v64, sigB.v0);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA + expB - 0x3FFE;
+ sigA.v64 |= UINT64_C(0x0001000000000000);
+ sigB.v64 |= UINT64_C(0x0001000000000000);
+ sigA = softfloat_shortShiftLeft128(sigA.v64, sigA.v0, 8);
+ sigB = softfloat_shortShiftLeft128(sigB.v64, sigB.v0, 15);
+ softfloat_mul128To256M(sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z);
+ sigZ.v64 = sig256Z[indexWord(4, 3)];
+ sigZ.v0 = sig256Z[indexWord(4, 2)];
+ shiftDist = 0;
+ if (! (sigZ.v64 & UINT64_C(0x0100000000000000))) {
+ --expZ;
+ shiftDist = -1;
+ }
+ if (! expC) {
+ if (! (sigC.v64 | sigC.v0)) {
+ shiftDist += 8;
+ goto sigZ;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(sigC.v64, sigC.v0);
+ expC = normExpSig.exp;
+ sigC = normExpSig.sig;
+ }
+ sigC.v64 |= UINT64_C(0x0001000000000000);
+ sigC = softfloat_shortShiftLeft128(sigC.v64, sigC.v0, 8);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expZ - expC;
+ if (expDiff < 0) {
+ expZ = expC;
+ if ((signZ == signC) || (expDiff < -1)) {
+ shiftDist -= expDiff;
+ if (shiftDist) {
+ sigZ = softfloat_shiftRightJam128(sigZ.v64, sigZ.v0, shiftDist);
+ }
+ } else {
+ if (! shiftDist) {
+ x128 = softfloat_shortShiftRight128(sig256Z[indexWord(4, 1)], sig256Z[indexWord(4, 0)], 1);
+ sig256Z[indexWord(4, 1)] = (sigZ.v0<<63) | x128.v64;
+ sig256Z[indexWord(4, 0)] = x128.v0;
+ sigZ = softfloat_shortShiftRight128(sigZ.v64, sigZ.v0, 1);
+ sig256Z[indexWord(4, 3)] = sigZ.v64;
+ sig256Z[indexWord(4, 2)] = sigZ.v0;
+ }
+ }
+ } else {
+ if (shiftDist) softfloat_add256M(sig256Z, sig256Z, sig256Z);
+ if (! expDiff) {
+ sigZ.v64 = sig256Z[indexWord(4, 3)];
+ sigZ.v0 = sig256Z[indexWord(4, 2)];
+ } else {
+ sig256C[indexWord(4, 3)] = sigC.v64;
+ sig256C[indexWord(4, 2)] = sigC.v0;
+ sig256C[indexWord(4, 1)] = 0;
+ sig256C[indexWord(4, 0)] = 0;
+ softfloat_shiftRightJam256M(sig256C, expDiff, sig256C);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 8;
+ if (signZ == signC) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (expDiff <= 0) {
+ sigZ = softfloat_add128(sigC.v64, sigC.v0, sigZ.v64, sigZ.v0);
+ } else {
+ softfloat_add256M(sig256Z, sig256C, sig256Z);
+ sigZ.v64 = sig256Z[indexWord(4, 3)];
+ sigZ.v0 = sig256Z[indexWord(4, 2)];
+ }
+ if (sigZ.v64 & UINT64_C(0x0200000000000000)) {
+ ++expZ;
+ shiftDist = 9;
+ }
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (expDiff < 0) {
+ signZ = signC;
+ if (expDiff < -1) {
+ sigZ = softfloat_sub128(sigC.v64, sigC.v0, sigZ.v64, sigZ.v0);
+ sigZExtra = sig256Z[indexWord(4, 1)] | sig256Z[indexWord(4, 0)];
+ if (sigZExtra) {
+ sigZ = softfloat_sub128(sigZ.v64, sigZ.v0, 0, 1);
+ }
+ if (! (sigZ.v64 & UINT64_C(0x0100000000000000))) {
+ --expZ;
+ shiftDist = 7;
+ }
+ goto shiftRightRoundPack;
+ } else {
+ sig256C[indexWord(4, 3)] = sigC.v64;
+ sig256C[indexWord(4, 2)] = sigC.v0;
+ sig256C[indexWord(4, 1)] = 0;
+ sig256C[indexWord(4, 0)] = 0;
+ softfloat_sub256M(sig256C, sig256Z, sig256Z);
+ }
+ } else if (! expDiff) {
+ sigZ = softfloat_sub128(sigZ.v64, sigZ.v0, sigC.v64, sigC.v0);
+ if (! (sigZ.v64 | sigZ.v0) && ! sig256Z[indexWord(4, 1)] && ! sig256Z[indexWord(4, 0)]) {
+ goto completeCancellation;
+ }
+ sig256Z[indexWord(4, 3)] = sigZ.v64;
+ sig256Z[indexWord(4, 2)] = sigZ.v0;
+ if (sigZ.v64 & UINT64_C(0x8000000000000000)) {
+ signZ = ! signZ;
+ softfloat_sub256M(zero256, sig256Z, sig256Z);
+ }
+ } else {
+ softfloat_sub256M(sig256Z, sig256C, sig256Z);
+ if (1 < expDiff) {
+ sigZ.v64 = sig256Z[indexWord(4, 3)];
+ sigZ.v0 = sig256Z[indexWord(4, 2)];
+ if (! (sigZ.v64 & UINT64_C(0x0100000000000000))) {
+ --expZ;
+ shiftDist = 7;
+ }
+ goto sigZ;
+ }
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sigZ.v64 = sig256Z[indexWord(4, 3)];
+ sigZ.v0 = sig256Z[indexWord(4, 2)];
+ sigZExtra = sig256Z[indexWord(4, 1)];
+ sig256Z0 = sig256Z[indexWord(4, 0)];
+ if (sigZ.v64) {
+ if (sig256Z0) sigZExtra |= 1;
+ } else {
+ expZ -= 64;
+ sigZ.v64 = sigZ.v0;
+ sigZ.v0 = sigZExtra;
+ sigZExtra = sig256Z0;
+ if (! sigZ.v64) {
+ expZ -= 64;
+ sigZ.v64 = sigZ.v0;
+ sigZ.v0 = sigZExtra;
+ sigZExtra = 0;
+ if (! sigZ.v64) {
+ expZ -= 64;
+ sigZ.v64 = sigZ.v0;
+ sigZ.v0 = 0;
+ }
+ }
+ }
+ shiftDist = softfloat_countLeadingZeros64(sigZ.v64);
+ expZ += 7 - shiftDist;
+ shiftDist = 15 - shiftDist;
+ if (0 < shiftDist) goto shiftRightRoundPack;
+ if (shiftDist) {
+ shiftDist = -shiftDist;
+ sigZ = softfloat_shortShiftLeft128(sigZ.v64, sigZ.v0, shiftDist);
+ x128 = softfloat_shortShiftLeft128(0, sigZExtra, shiftDist);
+ sigZ.v0 |= x128.v64;
+ sigZExtra = x128.v0;
+ }
+ goto roundPack;
+ }
+ sigZ:
+ sigZExtra = sig256Z[indexWord(4, 1)] | sig256Z[indexWord(4, 0)];
+ shiftRightRoundPack:
+ sigZExtra = (uint64_t) (sigZ.v0<<(64 - shiftDist)) | (sigZExtra != 0);
+ sigZ = softfloat_shortShiftRight128(sigZ.v64, sigZ.v0, shiftDist);
+ roundPack:
+ return softfloat_roundPackToF128(signZ, expZ - 1, sigZ.v64, sigZ.v0, sigZExtra, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN_ABC:
+ uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status);
+ goto propagateNaN_ZC;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infProdArg:
+ if ((sigC.v64 | sigC.v0) && expC == 0x7FFF) goto propagateNaN_ZC;
+ if (magBits) {
+ uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0);
+ uiZ.v0 = 0;
+ if (expC != 0x7FFF) return uiZ;
+ if (signZ == signC) return uiZ;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ.v64 = defaultNaNF128UI64;
+ uiZ.v0 = defaultNaNF128UI0;
+ propagateNaN_ZC:
+ uiZ = softfloat_propagateNaNF128UI(uiZ.v64, uiZ.v0, uiC64, uiC0, status);
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zeroProd:
+ uiZ.v64 = uiC64;
+ uiZ.v0 = uiC0;
+ if (! (expC | sigC.v64 | sigC.v0) && (signZ != signC)) {
+ completeCancellation:
+ uiZ.v64 = packToF128UI64((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0);
+ uiZ.v0 = 0;
+ }
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f128_roundToInt.cc b/src/cpu/softfloat3e/f128_roundToInt.cc
new file mode 100644
index 000000000..c3b728704
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_roundToInt.cc
@@ -0,0 +1,142 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float128_t
+ f128_roundToInt(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ int32_t exp;
+ struct uint128 uiZ;
+ uint64_t lastBitMask0, roundBitsMask;
+ bool roundNearEven;
+ uint64_t lastBitMask64;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ exp = expF128UI64(uiA64);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (0x402F <= exp) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (0x406F <= exp) {
+ if ((exp == 0x7FFF) && (fracF128UI64(uiA64) | uiA0)) {
+ uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, 0, 0, status);
+ return uiZ;
+ }
+ return a;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ lastBitMask0 = (uint64_t) 2<<(0x406E - exp);
+ roundBitsMask = lastBitMask0 - 1;
+ uiZ.v64 = uiA64;
+ uiZ.v0 = uiA0;
+ roundNearEven = (roundingMode == softfloat_round_near_even);
+ if (roundNearEven || (roundingMode == softfloat_round_near_maxMag)) {
+ if (exp == 0x402F) {
+ if (UINT64_C(0x8000000000000000) <= uiZ.v0) {
+ ++uiZ.v64;
+ if (roundNearEven && (uiZ.v0 == UINT64_C(0x8000000000000000))) {
+ uiZ.v64 &= ~1;
+ }
+ }
+ } else {
+ uiZ = softfloat_add128(uiZ.v64, uiZ.v0, 0, lastBitMask0>>1);
+ if (roundNearEven && !(uiZ.v0 & roundBitsMask)) {
+ uiZ.v0 &= ~lastBitMask0;
+ }
+ }
+ } else if (roundingMode == (signF128UI64(uiZ.v64) ? softfloat_round_min : softfloat_round_max)) {
+ uiZ = softfloat_add128(uiZ.v64, uiZ.v0, 0, roundBitsMask);
+ }
+ uiZ.v0 &= ~roundBitsMask;
+ lastBitMask64 = !lastBitMask0;
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (exp < 0x3FFF) {
+ if (!((uiA64 & UINT64_C(0x7FFFFFFFFFFFFFFF)) | uiA0)) return a;
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ uiZ.v64 = uiA64 & packToF128UI64(1, 0, 0);
+ uiZ.v0 = 0;
+ switch (roundingMode) {
+ case softfloat_round_near_even:
+ if (!(fracF128UI64(uiA64) | uiA0)) break;
+ case softfloat_round_near_maxMag:
+ if (exp == 0x3FFE) uiZ.v64 |= packToF128UI64(0, 0x3FFF, 0);
+ break;
+ case softfloat_round_min:
+ if (uiZ.v64) uiZ.v64 = packToF128UI64(1, 0x3FFF, 0);
+ break;
+ case softfloat_round_max:
+ if (!uiZ.v64) uiZ.v64 = packToF128UI64(0, 0x3FFF, 0);
+ break;
+ }
+ return uiZ;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ uiZ.v64 = uiA64;
+ uiZ.v0 = 0;
+ lastBitMask64 = (uint64_t) 1<<(0x402F - exp);
+ roundBitsMask = lastBitMask64 - 1;
+ if (roundingMode == softfloat_round_near_maxMag) {
+ uiZ.v64 += lastBitMask64>>1;
+ } else if (roundingMode == softfloat_round_near_even) {
+ uiZ.v64 += lastBitMask64>>1;
+ if (!((uiZ.v64 & roundBitsMask) | uiA0)) {
+ uiZ.v64 &= ~lastBitMask64;
+ }
+ } else if (roundingMode == (signF128UI64(uiZ.v64) ? softfloat_round_min : softfloat_round_max)) {
+ uiZ.v64 = (uiZ.v64 | (uiA0 != 0)) + roundBitsMask;
+ }
+ uiZ.v64 &= ~roundBitsMask;
+ lastBitMask0 = 0;
+ }
+ if ((uiZ.v64 != uiA64) || (uiZ.v0 != uiA0)) {
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f128_to_extF80.cc b/src/cpu/softfloat3e/f128_to_extF80.cc
new file mode 100644
index 000000000..916820bc9
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_extF80.cc
@@ -0,0 +1,94 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t f128_to_extF80(float128_t a, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t frac64, frac0;
+ struct commonNaN commonNaN;
+ struct uint128 uiZ;
+ uint16_t uiZ64;
+ uint64_t uiZ0;
+ struct exp32_sig128 normExpSig;
+ struct uint128 sig128;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ frac64 = fracF128UI64(uiA64);
+ frac0 = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FFF) {
+ if (frac64 | frac0) {
+ softfloat_f128UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
+ uiZ = softfloat_commonNaNToExtF80UI(&commonNaN);
+ uiZ64 = uiZ.v64;
+ uiZ0 = uiZ.v0;
+ } else {
+ uiZ64 = packToExtF80UI64(sign, 0x7FFF);
+ uiZ0 = UINT64_C(0x8000000000000000);
+ }
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! (frac64 | frac0)) {
+ return packToExtF80(sign, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF128Sig(frac64, frac0);
+ exp = normExpSig.exp;
+ frac64 = normExpSig.sig.v64;
+ frac0 = normExpSig.sig.v0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig128 = softfloat_shortShiftLeft128(frac64 | UINT64_C(0x0001000000000000), frac0, 15);
+ return softfloat_roundPackToExtF80(sign, exp, sig128.v64, sig128.v0, 80, status);
+}
diff --git a/src/cpu/softfloat3e/f128_to_f32.cc b/src/cpu/softfloat3e/f128_to_f32.cc
new file mode 100644
index 000000000..485d68a0c
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_f32.cc
@@ -0,0 +1,83 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 f128_to_f32(float128_t a, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t frac64;
+ struct commonNaN commonNaN;
+ uint32_t uiZ, frac32;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ frac64 = fracF128UI64(uiA64) | (uiA0 != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FFF) {
+ if (frac64) {
+ softfloat_f128UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF32UI(&commonNaN);
+ } else {
+ uiZ = packToF32UI(sign, 0xFF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ frac32 = softfloat_shortShiftRightJam64(frac64, 18);
+ if (! (exp | frac32)) {
+ return packToF32UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp -= 0x3F81;
+ if (sizeof (int16_t) < sizeof (int32_t)) {
+ if (exp < -0x1000) exp = -0x1000;
+ }
+ return softfloat_roundPackToF32(sign, exp, frac32 | 0x40000000, status);
+}
diff --git a/src/cpu/softfloat3e/f128_to_f64.cc b/src/cpu/softfloat3e/f128_to_f64.cc
new file mode 100644
index 000000000..0809c7102
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_f64.cc
@@ -0,0 +1,87 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f128_to_f64(float128_t a, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t frac64, frac0;
+ struct commonNaN commonNaN;
+ uint64_t uiZ;
+ struct uint128 frac128;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ frac64 = fracF128UI64(uiA64);
+ frac0 = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FFF) {
+ if (frac64 | frac0) {
+ softfloat_f128UIToCommonNaN(uiA64, uiA0, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF64UI(&commonNaN);
+ } else {
+ uiZ = packToF64UI(sign, 0x7FF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ frac128 = softfloat_shortShiftLeft128(frac64, frac0, 14);
+ frac64 = frac128.v64 | (frac128.v0 != 0);
+ if (! (exp | frac64)) {
+ return packToF64UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp -= 0x3C01;
+ if (sizeof (int16_t) < sizeof (int32_t)) {
+ if (exp < -0x1000) exp = -0x1000;
+ }
+ return
+ softfloat_roundPackToF64(sign, exp, frac64 | UINT64_C(0x4000000000000000), status);
+}
diff --git a/src/cpu/softfloat3e/f128_to_i32.cc b/src/cpu/softfloat3e/f128_to_i32.cc
new file mode 100644
index 000000000..68cf2b3a7
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_i32.cc
@@ -0,0 +1,80 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f128_to_i32(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig64, sig0;
+ int32_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64);
+ sig0 = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow)
+ if ((exp == 0x7FFF) && (sig64 | sig0)) {
+#if (i32_fromNaN == i32_fromPosOverflow)
+ sign = 0;
+#elif (i32_fromNaN == i32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig64 |= UINT64_C(0x0001000000000000);
+ sig64 |= (sig0 != 0);
+ shiftDist = 0x4023 - exp;
+ if (0 < shiftDist) sig64 = softfloat_shiftRightJam64(sig64, shiftDist);
+ return softfloat_roundToI32(sign, sig64, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f128_to_i32_r_minMag.cc b/src/cpu/softfloat3e/f128_to_i32_r_minMag.cc
new file mode 100644
index 000000000..a62233d4d
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_i32_r_minMag.cc
@@ -0,0 +1,89 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f128_to_i32_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ int32_t exp;
+ uint64_t sig64;
+ int32_t shiftDist;
+ bool sign;
+ int32_t absZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64) | (uiA0 != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x402F - exp;
+ if (49 <= shiftDist) {
+ if (exact && (exp | sig64)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF128UI64(uiA64);
+ if (shiftDist < 18) {
+ if (sign && (shiftDist == 17) && (sig64 < UINT64_C(0x0000000000020000))) {
+ if (exact && sig64) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return -0x7FFFFFFF - 1;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && sig64 ? i32_fromNaN
+ : sign ? i32_fromNegOverflow : i32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig64 |= UINT64_C(0x0001000000000000);
+ absZ = sig64>>shiftDist;
+ if (exact && ((uint64_t) (uint32_t) absZ<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f128_to_i64(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig64, sig0;
+ int32_t shiftDist;
+ struct uint128 sig128;
+ struct uint64_extra sigExtra;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64);
+ sig0 = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x402F - exp;
+ if (shiftDist <= 0) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (shiftDist < -15) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig64 | sig0) ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig64 |= UINT64_C(0x0001000000000000);
+ if (shiftDist) {
+ sig128 = softfloat_shortShiftLeft128(sig64, sig0, -shiftDist);
+ sig64 = sig128.v64;
+ sig0 = sig128.v0;
+ }
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (exp) sig64 |= UINT64_C(0x0001000000000000);
+ sigExtra = softfloat_shiftRightJam64Extra(sig64, sig0, shiftDist);
+ sig64 = sigExtra.v;
+ sig0 = sigExtra.extra;
+ }
+ return softfloat_roundToI64(sign, sig64, sig0, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f128_to_i64_r_minMag.cc b/src/cpu/softfloat3e/f128_to_i64_r_minMag.cc
new file mode 100644
index 000000000..edeccf182
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_i64_r_minMag.cc
@@ -0,0 +1,104 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f128_to_i64_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig64, sig0;
+ int32_t shiftDist;
+ int8_t negShiftDist;
+ uint64_t absZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64);
+ sig0 = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x402F - exp;
+ if (shiftDist < 0) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (shiftDist < -14) {
+ if ((uiA64 == UINT64_C(0xC03E000000000000)) && (sig0 < UINT64_C(0x0002000000000000))) {
+ if (exact && sig0) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x7FFF) && (sig64 | sig0)
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig64 |= UINT64_C(0x0001000000000000);
+ negShiftDist = -shiftDist;
+ absZ = sig64<>(shiftDist & 63);
+ if (exact && (uint64_t) (sig0<>shiftDist;
+ if (exact && (sig0 || (absZ<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f128_to_ui32(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig64;
+ int32_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64) | (uiA0 != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)
+ if ((exp == 0x7FFF) && sig64) {
+#if (ui32_fromNaN == ui32_fromPosOverflow)
+ sign = 0;
+#elif (ui32_fromNaN == ui32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig64 |= UINT64_C(0x0001000000000000);
+ shiftDist = 0x4023 - exp;
+ if (0 < shiftDist) {
+ sig64 = softfloat_shiftRightJam64(sig64, shiftDist);
+ }
+ return softfloat_roundToUI32(sign, sig64, roundingMode, exact, status);
+}
+
diff --git a/src/cpu/softfloat3e/f128_to_ui32_r_minMag.cc b/src/cpu/softfloat3e/f128_to_ui32_r_minMag.cc
new file mode 100644
index 000000000..96007f6a1
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_ui32_r_minMag.cc
@@ -0,0 +1,83 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f128_to_ui32_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ int32_t exp;
+ uint64_t sig64;
+ int32_t shiftDist;
+ bool sign;
+ uint32_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64) | (uiA0 != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x402F - exp;
+ if (49 <= shiftDist) {
+ if (exact && (exp | sig64)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF128UI64(uiA64);
+ if (sign || (shiftDist < 17)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && sig64 ? ui32_fromNaN
+ : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig64 |= UINT64_C(0x0001000000000000);
+ z = sig64>>shiftDist;
+ if (exact && ((uint64_t) z<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f128_to_ui64(float128_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig64, sig0;
+ int32_t shiftDist;
+ struct uint128 sig128;
+ struct uint64_extra sigExtra;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64);
+ sig0 = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x402F - exp;
+ if (shiftDist <= 0) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (shiftDist < -15) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FFF) && (sig64 | sig0) ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig64 |= UINT64_C(0x0001000000000000);
+ if (shiftDist) {
+ sig128 = softfloat_shortShiftLeft128(sig64, sig0, -shiftDist);
+ sig64 = sig128.v64;
+ sig0 = sig128.v0;
+ }
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (exp) sig64 |= UINT64_C(0x0001000000000000);
+ sigExtra = softfloat_shiftRightJam64Extra(sig64, sig0, shiftDist);
+ sig64 = sigExtra.v;
+ sig0 = sigExtra.extra;
+ }
+ return softfloat_roundToUI64(sign, sig64, sig0, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f128_to_ui64_r_minMag.cc b/src/cpu/softfloat3e/f128_to_ui64_r_minMag.cc
new file mode 100644
index 000000000..8d30420b0
--- /dev/null
+++ b/src/cpu/softfloat3e/f128_to_ui64_r_minMag.cc
@@ -0,0 +1,99 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f128_to_ui64_r_minMag(float128_t a, bool exact, struct softfloat_status_t *status)
+{
+ uint64_t uiA64, uiA0;
+ bool sign;
+ int32_t exp;
+ uint64_t sig64, sig0;
+ int32_t shiftDist;
+ int8_t negShiftDist;
+ uint64_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA64 = a.v64;
+ uiA0 = a.v0;
+ sign = signF128UI64(uiA64);
+ exp = expF128UI64(uiA64);
+ sig64 = fracF128UI64(uiA64);
+ sig0 = uiA0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x402F - exp;
+ if (shiftDist < 0) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (sign || (shiftDist < -15)) goto invalid;
+ sig64 |= UINT64_C(0x0001000000000000);
+ negShiftDist = -shiftDist;
+ z = sig64<>(shiftDist & 63);
+ if (exact && (uint64_t) (sig0<>shiftDist;
+ if (exact && (sig0 || (z<
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+extern float16 softfloat_addMagsF16(uint16_t, uint16_t, struct softfloat_status_t *);
+extern float16 softfloat_subMagsF16(uint16_t, uint16_t, struct softfloat_status_t *);
+
+float16 f16_add(float16 a, float16 b, struct softfloat_status_t *status)
+{
+ if (signF16UI((uint16_t) a ^ (uint16_t) b)) {
+ return softfloat_subMagsF16(a, b, status);
+ } else {
+ return softfloat_addMagsF16(a, b, status);
+ }
+}
+
+float16 f16_sub(float16 a, float16 b, struct softfloat_status_t *status)
+{
+ if (signF16UI((uint16_t) a ^ (uint16_t) b)) {
+ return softfloat_addMagsF16(a, b, status);
+ } else {
+ return softfloat_subMagsF16(a, b, status);
+ }
+}
diff --git a/src/cpu/softfloat3e/f16_class.c b/src/cpu/softfloat3e/f16_class.c
new file mode 100644
index 000000000..b375c1544
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_class.c
@@ -0,0 +1,64 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+softfloat_class_t f16_class(float16 a)
+{
+ bool signA;
+ int8_t expA;
+ uint16_t sigA;
+
+ signA = signF16UI(a);
+ expA = expF16UI(a);
+ sigA = fracF16UI(a);
+
+ if (expA == 0x1F) {
+ if (sigA == 0)
+ return (signA) ? softfloat_negative_inf : softfloat_positive_inf;
+
+ return (sigA & 0x200) ? softfloat_QNaN : softfloat_SNaN;
+ }
+
+ if (expA == 0) {
+ if (sigA == 0) return softfloat_zero;
+ return softfloat_denormal;
+ }
+
+ return softfloat_normalized;
+}
diff --git a/src/cpu/softfloat3e/f16_compare.c b/src/cpu/softfloat3e/f16_compare.c
new file mode 100644
index 000000000..1cfd56bec
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_compare.c
@@ -0,0 +1,92 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Compare between two half precision floating point numbers. Returns
+| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
+| the value 'a' is less than the corresponding value `b',
+| 'float_relation_greater' if the value 'a' is greater than the corresponding
+| value `b', or 'float_relation_unordered' otherwise.
+*----------------------------------------------------------------------------*/
+
+int f16_compare(float16 a, float16 b, bool quiet, struct softfloat_status_t *status)
+{
+ softfloat_class_t aClass;
+ softfloat_class_t bClass;
+ bool signA;
+ bool signB;
+
+ aClass = f16_class(a);
+ bClass = f16_class(b);
+
+ if (aClass == softfloat_SNaN || bClass == softfloat_SNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+
+ if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) {
+ if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+
+ if (aClass == softfloat_denormal) {
+ if (softfloat_denormalsAreZeros(status))
+ a = a & 0x8000;
+ else
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+
+ if (bClass == softfloat_denormal) {
+ if (softfloat_denormalsAreZeros(status))
+ b = b & 0x8000;
+ else
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+
+ if ((a == b) || ((uint16_t) ((a | b)<<1) == 0)) return softfloat_relation_equal;
+
+ signA = signF16UI(a);
+ signB = signF16UI(b);
+ if (signA != signB)
+ return (signA) ? softfloat_relation_less : softfloat_relation_greater;
+
+ if (signA ^ (a < b)) return softfloat_relation_less;
+ return softfloat_relation_greater;
+}
diff --git a/src/cpu/softfloat3e/f16_div.c b/src/cpu/softfloat3e/f16_div.c
new file mode 100644
index 000000000..c91760b03
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_div.c
@@ -0,0 +1,149 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+#define SOFTFLOAT_FAST_DIV32TO16 1
+
+extern const uint16_t softfloat_approxRecip_1k0s[];
+extern const uint16_t softfloat_approxRecip_1k1s[];
+
+float16 f16_div(float16 a, float16 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int8_t expA;
+ uint16_t sigA;
+ bool signB;
+ int8_t expB;
+ uint16_t sigB;
+ bool signZ;
+ struct exp8_sig16 normExpSig;
+ int8_t expZ;
+#ifdef SOFTFLOAT_FAST_DIV32TO16
+ uint32_t sig32A;
+ uint16_t sigZ;
+#endif
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF16UI(a);
+ expA = expF16UI(a);
+ sigA = fracF16UI(a);
+ signB = signF16UI(b);
+ expB = expF16UI(b);
+ sigB = fracF16UI(b);
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x1F) {
+ if (sigA) goto propagateNaN;
+ if (expB == 0x1F) {
+ if (sigB) goto propagateNaN;
+ goto invalid;
+ }
+ if (sigB && !expB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infinity;
+ }
+ if (expB == 0x1F) {
+ if (sigB) goto propagateNaN;
+ if (sigA && !expA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expB) {
+ if (! sigB) {
+ if (! (expA | sigA)) goto invalid;
+ softfloat_raiseFlags(status, softfloat_flag_infinite);
+ goto infinity;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ if (! expA) {
+ if (! sigA) goto zero;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA - expB + 0xE;
+ sigA |= 0x0400;
+ sigB |= 0x0400;
+#ifdef SOFTFLOAT_FAST_DIV32TO16
+ if (sigA < sigB) {
+ --expZ;
+ sig32A = (uint32_t) sigA<<15;
+ } else {
+ sig32A = (uint32_t) sigA<<14;
+ }
+ sigZ = sig32A / sigB;
+ if (! (sigZ & 7)) sigZ |= ((uint32_t) sigB * sigZ != sig32A);
+#endif
+ return softfloat_roundPackToF16(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF16UI(a, b, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF16UI;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infinity:
+ return packToF16UI(signZ, 0x1F, 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ return packToF16UI(signZ, 0, 0);
+}
diff --git a/src/cpu/softfloat3e/f16_getExp.c b/src/cpu/softfloat3e/f16_getExp.c
new file mode 100644
index 000000000..dfade995f
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_getExp.c
@@ -0,0 +1,73 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the exponent portion of half-precision floating-point value 'a',
+| and returns the result as a half-precision floating-point value
+| representing unbiased integer exponent. The operation is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float16 f16_getExp(float16 a, struct softfloat_status_t *status)
+{
+ int8_t expA;
+ uint16_t sigA;
+ struct exp8_sig16 normExpSig;
+
+ expA = expF16UI(a);
+ sigA = fracF16UI(a);
+
+ if (expA == 0x1F) {
+ if (sigA) return softfloat_propagateNaNF16UI(a, 0, status);
+ return (float16)packToF32UI(0, 0x1F, 0);
+ }
+
+ if (! expA) {
+ if (! sigA || softfloat_denormalsAreZeros(status))
+ return (float16)packToF32UI(1, 0x1F, 0);
+
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigA);
+ expA = normExpSig.exp;
+ }
+
+ return i32_to_f16((int32_t)(expA) - 0xF, status);
+}
diff --git a/src/cpu/softfloat3e/f16_getMant.c b/src/cpu/softfloat3e/f16_getMant.c
new file mode 100644
index 000000000..f0d8d5482
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_getMant.c
@@ -0,0 +1,108 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the mantissa of half-precision floating-point value 'a' and
+| returns the result as a half-precision floating-point after applying
+| the mantissa interval normalization and sign control. The operation is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float16 f16_getMant(float16 a, struct softfloat_status_t *status, int sign_ctrl, int interv)
+{
+ bool signA;
+ int8_t expA;
+ uint16_t sigA;
+ struct exp8_sig16 normExpSig;
+
+ signA = signF16UI(a);
+ expA = expF16UI(a);
+ sigA = fracF16UI(a);
+
+ if (expA == 0x1F) {
+ if (sigA) return softfloat_propagateNaNF16UI(a, 0, status);
+ if (signA) {
+ if (sign_ctrl & 0x2) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF16UI;
+ }
+ }
+ return packToF16UI(~sign_ctrl & signA, 0x1F, 0);
+ }
+
+ if (! expA && (! sigA || softfloat_denormalsAreZeros(status))) {
+ return packToF16UI(~sign_ctrl & signA, 0x1F, 0);
+ }
+
+ if (signA) {
+ if (sign_ctrl & 0x2) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF16UI;
+ }
+ }
+
+ if (expA == 0) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ sigA &= 0x3ff;
+ }
+
+ switch(interv) {
+ case 0x0: // interval [1,2)
+ expA = 0xF;
+ break;
+ case 0x1: // interval [1/2,2)
+ expA -= 0xF;
+ expA = 0xF - (expA & 0x1);
+ break;
+ case 0x2: // interval [1/2,1)
+ expA = 0xE;
+ break;
+ case 0x3: // interval [3/4,3/2)
+ expA = 0xF - ((sigA >> 9) & 0x1);
+ break;
+ }
+
+ return packToF16UI(~sign_ctrl & signA, expA, sigA);
+}
diff --git a/src/cpu/softfloat3e/f16_minmax.c b/src/cpu/softfloat3e/f16_minmax.c
new file mode 100644
index 000000000..11922a1ba
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_minmax.c
@@ -0,0 +1,69 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Compare between two half precision floating point numbers and return the
+| smaller of them.
+*----------------------------------------------------------------------------*/
+
+float16 f16_min(float16 a, float16 b, struct softfloat_status_t *status)
+{
+ if (softfloat_denormalsAreZeros(status)) {
+ a = f16_denormal_to_zero(a);
+ b = f16_denormal_to_zero(b);
+ }
+
+ return (f16_compare_normal(a, b, status) == softfloat_relation_less) ? a : b;
+}
+
+/*----------------------------------------------------------------------------
+| Compare between two half precision floating point numbers and return the
+| larger of them.
+*----------------------------------------------------------------------------*/
+
+float16 f16_max(float16 a, float16 b, struct softfloat_status_t *status)
+{
+ if (softfloat_denormalsAreZeros(status)) {
+ a = f16_denormal_to_zero(a);
+ b = f16_denormal_to_zero(b);
+ }
+
+ return (f16_compare_normal(a, b, status) == softfloat_relation_greater) ? a : b;
+}
diff --git a/src/cpu/softfloat3e/f16_mul.c b/src/cpu/softfloat3e/f16_mul.c
new file mode 100644
index 000000000..2e7e74826
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_mul.c
@@ -0,0 +1,139 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float16 f16_mul(float16 a, float16 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int8_t expA;
+ uint16_t sigA;
+ bool signB;
+ int8_t expB;
+ uint16_t sigB;
+ bool signZ;
+ uint16_t magBits;
+ struct exp8_sig16 normExpSig;
+ int8_t expZ;
+ uint32_t sig32Z;
+ uint16_t sigZ, uiZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF16UI(a);
+ expA = expF16UI(a);
+ sigA = fracF16UI(a);
+ signB = signF16UI(b);
+ expB = expF16UI(b);
+ sigB = fracF16UI(b);
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x1F) {
+ if (sigA || ((expB == 0x1F) && sigB)) goto propagateNaN;
+ magBits = expB | sigB;
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infArg;
+ }
+ if (expB == 0x1F) {
+ if (sigB) goto propagateNaN;
+ magBits = expA | sigA;
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infArg;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) {
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! sigB) {
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA + expB - 0xF;
+ sigA = (sigA | 0x0400)<<4;
+ sigB = (sigB | 0x0400)<<5;
+ sig32Z = (uint32_t) sigA * sigB;
+ sigZ = sig32Z>>16;
+ if (sig32Z & 0xFFFF) sigZ |= 1;
+ if (sigZ < 0x4000) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ return softfloat_roundPackToF16(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF16UI(a, b, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infArg:
+ if (! magBits) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ = defaultNaNF16UI;
+ } else {
+ uiZ = packToF16UI(signZ, 0x1F, 0);
+ }
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ return packToF16UI(signZ, 0, 0);
+}
diff --git a/src/cpu/softfloat3e/f16_mulAdd.c b/src/cpu/softfloat3e/f16_mulAdd.c
new file mode 100644
index 000000000..0e630a9b7
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_mulAdd.c
@@ -0,0 +1,232 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+#include "specialize.h"
+
+float16 f16_mulAdd(float16 a, float16 b, float16 c, uint8_t op, struct softfloat_status_t *status)
+{
+ bool signA;
+ int8_t expA;
+ uint16_t sigA;
+ bool signB;
+ int8_t expB;
+ uint16_t sigB;
+ bool signC;
+ int8_t expC;
+ uint16_t sigC;
+ bool signProd;
+ uint16_t magBits, uiA, uiB, uiC, uiZ;
+ struct exp8_sig16 normExpSig;
+ int8_t expProd;
+ uint32_t sigProd;
+ bool signZ;
+ int8_t expZ;
+ uint16_t sigZ;
+ int8_t expDiff;
+ uint32_t sig32Z, sig32C;
+ int8_t shiftDist;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA = a;
+ uiB = b;
+ uiC = c;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF16UI(uiA);
+ expA = expF16UI(uiA);
+ sigA = fracF16UI(uiA);
+ signB = signF16UI(uiB);
+ expB = expF16UI(uiB);
+ sigB = fracF16UI(uiB);
+ signC = signF16UI(uiC) ^ ((op & softfloat_mulAdd_subC) != 0);
+ expC = expF16UI(uiC);
+ sigC = fracF16UI(uiC);
+ signProd = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ bool aisNaN = (expA == 0x1F) && sigA;
+ bool bisNaN = (expB == 0x1F) && sigB;
+ bool cisNaN = (expC == 0x1F) && sigC;
+ if (aisNaN | bisNaN | cisNaN) {
+ uiZ = (aisNaN | bisNaN) ? softfloat_propagateNaNF16UI(uiA, uiB, status) : 0;
+ return softfloat_propagateNaNF16UI(uiZ, uiC, status);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ if (!expC) sigC = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x1F) {
+ magBits = expB | sigB;
+ goto infProdArg;
+ }
+ if (expB == 0x1F) {
+ magBits = expA | sigA;
+ goto infProdArg;
+ }
+ if (expC == 0x1F) {
+ if ((sigA && !expA) || (sigB && !expB)) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ return packToF16UI(signC, 0x1F, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! sigB) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expProd = expA + expB - 0xE;
+ sigA = (sigA | 0x0400)<<4;
+ sigB = (sigB | 0x0400)<<4;
+ sigProd = (uint32_t) sigA * sigB;
+ if (sigProd < 0x20000000) {
+ --expProd;
+ sigProd <<= 1;
+ }
+ signZ = signProd;
+ if (! expC) {
+ if (! sigC) {
+ expZ = expProd - 1;
+ sigZ = sigProd>>15 | ((sigProd & 0x7FFF) != 0);
+ goto roundPack;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigC);
+ expC = normExpSig.exp;
+ sigC = normExpSig.sig;
+ }
+ sigC = (sigC | 0x0400)<<3;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expProd - expC;
+ if (signProd == signC) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (expDiff <= 0) {
+ expZ = expC;
+ sigZ = sigC + softfloat_shiftRightJam32(sigProd, 16 - expDiff);
+ } else {
+ expZ = expProd;
+ sig32Z = sigProd + softfloat_shiftRightJam32((uint32_t) sigC<<16, expDiff);
+ sigZ = sig32Z>>16 | ((sig32Z & 0xFFFF) != 0);
+ }
+ if (sigZ < 0x4000) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig32C = (uint32_t) sigC<<16;
+ if (expDiff < 0) {
+ signZ = signC;
+ expZ = expC;
+ sig32Z = sig32C - softfloat_shiftRightJam32(sigProd, -expDiff);
+ } else if (! expDiff) {
+ expZ = expProd;
+ sig32Z = sigProd - sig32C;
+ if (! sig32Z) goto completeCancellation;
+ if (sig32Z & 0x80000000) {
+ signZ = ! signZ;
+ sig32Z = -sig32Z;
+ }
+ } else {
+ expZ = expProd;
+ sig32Z = sigProd - softfloat_shiftRightJam32(sig32C, expDiff);
+ }
+ shiftDist = softfloat_countLeadingZeros32(sig32Z) - 1;
+ expZ -= shiftDist;
+ shiftDist -= 16;
+ if (shiftDist < 0) {
+ sigZ = sig32Z>>(-shiftDist) | ((uint32_t) (sig32Z<<(shiftDist & 31)) != 0);
+ } else {
+ sigZ = (uint16_t) sig32Z<
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float16 f16_range(float16 a, float16 b, bool is_max, bool is_abs, int sign_ctrl, struct softfloat_status_t *status)
+{
+ bool signA;
+ int8_t expA;
+ uint16_t sigA;
+ bool signB;
+ int8_t expB;
+ uint16_t sigB;
+ bool aIsNaN, bIsNaN;
+ uint16_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF16UI(a);
+ expA = expF16UI(a);
+ sigA = fracF16UI(a);
+ signB = signF16UI(b);
+ expB = expF16UI(b);
+ sigB = fracF16UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_isSigNaNF16UI(a)) {
+ return softfloat_propagateNaNF16UI(a, 0, status);
+ }
+ if (softfloat_isSigNaNF16UI(b)) {
+ return softfloat_propagateNaNF16UI(b, 0, status);
+ }
+
+ aIsNaN = isNaNF16UI(a);
+ bIsNaN = isNaNF16UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA && sigA) {
+ if (softfloat_denormalsAreZeros(status)) {
+ a = packToF16UI(signA, 0, 0);
+ }
+ else if (! bIsNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ }
+
+ if (! expB && sigB) {
+ if (softfloat_denormalsAreZeros(status)) {
+ b = packToF16UI(signB, 0, 0);
+ }
+ else if (! aIsNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (bIsNaN) {
+ z = a;
+ }
+ else if (aIsNaN) {
+ z = b;
+ }
+ else if (signA != signB && ! is_abs) {
+ if (! is_max) {
+ z = signA ? a : b;
+ } else {
+ z = signA ? b : a;
+ }
+ } else {
+ float16 tmp_a = a, tmp_b = b;
+ if (is_abs) {
+ tmp_a = tmp_a & ~0x8000; // clear the sign bit
+ tmp_b = tmp_b & ~0x8000;
+ signA = 0;
+ }
+
+ if (! is_max) {
+ z = (signA ^ (tmp_a < tmp_b)) ? a : b;
+ } else {
+ z = (signA ^ (tmp_a < tmp_b)) ? b : a;
+ }
+ }
+
+ switch(sign_ctrl) {
+ case 0:
+ z = (z & ~0x8000) | (a & 0x8000); // keep sign of a
+ break;
+ case 1:
+ break; // preserve sign of compare result
+ case 2:
+ z = z & ~0x8000; // zero out the sign bit
+ break;
+ case 3:
+ z = z | 0x8000; // set the sign bit
+ break;
+ }
+
+ return z;
+}
diff --git a/src/cpu/softfloat3e/f16_roundToInt.c b/src/cpu/softfloat3e/f16_roundToInt.c
new file mode 100644
index 000000000..ee9be0c0b
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_roundToInt.c
@@ -0,0 +1,112 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float16 f16_roundToInt(float16 a, uint8_t scale, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ int8_t exp;
+ uint16_t frac;
+ bool sign;
+ uint16_t uiZ, lastBitMask, roundBitsMask;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ scale &= 0xF;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ sign = signF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (0x19 <= (exp + scale)) {
+ if ((exp == 0x1F) && frac) {
+ return softfloat_propagateNaNF16UI(a, 0, status);
+ }
+ return a;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!exp) {
+ frac = 0;
+ a = packToF16UI(sign, 0, 0);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((exp + scale) <= 0xE) {
+ if (!(exp | frac)) return a;
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ uiZ = packToF16UI(sign, 0, 0);
+ switch (roundingMode) {
+ case softfloat_round_near_even:
+ if (!frac) break;
+ case softfloat_round_near_maxMag:
+ if ((exp + scale) == 0xE) uiZ |= packToF16UI(0, 0xF - scale, 0);
+ break;
+ case softfloat_round_min:
+ if (uiZ) uiZ = packToF16UI(1, 0xF - scale, 0);
+ break;
+ case softfloat_round_max:
+ if (!uiZ) uiZ = packToF16UI(0, 0xF - scale, 0);
+ break;
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ = a;
+ lastBitMask = (uint16_t) 1<<(0x19 - exp - scale);
+ roundBitsMask = lastBitMask - 1;
+ if (roundingMode == softfloat_round_near_maxMag) {
+ uiZ += lastBitMask>>1;
+ } else if (roundingMode == softfloat_round_near_even) {
+ uiZ += lastBitMask>>1;
+ if (!(uiZ & roundBitsMask)) uiZ &= ~lastBitMask;
+ } else if (roundingMode == (signF16UI(uiZ) ? softfloat_round_min : softfloat_round_max)) {
+ uiZ += roundBitsMask;
+ }
+ uiZ &= ~roundBitsMask;
+ if (uiZ != a) {
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f16_sqrt.c b/src/cpu/softfloat3e/f16_sqrt.c
new file mode 100644
index 000000000..f0f8afef1
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_sqrt.c
@@ -0,0 +1,130 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extern const uint16_t softfloat_approxRecipSqrt_1k0s[];
+extern const uint16_t softfloat_approxRecipSqrt_1k1s[];
+
+float16 f16_sqrt(float16 a, struct softfloat_status_t *status)
+{
+ bool signA;
+ int8_t expA;
+ uint16_t sigA;
+ struct exp8_sig16 normExpSig;
+ int8_t expZ;
+ int index;
+ uint16_t r0;
+ uint32_t ESqrR0;
+ uint16_t sigma0;
+ uint16_t recipSqrt16, sigZ, shiftedSigZ;
+ uint16_t negRem;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF16UI(a);
+ expA = expF16UI(a);
+ sigA = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x1F) {
+ if (sigA) {
+ return softfloat_propagateNaNF16UI(a, 0, status);
+ }
+ if (! signA) return a;
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) {
+ sigA = 0;
+ a = packToF16UI(signA, 0, 0);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (signA) {
+ if (! (expA | sigA)) return a;
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) return a;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = ((expA - 0xF)>>1) + 0xE;
+ expA &= 1;
+ sigA |= 0x0400;
+ index = (sigA>>6 & 0xE) + expA;
+ r0 = softfloat_approxRecipSqrt_1k0s[index]
+ - (((uint32_t) softfloat_approxRecipSqrt_1k1s[index] * (sigA & 0x7F)) >>11);
+ ESqrR0 = ((uint32_t) r0 * r0)>>1;
+ if (expA) ESqrR0 >>= 1;
+ sigma0 = ~(uint16_t) ((ESqrR0 * sigA)>>16);
+ recipSqrt16 = r0 + (((uint32_t) r0 * sigma0)>>25);
+ if (! (recipSqrt16 & 0x8000)) recipSqrt16 = 0x8000;
+ sigZ = ((uint32_t) (sigA<<5) * recipSqrt16)>>16;
+ if (expA) sigZ >>= 1;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ ++sigZ;
+ if (! (sigZ & 7)) {
+ shiftedSigZ = sigZ>>1;
+ negRem = shiftedSigZ * shiftedSigZ;
+ sigZ &= ~1;
+ if (negRem & 0x8000) {
+ sigZ |= 1;
+ } else {
+ if (negRem) --sigZ;
+ }
+ }
+ return softfloat_roundPackToF16(0, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF16UI;
+}
diff --git a/src/cpu/softfloat3e/f16_to_extF80.cc b/src/cpu/softfloat3e/f16_to_extF80.cc
new file mode 100644
index 000000000..418be8083
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_extF80.cc
@@ -0,0 +1,88 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t f16_to_extF80(float16 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int8_t exp;
+ uint16_t frac;
+ struct commonNaN commonNaN;
+ struct uint128 uiZ;
+ uint16_t uiZ64;
+ uint64_t uiZ0;
+ struct exp8_sig16 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x1F) {
+ if (frac) {
+ softfloat_f16UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToExtF80UI(&commonNaN);
+ uiZ64 = uiZ.v64;
+ uiZ0 = uiZ.v0;
+ } else {
+ uiZ64 = packToExtF80UI64(sign, 0x7FFF);
+ uiZ0 = UINT64_C(0x8000000000000000);
+ }
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac) {
+ return packToExtF80(sign, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(frac);
+ exp = normExpSig.exp;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ64 = packToExtF80UI64(sign, exp + 0x3FF0);
+ uiZ0 = (uint64_t) (frac | 0x0400)<<53;
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+}
diff --git a/src/cpu/softfloat3e/f16_to_f32.c b/src/cpu/softfloat3e/f16_to_f32.c
new file mode 100644
index 000000000..4d862161d
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_f32.c
@@ -0,0 +1,81 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 f16_to_f32(float16 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int8_t exp;
+ uint16_t frac;
+ struct commonNaN commonNaN;
+ uint32_t uiZ;
+ struct exp8_sig16 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x1F) {
+ if (frac) {
+ softfloat_f16UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF32UI(&commonNaN);
+ } else {
+ uiZ = packToF32UI(sign, 0xFF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac || softfloat_denormalsAreZeros(status)) {
+ return packToF32UI(sign, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(frac);
+ exp = normExpSig.exp - 1;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ return packToF32UI(sign, exp + 0x70, (uint32_t) frac<<13);
+}
diff --git a/src/cpu/softfloat3e/f16_to_f64.c b/src/cpu/softfloat3e/f16_to_f64.c
new file mode 100644
index 000000000..7d61b6357
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_f64.c
@@ -0,0 +1,81 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f16_to_f64(float16 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int8_t exp;
+ uint16_t frac;
+ struct commonNaN commonNaN;
+ uint64_t uiZ;
+ struct exp8_sig16 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x1F) {
+ if (frac) {
+ softfloat_f16UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF64UI(&commonNaN);
+ } else {
+ uiZ = packToF64UI(sign, 0x7FF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac || softfloat_denormalsAreZeros(status)) {
+ return packToF64UI(sign, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF16Sig(frac);
+ exp = normExpSig.exp - 1;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ return packToF64UI(sign, exp + 0x3F0, (uint64_t) frac<<42);
+}
diff --git a/src/cpu/softfloat3e/f16_to_i32.c b/src/cpu/softfloat3e/f16_to_i32.c
new file mode 100644
index 000000000..d00cfe236
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_i32.c
@@ -0,0 +1,81 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f16_to_i32(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int8_t exp;
+ uint16_t frac;
+ int32_t sig32;
+ int8_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x1F) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ frac ? i32_fromNaN
+ : sign ? i32_fromNegOverflow : i32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig32 = frac;
+ if (exp) {
+ sig32 |= 0x0400;
+ shiftDist = exp - 0x19;
+ if (0 <= shiftDist) {
+ sig32 <<= shiftDist;
+ return sign ? -sig32 : sig32;
+ }
+ shiftDist = exp - 0x0D;
+ if (0 < shiftDist) sig32 <<= shiftDist;
+ }
+ else {
+ if (softfloat_denormalsAreZeros(status)) sig32 = 0;
+ }
+ return softfloat_roundToI32(sign, (uint32_t) sig32, roundingMode, exact, status);
+}
+
diff --git a/src/cpu/softfloat3e/f16_to_i32_r_minMag.c b/src/cpu/softfloat3e/f16_to_i32_r_minMag.c
new file mode 100644
index 000000000..9a6bbdf83
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_i32_r_minMag.c
@@ -0,0 +1,82 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f16_to_i32_r_minMag(float16 a, bool exact, struct softfloat_status_t *status)
+{
+ int8_t exp;
+ uint16_t frac;
+ int8_t shiftDist;
+ bool sign;
+ int32_t alignedSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && frac) frac = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = exp - 0x0F;
+ if (shiftDist < 0) {
+ if (exact && (exp | frac)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ if (exp == 0x1F) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x1F) && frac
+ ? i32_fromNaN
+ : sign ? i32_fromNegOverflow : i32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ alignedSig = (int32_t) (frac | 0x0400)<>= 10;
+ return sign ? -alignedSig : alignedSig;
+}
diff --git a/src/cpu/softfloat3e/f16_to_i64.c b/src/cpu/softfloat3e/f16_to_i64.c
new file mode 100644
index 000000000..7dcbeaad8
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_i64.c
@@ -0,0 +1,80 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f16_to_i64(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int8_t exp;
+ uint16_t frac;
+ int32_t sig32;
+ int8_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x1F) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ frac ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig32 = frac;
+ if (exp) {
+ sig32 |= 0x0400;
+ shiftDist = exp - 0x19;
+ if (0 <= shiftDist) {
+ sig32 <<= shiftDist;
+ return sign ? -sig32 : sig32;
+ }
+ shiftDist = exp - 0x0D;
+ if (0 < shiftDist) sig32 <<= shiftDist;
+ }
+ else {
+ if (softfloat_denormalsAreZeros(status)) sig32 = 0;
+ }
+ return softfloat_roundToI32(sign, (uint32_t) sig32, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f16_to_i64_r_minMag.c b/src/cpu/softfloat3e/f16_to_i64_r_minMag.c
new file mode 100644
index 000000000..4289c5352
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_i64_r_minMag.c
@@ -0,0 +1,82 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f16_to_i64_r_minMag(float16 a, bool exact, struct softfloat_status_t *status)
+{
+ int8_t exp;
+ uint16_t frac;
+ int8_t shiftDist;
+ bool sign;
+ int32_t alignedSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && frac) frac = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = exp - 0x0F;
+ if (shiftDist < 0) {
+ if (exact && (exp | frac)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ if (exp == 0x1F) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x1F) && frac
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ alignedSig = (int32_t) (frac | 0x0400)<>= 10;
+ return sign ? -alignedSig : alignedSig;
+}
diff --git a/src/cpu/softfloat3e/f16_to_ui32.c b/src/cpu/softfloat3e/f16_to_ui32.c
new file mode 100644
index 000000000..d217b2627
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_ui32.c
@@ -0,0 +1,79 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f16_to_ui32(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int8_t exp;
+ uint16_t frac;
+ uint32_t sig32;
+ int8_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x1F) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ frac ? ui32_fromNaN
+ : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig32 = frac;
+ if (exp) {
+ sig32 |= 0x0400;
+ shiftDist = exp - 0x19;
+ if ((0 <= shiftDist) && ! sign) {
+ return sig32<
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f16_to_ui32_r_minMag(float16 a, bool exact, struct softfloat_status_t *status)
+{
+ int8_t exp;
+ uint16_t frac;
+ int8_t shiftDist;
+ bool sign;
+ uint32_t alignedSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && frac) frac = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = exp - 0x0F;
+ if (shiftDist < 0) {
+ if (exact && (exp | frac)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ if (sign || (exp == 0x1F)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x1F) && frac
+ ? ui32_fromNaN
+ : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ alignedSig = (uint32_t) (frac | 0x0400)<>10;
+}
diff --git a/src/cpu/softfloat3e/f16_to_ui64.c b/src/cpu/softfloat3e/f16_to_ui64.c
new file mode 100644
index 000000000..351edb32c
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_ui64.c
@@ -0,0 +1,79 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f16_to_ui64(float16 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int8_t exp;
+ uint16_t frac;
+ uint32_t sig32;
+ int8_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x1F) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ frac ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig32 = frac;
+ if (exp) {
+ sig32 |= 0x0400;
+ shiftDist = exp - 0x19;
+ if ((0 <= shiftDist) && ! sign) {
+ return sig32<>12, (uint64_t) sig32<<52, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f16_to_ui64_r_minMag.c b/src/cpu/softfloat3e/f16_to_ui64_r_minMag.c
new file mode 100644
index 000000000..d80d6e8f5
--- /dev/null
+++ b/src/cpu/softfloat3e/f16_to_ui64_r_minMag.c
@@ -0,0 +1,81 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f16_to_ui64_r_minMag(float16 a, bool exact, struct softfloat_status_t *status)
+{
+ int8_t exp;
+ uint16_t frac;
+ int8_t shiftDist;
+ bool sign;
+ uint32_t alignedSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF16UI(a);
+ frac = fracF16UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && frac) frac = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = exp - 0x0F;
+ if (shiftDist < 0) {
+ if (exact && (exp | frac)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF16UI(a);
+ if (sign || (exp == 0x1F)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x1F) && frac
+ ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ alignedSig = (uint32_t) (frac | 0x0400)<>10;
+}
diff --git a/src/cpu/softfloat/f2xm1.cc b/src/cpu/softfloat3e/f2xm1.cc
similarity index 77%
rename from src/cpu/softfloat/f2xm1.cc
rename to src/cpu/softfloat3e/f2xm1.cc
index ed4af1d12..16daec1d3 100644
--- a/src/cpu/softfloat/f2xm1.cc
+++ b/src/cpu/softfloat3e/f2xm1.cc
@@ -25,12 +25,15 @@ these four paragraphs for those parts of this code that are retained.
#define FLOAT128
-#include "softfloatx80.h"
-#include "softfloat-round-pack.h"
+#include "config.h"
+#include "specialize.h"
+
+#include "fpu_trans.h"
+#include "softfloat-helpers.h"
static const floatx80 floatx80_negone = packFloatx80(1, 0x3fff, BX_CONST64(0x8000000000000000));
static const floatx80 floatx80_neghalf = packFloatx80(1, 0x3ffe, BX_CONST64(0x8000000000000000));
-static const float128 float128_ln2 =
+static const float128_t float128_ln2 =
packFloat128(BX_CONST64(0x3ffe62e42fefa39e), BX_CONST64(0xf35793c7673007e6));
#ifdef BETTER_THAN_PENTIUM
@@ -47,7 +50,7 @@ static const float128 float128_ln2 =
#define EXP_ARR_SIZE 15
-static float128 exp_arr[EXP_ARR_SIZE] =
+static float128_t exp_arr[EXP_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
PACK_FLOAT_128(0x3ffe000000000000, 0x0000000000000000), /* 2 */
@@ -66,10 +69,10 @@ static float128 exp_arr[EXP_ARR_SIZE] =
PACK_FLOAT_128(0x3fd6ae7f3e733b81, 0xf11d8656b0ee8cb0) /* 15 */
};
-extern float128 EvalPoly(float128 x, float128 *arr, int n, struct float_status_t *status);
+extern float128_t EvalPoly(float128_t x, const float128_t *arr, int n, struct softfloat_status_t *status);
/* required -1 < x < 1 */
-static float128 poly_exp(float128 x, struct float_status_t *status)
+static float128_t poly_exp(float128_t x, struct softfloat_status_t *status)
{
/*
// 2 3 4 5 6 7 8 9
@@ -92,8 +95,8 @@ static float128 poly_exp(float128 x, struct float_status_t *status)
// e - 1 ~ x * [ p(x) + x * q(x) ]
//
*/
- float128 t = EvalPoly(x, exp_arr, EXP_ARR_SIZE, status);
- return float128_mul(t, x, status);
+ float128_t t = EvalPoly(x, (const float128_t*) exp_arr, EXP_ARR_SIZE, status);
+ return f128_mul(t, x, status);
}
// =================================================
@@ -114,49 +117,51 @@ static float128 poly_exp(float128 x, struct float_status_t *status)
// e = 1 + --- + --- + --- + --- + --- + ... + --- + ...
// 1! 2! 3! 4! 5! n!
//
-
-floatx80 f2xm1(floatx80 a, struct float_status_t *status)
+floatx80 f2xm1(floatx80 a, struct softfloat_status_t *status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
- Bit64u zSig0, zSig1, zSig2;
+ static const floatx80 floatx80_default_nan =
+ packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
+
+ uint64_t zSig0, zSig1, zSig2;
+ struct exp32_sig64 normExpSig;
// handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a))
- {
- float_raise(status, float_flag_invalid);
+ if (extF80_isUnsupported(a)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
return floatx80_default_nan;
}
- Bit64u aSig = extractFloatx80Frac(a);
- Bit32s aExp = extractFloatx80Exp(a);
- int aSign = extractFloatx80Sign(a);
+ uint64_t aSig = extF80_fraction(a);
+ int32_t aExp = extF80_exp(a);
+ int aSign = extF80_sign(a);
if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1))
- return propagateFloatx80NaNOne(a, status);
+ if (aSig << 1)
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, 0, 0, status);
return (aSign) ? floatx80_negone : a;
}
- if (aExp == 0) {
- if (aSig == 0) return a;
- float_raise(status, float_flag_denormal | float_flag_inexact);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+ if (! aExp) {
+ if (! aSig) return a;
+ softfloat_raiseFlags(status, softfloat_flag_denormal | softfloat_flag_inexact);
+ normExpSig = softfloat_normSubnormalExtF80Sig(aSig);
+ aExp = normExpSig.exp + 1;
+ aSig = normExpSig.sig;
tiny_argument:
mul128By64To192(LN2_SIG_HI, LN2_SIG_LO, aSig, &zSig0, &zSig1, &zSig2);
- if (0 < (Bit64s) zSig0) {
+ if (0 < (int64_t) zSig0) {
shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
--aExp;
}
- return
- roundAndPackFloatx80(80, aSign, aExp, zSig0, zSig1, status);
+ return softfloat_roundPackToExtF80(aSign, aExp, zSig0, zSig1, 80, status);
}
- float_raise(status, float_flag_inexact);
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
if (aExp < 0x3FFF)
{
@@ -167,14 +172,14 @@ floatx80 f2xm1(floatx80 a, struct float_status_t *status)
/* using float128 for approximation */
/* ******************************** */
- float128 x = floatx80_to_float128(a, status);
- x = float128_mul(x, float128_ln2, status);
+ float128_t x = extF80_to_f128(a, status);
+ x = f128_mul(x, float128_ln2, status);
x = poly_exp(x, status);
- return float128_to_floatx80(x, status);
+ return f128_to_extF80(x, status);
}
else
{
- if (a.exp == 0xBFFF && ! (aSig<<1))
+ if (a.signExp == 0xBFFF && ! (aSig<<1))
return floatx80_neghalf;
return a;
diff --git a/src/cpu/softfloat3e/f32_addsub.c b/src/cpu/softfloat3e/f32_addsub.c
new file mode 100644
index 000000000..0b12d0e76
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_addsub.c
@@ -0,0 +1,60 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+extern float32 softfloat_addMagsF32(uint32_t, uint32_t, struct softfloat_status_t *);
+extern float32 softfloat_subMagsF32(uint32_t, uint32_t, struct softfloat_status_t *);
+
+float32 f32_add(float32 a, float32 b, struct softfloat_status_t *status)
+{
+ if (signF32UI((uint32_t) a ^ (uint32_t) b)) {
+ return softfloat_subMagsF32(a, b, status);
+ } else {
+ return softfloat_addMagsF32(a, b, status);
+ }
+}
+
+float32 f32_sub(float32 a, float32 b, struct softfloat_status_t *status)
+{
+ if (signF32UI((uint32_t) a ^ (uint32_t) b)) {
+ return softfloat_addMagsF32(a, b, status);
+ } else {
+ return softfloat_subMagsF32(a, b, status);
+ }
+}
diff --git a/src/cpu/softfloat3e/f32_class.c b/src/cpu/softfloat3e/f32_class.c
new file mode 100644
index 000000000..84c337d0e
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_class.c
@@ -0,0 +1,64 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+softfloat_class_t f32_class(float32 a)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+
+ if (expA == 0xFF) {
+ if (sigA == 0)
+ return (signA) ? softfloat_negative_inf : softfloat_positive_inf;
+
+ return (sigA & 0x00400000) ? softfloat_QNaN : softfloat_SNaN;
+ }
+
+ if (expA == 0) {
+ if (sigA == 0) return softfloat_zero;
+ return softfloat_denormal;
+ }
+
+ return softfloat_normalized;
+}
diff --git a/src/cpu/softfloat3e/f32_compare.c b/src/cpu/softfloat3e/f32_compare.c
new file mode 100644
index 000000000..6c8ecfaae
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_compare.c
@@ -0,0 +1,92 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Compare between two single precision floating point numbers. Returns
+| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
+| the value 'a' is less than the corresponding value `b',
+| 'float_relation_greater' if the value 'a' is greater than the corresponding
+| value `b', or 'float_relation_unordered' otherwise.
+*----------------------------------------------------------------------------*/
+
+int f32_compare(float32 a, float32 b, bool quiet, struct softfloat_status_t *status)
+{
+ softfloat_class_t aClass;
+ softfloat_class_t bClass;
+ bool signA;
+ bool signB;
+
+ aClass = f32_class(a);
+ bClass = f32_class(b);
+
+ if (aClass == softfloat_SNaN || bClass == softfloat_SNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+
+ if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) {
+ if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+
+ if (aClass == softfloat_denormal) {
+ if (softfloat_denormalsAreZeros(status))
+ a = a & 0x80000000;
+ else
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+
+ if (bClass == softfloat_denormal) {
+ if (softfloat_denormalsAreZeros(status))
+ b = b & 0x80000000;
+ else
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+
+ if ((a == b) || ((uint32_t) ((a | b)<<1) == 0)) return softfloat_relation_equal;
+
+ signA = signF32UI(a);
+ signB = signF32UI(b);
+ if (signA != signB)
+ return (signA) ? softfloat_relation_less : softfloat_relation_greater;
+
+ if (signA ^ (a < b)) return softfloat_relation_less;
+ return softfloat_relation_greater;
+}
diff --git a/src/cpu/softfloat3e/f32_div.c b/src/cpu/softfloat3e/f32_div.c
new file mode 100644
index 000000000..a9ccfcfd4
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_div.c
@@ -0,0 +1,146 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+#define SOFTFLOAT_FAST_DIV64TO32
+
+float32 f32_div(float32 a, float32 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ bool signB;
+ int16_t expB;
+ uint32_t sigB;
+ bool signZ;
+ struct exp16_sig32 normExpSig;
+ int16_t expZ;
+#ifdef SOFTFLOAT_FAST_DIV64TO32
+ uint64_t sig64A;
+ uint32_t sigZ;
+#endif
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+ signB = signF32UI(b);
+ expB = expF32UI(b);
+ sigB = fracF32UI(b);
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0xFF) {
+ if (sigA) goto propagateNaN;
+ if (expB == 0xFF) {
+ if (sigB) goto propagateNaN;
+ goto invalid;
+ }
+ if (sigB && !expB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infinity;
+ }
+ if (expB == 0xFF) {
+ if (sigB) goto propagateNaN;
+ if (sigA && !expA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expB) {
+ if (! sigB) {
+ if (! (expA | sigA)) goto invalid;
+ softfloat_raiseFlags(status, softfloat_flag_infinite);
+ goto infinity;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ if (! expA) {
+ if (! sigA) goto zero;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA - expB + 0x7E;
+ sigA |= 0x00800000;
+ sigB |= 0x00800000;
+#ifdef SOFTFLOAT_FAST_DIV64TO32
+ if (sigA < sigB) {
+ --expZ;
+ sig64A = (uint64_t) sigA<<31;
+ } else {
+ sig64A = (uint64_t) sigA<<30;
+ }
+ sigZ = sig64A / sigB;
+ if (! (sigZ & 0x3F)) sigZ |= ((uint64_t) sigB * sigZ != sig64A);
+#endif
+ return softfloat_roundPackToF32(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF32UI(a, b, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infinity:
+ return packToF32UI(signZ, 0xFF, 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ return packToF32UI(signZ, 0, 0);
+}
diff --git a/src/cpu/softfloat3e/f32_frc.c b/src/cpu/softfloat3e/f32_frc.c
new file mode 100644
index 000000000..fc1b02460
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_frc.c
@@ -0,0 +1,101 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the fractional portion of single-precision floating-point value `a',
+| and returns the result as a single-precision floating-point value. The
+| fractional results are precise. The operation is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float32 f32_frc(float32 a, struct softfloat_status_t *status)
+{
+ int roundingMode = softfloat_getRoundingMode(status);
+
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ uint32_t lastBitMask;
+ uint32_t roundBitsMask;
+
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+
+ if (expA == 0xFF) {
+ if (sigA) return softfloat_propagateNaNF32UI(a, 0, status);
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+ }
+
+ if (expA >= 0x96) {
+ return packToF32UI(roundingMode == softfloat_round_down, 0, 0);
+ }
+
+ if (expA < 0x7F) {
+ if (! expA) {
+ if (! sigA || softfloat_denormalsAreZeros(status))
+ return packToF32UI(roundingMode == softfloat_round_down, 0, 0);
+
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ if (! softfloat_isMaskedException(status, softfloat_flag_underflow))
+ softfloat_raiseFlags(status, softfloat_flag_underflow);
+
+ if (softfloat_flushUnderflowToZero(status)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
+ return packToF32UI(signA, 0, 0);
+ }
+ }
+ return a;
+ }
+
+ lastBitMask = 1 << (0x96 - expA);
+ roundBitsMask = lastBitMask - 1;
+
+ sigA &= roundBitsMask;
+ sigA <<= 7;
+ expA--;
+
+ if (! sigA)
+ return packToF32UI(roundingMode == softfloat_round_down, 0, 0);
+
+ return softfloat_normRoundPackToF32(signA, expA, sigA, status);
+}
diff --git a/src/cpu/softfloat3e/f32_getExp.c b/src/cpu/softfloat3e/f32_getExp.c
new file mode 100644
index 000000000..66b00ac7c
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_getExp.c
@@ -0,0 +1,73 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the exponent portion of single-precision floating-point value 'a',
+| and returns the result as a single-precision floating-point value
+| representing unbiased integer exponent. The operation is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float32 f32_getExp(float32 a, struct softfloat_status_t *status)
+{
+ int16_t expA;
+ uint32_t sigA;
+ struct exp16_sig32 normExpSig;
+
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+
+ if (expA == 0xFF) {
+ if (sigA) return softfloat_propagateNaNF32UI(a, 0, status);
+ return packToF32UI(0, 0xFF, 0);
+ }
+
+ if (! expA) {
+ if (! sigA || softfloat_denormalsAreZeros(status))
+ return packToF32UI(1, 0xFF, 0);
+
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigA);
+ expA = normExpSig.exp;
+ }
+
+ return i32_to_f32((int32_t)(expA) - 0x7F, status);
+}
diff --git a/src/cpu/softfloat3e/f32_getMant.c b/src/cpu/softfloat3e/f32_getMant.c
new file mode 100644
index 000000000..9dfa58a63
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_getMant.c
@@ -0,0 +1,108 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the mantissa of single-precision floating-point value 'a' and
+| returns the result as a single-precision floating-point after applying
+| the mantissa interval normalization and sign control. The operation is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float32 f32_getMant(float32 a, struct softfloat_status_t *status, int sign_ctrl, int interv)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ struct exp16_sig32 normExpSig;
+
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+
+ if (expA == 0xFF) {
+ if (sigA) return softfloat_propagateNaNF32UI(a, 0, status);
+ if (signA) {
+ if (sign_ctrl & 0x2) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+ }
+ }
+ return packToF32UI(~sign_ctrl & signA, 0x7F, 0);
+ }
+
+ if (! expA && (! sigA || softfloat_denormalsAreZeros(status))) {
+ return packToF32UI(~sign_ctrl & signA, 0x7F, 0);
+ }
+
+ if (signA) {
+ if (sign_ctrl & 0x2) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+ }
+ }
+
+ if (! expA) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ sigA &= 0x7FFFFF;
+ }
+
+ switch(interv) {
+ case 0x0: // interval [1,2)
+ expA = 0x7F;
+ break;
+ case 0x1: // interval [1/2,2)
+ expA -= 0x7F;
+ expA = 0x7F - (expA & 0x1);
+ break;
+ case 0x2: // interval [1/2,1)
+ expA = 0x7E;
+ break;
+ case 0x3: // interval [3/4,3/2)
+ expA = 0x7F - ((sigA >> 22) & 0x1);
+ break;
+ }
+
+ return packToF32UI(~sign_ctrl & signA, expA, sigA);
+}
diff --git a/src/cpu/softfloat3e/f32_minmax.c b/src/cpu/softfloat3e/f32_minmax.c
new file mode 100644
index 000000000..e36c297ae
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_minmax.c
@@ -0,0 +1,69 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Compare between two single precision floating point numbers and return the
+| smaller of them.
+*----------------------------------------------------------------------------*/
+
+float32 f32_min(float32 a, float32 b, struct softfloat_status_t *status)
+{
+ if (softfloat_denormalsAreZeros(status)) {
+ a = f32_denormal_to_zero(a);
+ b = f32_denormal_to_zero(b);
+ }
+
+ return (f32_compare_normal(a, b, status) == softfloat_relation_less) ? a : b;
+}
+
+/*----------------------------------------------------------------------------
+| Compare between two single precision floating point numbers and return the
+| larger of them.
+*----------------------------------------------------------------------------*/
+
+float32 f32_max(float32 a, float32 b, struct softfloat_status_t *status)
+{
+ if (softfloat_denormalsAreZeros(status)) {
+ a = f32_denormal_to_zero(a);
+ b = f32_denormal_to_zero(b);
+ }
+
+ return (f32_compare_normal(a, b, status) == softfloat_relation_greater) ? a : b;
+}
diff --git a/src/cpu/softfloat3e/f32_mul.c b/src/cpu/softfloat3e/f32_mul.c
new file mode 100644
index 000000000..db96e0db7
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_mul.c
@@ -0,0 +1,137 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 f32_mul(float32 a, float32 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ bool signB;
+ int16_t expB;
+ uint32_t sigB;
+ bool signZ;
+ uint32_t magBits;
+ struct exp16_sig32 normExpSig;
+ int16_t expZ;
+ uint32_t sigZ, uiZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+ signB = signF32UI(b);
+ expB = expF32UI(b);
+ sigB = fracF32UI(b);
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0xFF) {
+ if (sigA || ((expB == 0xFF) && sigB)) goto propagateNaN;
+ magBits = expB | sigB;
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infArg;
+ }
+ if (expB == 0xFF) {
+ if (sigB) goto propagateNaN;
+ magBits = expA | sigA;
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infArg;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) {
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! sigB) {
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA + expB - 0x7F;
+ sigA = (sigA | 0x00800000)<<7;
+ sigB = (sigB | 0x00800000)<<8;
+ sigZ = softfloat_shortShiftRightJam64((uint64_t) sigA * sigB, 32);
+ if (sigZ < 0x40000000) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ return softfloat_roundPackToF32(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF32UI(a, b, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infArg:
+ if (! magBits) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ = defaultNaNF32UI;
+ } else {
+ uiZ = packToF32UI(signZ, 0xFF, 0);
+ }
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ return packToF32UI(signZ, 0, 0);
+}
diff --git a/src/cpu/softfloat3e/f32_mulAdd.c b/src/cpu/softfloat3e/f32_mulAdd.c
new file mode 100644
index 000000000..101b20f18
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_mulAdd.c
@@ -0,0 +1,233 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+#include "specialize.h"
+
+float32 f32_mulAdd(float32 a, float32 b, float32 c, uint8_t op, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ bool signB;
+ int16_t expB;
+ uint32_t sigB;
+ bool signC;
+ int16_t expC;
+ uint32_t sigC;
+ bool signProd;
+ uint32_t magBits, uiA, uiB, uiC, uiZ;
+ struct exp16_sig32 normExpSig;
+ int16_t expProd;
+ uint64_t sigProd;
+ bool signZ;
+ int16_t expZ;
+ uint32_t sigZ;
+ int16_t expDiff;
+ uint64_t sig64Z, sig64C;
+ int8_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA = a;
+ uiB = b;
+ uiC = c;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF32UI(uiA);
+ expA = expF32UI(uiA);
+ sigA = fracF32UI(uiA);
+ signB = signF32UI(uiB);
+ expB = expF32UI(uiB);
+ sigB = fracF32UI(uiB);
+ signC = signF32UI(uiC) ^ ((op & softfloat_mulAdd_subC) != 0);
+ expC = expF32UI(uiC);
+ sigC = fracF32UI(uiC);
+ signProd = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ bool aisNaN = (expA == 0xFF) && sigA;
+ bool bisNaN = (expB == 0xFF) && sigB;
+ bool cisNaN = (expC == 0xFF) && sigC;
+ if (aisNaN | bisNaN | cisNaN) {
+ uiZ = (aisNaN | bisNaN) ? softfloat_propagateNaNF32UI(uiA, uiB, status) : 0;
+ return softfloat_propagateNaNF32UI(uiZ, uiC, status);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ if (!expC) sigC = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0xFF) {
+ magBits = expB | sigB;
+ goto infProdArg;
+ }
+ if (expB == 0xFF) {
+ magBits = expA | sigA;
+ goto infProdArg;
+ }
+ if (expC == 0xFF) {
+ if ((sigA && !expA) || (sigB && !expB)) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ return packToF32UI(signC, 0xFF, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! sigB) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expProd = expA + expB - 0x7E;
+ sigA = (sigA | 0x00800000)<<7;
+ sigB = (sigB | 0x00800000)<<7;
+ sigProd = (uint64_t) sigA * sigB;
+ if (sigProd < UINT64_C(0x2000000000000000)) {
+ --expProd;
+ sigProd <<= 1;
+ }
+ signZ = signProd;
+ if (! expC) {
+ if (! sigC) {
+ expZ = expProd - 1;
+ sigZ = softfloat_shortShiftRightJam64(sigProd, 31);
+ goto roundPack;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigC);
+ expC = normExpSig.exp;
+ sigC = normExpSig.sig;
+ }
+ sigC = (sigC | 0x00800000)<<6;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expProd - expC;
+ if (signProd == signC) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (expDiff <= 0) {
+ expZ = expC;
+ sigZ = sigC + softfloat_shiftRightJam64(sigProd, 32 - expDiff);
+ } else {
+ expZ = expProd;
+ sig64Z = sigProd + softfloat_shiftRightJam64((uint64_t) sigC<<32, expDiff);
+ sigZ = softfloat_shortShiftRightJam64(sig64Z, 32);
+ }
+ if (sigZ < 0x40000000) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig64C = (uint64_t) sigC<<32;
+ if (expDiff < 0) {
+ signZ = signC;
+ expZ = expC;
+ sig64Z = sig64C - softfloat_shiftRightJam64(sigProd, -expDiff);
+ } else if (! expDiff) {
+ expZ = expProd;
+ sig64Z = sigProd - sig64C;
+ if (! sig64Z) goto completeCancellation;
+ if (sig64Z & UINT64_C(0x8000000000000000)) {
+ signZ = ! signZ;
+ sig64Z = -sig64Z;
+ }
+ } else {
+ expZ = expProd;
+ sig64Z = sigProd - softfloat_shiftRightJam64(sig64C, expDiff);
+ }
+ shiftDist = softfloat_countLeadingZeros64(sig64Z) - 1;
+ expZ -= shiftDist;
+ shiftDist -= 32;
+ if (shiftDist < 0) {
+ sigZ = softfloat_shortShiftRightJam64(sig64Z, -shiftDist);
+ } else {
+ sigZ = (uint32_t) sig64Z<
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 f32_range(float32 a, float32 b, bool is_max, bool is_abs, int sign_ctrl, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ bool signB;
+ int16_t expB;
+ uint32_t sigB;
+ bool aIsNaN, bIsNaN;
+ uint32_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+ signB = signF32UI(b);
+ expB = expF32UI(b);
+ sigB = fracF32UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_isSigNaNF32UI(a)) {
+ return softfloat_propagateNaNF32UI(a, 0, status);
+ }
+ if (softfloat_isSigNaNF32UI(b)) {
+ return softfloat_propagateNaNF32UI(b, 0, status);
+ }
+
+ aIsNaN = isNaNF32UI(a);
+ bIsNaN = isNaNF32UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA && sigA) {
+ if (softfloat_denormalsAreZeros(status)) {
+ a = packToF32UI(signA, 0, 0);
+ }
+ else if (! bIsNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ }
+
+ if (! expB && sigB) {
+ if (softfloat_denormalsAreZeros(status)) {
+ b = packToF32UI(signB, 0, 0);
+ }
+ else if (! aIsNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (bIsNaN) {
+ z = a;
+ }
+ else if (aIsNaN) {
+ z = b;
+ }
+ else if (signA != signB && ! is_abs) {
+ if (! is_max) {
+ z = signA ? a : b;
+ } else {
+ z = signA ? b : a;
+ }
+ } else {
+ float32 tmp_a = a, tmp_b = b;
+ if (is_abs) {
+ tmp_a = tmp_a & ~0x80000000; // clear the sign bit
+ tmp_b = tmp_b & ~0x80000000;
+ signA = 0;
+ }
+ if (! is_max) {
+ z = (signA ^ (tmp_a < tmp_b)) ? a : b;
+ } else {
+ z = (signA ^ (tmp_a < tmp_b)) ? b : a;
+ }
+ }
+
+ switch(sign_ctrl) {
+ case 0:
+ z = (z & ~0x80000000) | (a & 0x80000000); // keep sign of a
+ break;
+ case 1:
+ break; // preserve sign of compare result
+ case 2:
+ z = z & ~0x80000000; // zero out the sign bit
+ break;
+ case 3:
+ z = z | 0x80000000; // set the sign bit
+ break;
+ }
+
+ return z;
+}
diff --git a/src/cpu/softfloat3e/f32_roundToInt.c b/src/cpu/softfloat3e/f32_roundToInt.c
new file mode 100644
index 000000000..7791fbbf4
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_roundToInt.c
@@ -0,0 +1,112 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 f32_roundToInt(float32 a, uint8_t scale, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ int32_t frac;
+ uint32_t uiZ, lastBitMask, roundBitsMask;
+ bool sign;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ scale &= 0xF;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF32UI(a);
+ frac = fracF32UI(a);
+ sign = signF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (0x96 <= (exp + scale)) {
+ if ((exp == 0xFF) && frac) {
+ return softfloat_propagateNaNF32UI(a, 0, status);
+ }
+ return a;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!exp) {
+ frac = 0;
+ a = packToF32UI(sign, 0, 0);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((exp + scale) <= 0x7E) {
+ if (!(exp | frac)) return a;
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ uiZ = packToF32UI(sign, 0, 0);
+ switch (roundingMode) {
+ case softfloat_round_near_even:
+ if (!frac) break;
+ case softfloat_round_near_maxMag:
+ if ((exp + scale) == 0x7E) uiZ |= packToF32UI(0, 0x7F - scale, 0);
+ break;
+ case softfloat_round_min:
+ if (uiZ) uiZ = packToF32UI(1, 0x7F - scale, 0);
+ break;
+ case softfloat_round_max:
+ if (!uiZ) uiZ = packToF32UI(0, 0x7F - scale, 0);
+ break;
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ = a;
+ lastBitMask = (uint32_t) 1<<(0x96 - exp - scale);
+ roundBitsMask = lastBitMask - 1;
+ if (roundingMode == softfloat_round_near_maxMag) {
+ uiZ += lastBitMask>>1;
+ } else if (roundingMode == softfloat_round_near_even) {
+ uiZ += lastBitMask>>1;
+ if (!(uiZ & roundBitsMask)) uiZ &= ~lastBitMask;
+ } else if (roundingMode == (signF32UI(uiZ) ? softfloat_round_min : softfloat_round_max)) {
+ uiZ += roundBitsMask;
+ }
+ uiZ &= ~roundBitsMask;
+ if (uiZ != a) {
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f32_scalef.c b/src/cpu/softfloat3e/f32_scalef.c
new file mode 100644
index 000000000..320baff30
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_scalef.c
@@ -0,0 +1,155 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Return the result of a floating point scale of the single-precision floating
+| point value `a' by multiplying it by 2 power of the single-precision
+| floating point value 'b' converted to integral value. If the result cannot
+| be represented in single precision, then the proper overflow response (for
+| positive scaling operand), or the proper underflow response (for negative
+| scaling operand) is issued. The operation is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float32 f32_scalef(float32 a, float32 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ bool signB;
+ int16_t expB;
+ uint32_t sigB;
+ int shiftCount;
+ int scale = 0;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+ signB = signF32UI(b);
+ expB = expF32UI(b);
+ sigB = fracF32UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expB == 0xFF) {
+ if (sigB) return softfloat_propagateNaNF32UI(a, b, status);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0xFF) {
+ if (sigA) {
+ int aIsSignalingNaN = (sigA & 0x00400000) == 0;
+ if (aIsSignalingNaN || expB != 0xFF || sigB)
+ return softfloat_propagateNaNF32UI(a, b, status);
+
+ return signB ? 0 : packToF32UI(0, 0xFF, 0);
+ }
+
+ if (expB == 0xFF && signB) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+ }
+
+ return a;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) {
+ if (expB == 0xFF && ! signB) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+ }
+ return packToF32UI(signA, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((expB | sigB) == 0) return a;
+
+ if (expB == 0xFF) {
+ if (signB) return packToF32UI(signA, 0, 0);
+ return packToF32UI(signA, 0xFF, 0);
+ }
+
+ if (expB >= 0x8E) {
+ // handle obvious overflow/underflow result
+ return softfloat_roundPackToF32(signA, signB ? -0x7F : 0xFF, sigA, status);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expB <= 0x7E) {
+ if (! expB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ scale = -signB;
+ }
+ else {
+ shiftCount = expB - 0x9E;
+ sigB = (sigB | 0x800000)<<8;
+ scale = sigB>>(-shiftCount);
+
+ if (signB) {
+ if ((uint32_t) (sigB<<(shiftCount & 31))) scale++;
+ scale = -scale;
+ }
+
+ if (scale > 0x200) scale = 0x200;
+ if (scale < -0x200) scale = -0x200;
+ }
+
+ if (expA != 0) {
+ sigA |= 0x00800000;
+ } else {
+ expA++;
+ }
+
+ expA += scale - 1;
+ sigA <<= 7;
+ return softfloat_normRoundPackToF32(signA, expA, sigA, status);
+}
diff --git a/src/cpu/softfloat3e/f32_sqrt.c b/src/cpu/softfloat3e/f32_sqrt.c
new file mode 100644
index 000000000..fc2ef8f76
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_sqrt.c
@@ -0,0 +1,117 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 f32_sqrt(float32 a, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint32_t sigA;
+ struct exp16_sig32 normExpSig;
+ int16_t expZ;
+ uint32_t sigZ, shiftedSigZ;
+ uint32_t negRem;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF32UI(a);
+ expA = expF32UI(a);
+ sigA = fracF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0xFF) {
+ if (sigA) {
+ return softfloat_propagateNaNF32UI(a, 0, status);
+ }
+ if (! signA) return a;
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) {
+ sigA = 0;
+ a = packToF32UI(signA, 0, 0);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (signA) {
+ if (! (expA | sigA)) return a;
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) return a;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = ((expA - 0x7F)>>1) + 0x7E;
+ expA &= 1;
+ sigA = (sigA | 0x00800000)<<8;
+ sigZ =
+ ((uint64_t) sigA * softfloat_approxRecipSqrt32_1(expA, sigA))>>32;
+ if (expA) sigZ >>= 1;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sigZ += 2;
+ if ((sigZ & 0x3F) < 2) {
+ shiftedSigZ = sigZ>>2;
+ negRem = shiftedSigZ * shiftedSigZ;
+ sigZ &= ~3;
+ if (negRem & 0x80000000) {
+ sigZ |= 1;
+ } else {
+ if (negRem) --sigZ;
+ }
+ }
+ return softfloat_roundPackToF32(0, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF32UI;
+}
diff --git a/src/cpu/softfloat3e/f32_to_extF80.cc b/src/cpu/softfloat3e/f32_to_extF80.cc
new file mode 100644
index 000000000..73b8bedfd
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_extF80.cc
@@ -0,0 +1,88 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t f32_to_extF80(float32 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t frac;
+ struct commonNaN commonNaN;
+ struct uint128 uiZ;
+ uint16_t uiZ64;
+ uint64_t uiZ0;
+ struct exp16_sig32 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ frac = fracF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0xFF) {
+ if (frac) {
+ softfloat_f32UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToExtF80UI(&commonNaN);
+ uiZ64 = uiZ.v64;
+ uiZ0 = uiZ.v0;
+ } else {
+ uiZ64 = packToExtF80UI64(sign, 0x7FFF);
+ uiZ0 = UINT64_C(0x8000000000000000);
+ }
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac) {
+ return packToExtF80(sign, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(frac);
+ exp = normExpSig.exp;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ64 = packToExtF80UI64(sign, exp + 0x3F80);
+ uiZ0 = (uint64_t) (frac | 0x00800000)<<40;
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+}
diff --git a/src/cpu/softfloat3e/f32_to_f128.cc b/src/cpu/softfloat3e/f32_to_f128.cc
new file mode 100644
index 000000000..6d3fafec2
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_f128.cc
@@ -0,0 +1,86 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float128_t f32_to_f128(float32 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t frac;
+ struct commonNaN commonNaN;
+ struct uint128 uiZ;
+ struct exp16_sig32 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ frac = fracF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0xFF) {
+ if (frac) {
+ softfloat_f32UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF128UI(&commonNaN);
+ } else {
+ uiZ.v64 = packToF128UI64(sign, 0x7FFF, 0);
+ uiZ.v0 = 0;
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac) {
+ uiZ.v64 = packToF128UI64(sign, 0, 0);
+ uiZ.v0 = 0;
+ return uiZ;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(frac);
+ exp = normExpSig.exp - 1;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ.v64 = packToF128UI64(sign, exp + 0x3F80, (uint64_t) frac<<25);
+ uiZ.v0 = 0;
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f32_to_f16.c b/src/cpu/softfloat3e/f32_to_f16.c
new file mode 100644
index 000000000..9253a958a
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_f16.c
@@ -0,0 +1,82 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float16 f32_to_f16(float32 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t frac;
+ struct commonNaN commonNaN;
+ uint16_t uiZ, frac16;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ frac = fracF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0xFF) {
+ if (frac) {
+ softfloat_f32UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF16UI(&commonNaN);
+ } else {
+ uiZ = packToF16UI(sign, 0x1F, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (!exp && frac) {
+ if (softfloat_denormalsAreZeros(status))
+ return packToF16UI(sign, 0, 0);
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ frac16 = frac>>9 | ((frac & 0x1FF) != 0);
+ if (! (exp | frac16)) {
+ return packToF16UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ return softfloat_roundPackToF16(sign, exp - 0x71, frac16 | 0x4000, status);
+}
diff --git a/src/cpu/softfloat3e/f32_to_f64.c b/src/cpu/softfloat3e/f32_to_f64.c
new file mode 100644
index 000000000..28ebb61b6
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_f64.c
@@ -0,0 +1,81 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f32_to_f64(float32 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t frac;
+ struct commonNaN commonNaN;
+ uint64_t uiZ;
+ struct exp16_sig32 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ frac = fracF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0xFF) {
+ if (frac) {
+ softfloat_f32UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF64UI(&commonNaN);
+ } else {
+ uiZ = packToF64UI(sign, 0x7FF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac || softfloat_denormalsAreZeros(status)) {
+ return packToF64UI(sign, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF32Sig(frac);
+ exp = normExpSig.exp - 1;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ return packToF64UI(sign, exp + 0x380, (uint64_t) frac<<29);
+}
diff --git a/src/cpu/softfloat3e/f32_to_i32.c b/src/cpu/softfloat3e/f32_to_i32.c
new file mode 100644
index 000000000..2b3df52a3
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_i32.c
@@ -0,0 +1,78 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f32_to_i32(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t sig;
+ uint64_t sig64;
+ int16_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow)
+ if ((exp == 0xFF) && sig) {
+#if (i32_fromNaN == i32_fromPosOverflow)
+ sign = 0;
+#elif (i32_fromNaN == i32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= 0x00800000;
+ else if (softfloat_denormalsAreZeros(status)) sig = 0;
+ sig64 = (uint64_t) sig<<32;
+ shiftDist = 0xAA - exp;
+ if (0 < shiftDist) sig64 = softfloat_shiftRightJam64(sig64, shiftDist);
+ return softfloat_roundToI32(sign, sig64, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f32_to_i32_r_minMag.c b/src/cpu/softfloat3e/f32_to_i32_r_minMag.c
new file mode 100644
index 000000000..abe782d3b
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_i32_r_minMag.c
@@ -0,0 +1,83 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f32_to_i32_r_minMag(float32 a, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ uint32_t sig;
+ int16_t shiftDist;
+ bool sign;
+ int32_t absZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x9E - exp;
+ if (32 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ if (shiftDist <= 0) {
+ if (a == packToF32UI(1, 0x9E, 0)) return -0x7FFFFFFF - 1;
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0xFF) && sig
+ ? i32_fromNaN
+ : sign ? i32_fromNegOverflow : i32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig = (sig | 0x00800000)<<8;
+ absZ = sig>>shiftDist;
+ if (exact && ((uint32_t) absZ<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f32_to_i64(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t sig;
+ int16_t shiftDist;
+ uint64_t sig64, extra;
+ struct uint64_extra sig64Extra;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0xBE - exp;
+ if (shiftDist < 0) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0xFF) && sig
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= 0x00800000;
+ sig64 = (uint64_t) sig<<40;
+ extra = 0;
+ if (shiftDist) {
+ sig64Extra = softfloat_shiftRightJam64Extra(sig64, 0, shiftDist);
+ sig64 = sig64Extra.v;
+ extra = sig64Extra.extra;
+ }
+ return softfloat_roundToI64(sign, sig64, extra, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f32_to_i64_r_minMag.c b/src/cpu/softfloat3e/f32_to_i64_r_minMag.c
new file mode 100644
index 000000000..2ccabd09d
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_i64_r_minMag.c
@@ -0,0 +1,88 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f32_to_i64_r_minMag(float32 a, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ uint32_t sig;
+ int16_t shiftDist;
+ bool sign;
+ uint64_t sig64;
+ int64_t absZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0xBE - exp;
+ if (64 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ if (shiftDist <= 0) {
+ if (a == packToF32UI(1, 0xBE, 0)) {
+ return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0xFF) && sig
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig |= 0x00800000;
+ sig64 = (uint64_t) sig<<40;
+ absZ = sig64>>shiftDist;
+ shiftDist = 40 - shiftDist;
+ if (exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31))) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return sign ? -absZ : absZ;
+}
diff --git a/src/cpu/softfloat3e/f32_to_ui32.c b/src/cpu/softfloat3e/f32_to_ui32.c
new file mode 100644
index 000000000..5a8d57414
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_ui32.c
@@ -0,0 +1,80 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f32_to_ui32(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t sig;
+ uint64_t sig64;
+ int16_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)
+ if ((exp == 0xFF) && sig) {
+#if (ui32_fromNaN == ui32_fromPosOverflow)
+ sign = 0;
+#elif (ui32_fromNaN == ui32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= 0x00800000;
+ else if (softfloat_denormalsAreZeros(status)) sig = 0;
+ sig64 = (uint64_t) sig<<32;
+ shiftDist = 0xAA - exp;
+ if (0 < shiftDist) sig64 = softfloat_shiftRightJam64(sig64, shiftDist);
+ return softfloat_roundToUI32(sign, sig64, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f32_to_ui32_r_minMag.c b/src/cpu/softfloat3e/f32_to_ui32_r_minMag.c
new file mode 100644
index 000000000..4b37708b0
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_ui32_r_minMag.c
@@ -0,0 +1,83 @@
+
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f32_to_ui32_r_minMag(float32 a, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ uint32_t sig;
+ int16_t shiftDist;
+ bool sign;
+ uint32_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x9E - exp;
+ if (32 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ if (sign || (shiftDist < 0)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0xFF) && sig
+ ? ui32_fromNaN
+ : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig = (sig | 0x00800000)<<8;
+ z = sig>>shiftDist;
+ if (exact && (z<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f32_to_ui64(float32 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint32_t sig;
+ int16_t shiftDist;
+ uint64_t sig64, extra;
+ struct uint64_extra sig64Extra;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0xBE - exp;
+ if (shiftDist < 0) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0xFF) && sig
+ ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= 0x00800000;
+ else if (softfloat_denormalsAreZeros(status)) sig = 0;
+ sig64 = (uint64_t) sig<<40;
+ extra = 0;
+ if (shiftDist) {
+ sig64Extra = softfloat_shiftRightJam64Extra(sig64, 0, shiftDist);
+ sig64 = sig64Extra.v;
+ extra = sig64Extra.extra;
+ }
+ return softfloat_roundToUI64(sign, sig64, extra, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f32_to_ui64_r_minMag.c b/src/cpu/softfloat3e/f32_to_ui64_r_minMag.c
new file mode 100644
index 000000000..111c50e7f
--- /dev/null
+++ b/src/cpu/softfloat3e/f32_to_ui64_r_minMag.c
@@ -0,0 +1,84 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f32_to_ui64_r_minMag(float32 a, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ uint32_t sig;
+ int16_t shiftDist;
+ bool sign;
+ uint64_t sig64, z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF32UI(a);
+ sig = fracF32UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0xBE - exp;
+ if (64 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF32UI(a);
+ if (sign || (shiftDist < 0)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0xFF) && sig
+ ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig |= 0x00800000;
+ sig64 = (uint64_t) sig<<40;
+ z = sig64>>shiftDist;
+ shiftDist = 40 - shiftDist;
+ if (exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31))) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return z;
+}
diff --git a/src/cpu/softfloat3e/f64_addsub.c b/src/cpu/softfloat3e/f64_addsub.c
new file mode 100644
index 000000000..6c5acb4f7
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_addsub.c
@@ -0,0 +1,70 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+extern float64 softfloat_addMagsF64(uint64_t, uint64_t, bool, struct softfloat_status_t *);
+extern float64 softfloat_subMagsF64(uint64_t, uint64_t, bool, struct softfloat_status_t *);
+
+float64 f64_add(float64 a, float64 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ bool signB;
+
+ signA = signF64UI(a);
+ signB = signF64UI(b);
+ if (signA == signB) {
+ return softfloat_addMagsF64(a, b, signA, status);
+ } else {
+ return softfloat_subMagsF64(a, b, signA, status);
+ }
+}
+
+float64 f64_sub(float64 a, float64 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ bool signB;
+
+ signA = signF64UI(a);
+ signB = signF64UI(b);
+ if (signA == signB) {
+ return softfloat_subMagsF64(a, b, signA, status);
+ } else {
+ return softfloat_addMagsF64(a, b, signA, status);
+ }
+}
diff --git a/src/cpu/softfloat3e/f64_class.c b/src/cpu/softfloat3e/f64_class.c
new file mode 100644
index 000000000..1d44a6351
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_class.c
@@ -0,0 +1,64 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+softfloat_class_t f64_class(float64 a)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+
+ if (expA == 0x7FF) {
+ if (sigA == 0)
+ return (signA) ? softfloat_negative_inf : softfloat_positive_inf;
+
+ return (sigA & UINT64_C(0x0008000000000000)) ? softfloat_QNaN : softfloat_SNaN;
+ }
+
+ if (expA == 0) {
+ if (sigA == 0) return softfloat_zero;
+ return softfloat_denormal;
+ }
+
+ return softfloat_normalized;
+}
diff --git a/src/cpu/softfloat3e/f64_compare.c b/src/cpu/softfloat3e/f64_compare.c
new file mode 100644
index 000000000..aed250768
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_compare.c
@@ -0,0 +1,92 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Compare between two double precision floating point numbers. Returns
+| 'float_relation_equal' if the operands are equal, 'float_relation_less' if
+| the value 'a' is less than the corresponding value `b',
+| 'float_relation_greater' if the value 'a' is greater than the corresponding
+| value `b', or 'float_relation_unordered' otherwise.
+*----------------------------------------------------------------------------*/
+
+int f64_compare(float64 a, float64 b, bool quiet, struct softfloat_status_t *status)
+{
+ softfloat_class_t aClass;
+ softfloat_class_t bClass;
+ bool signA;
+ bool signB;
+
+ aClass = f64_class(a);
+ bClass = f64_class(b);
+
+ if (aClass == softfloat_SNaN || bClass == softfloat_SNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+
+ if (aClass == softfloat_QNaN || bClass == softfloat_QNaN) {
+ if (! quiet) softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return softfloat_relation_unordered;
+ }
+
+ if (aClass == softfloat_denormal) {
+ if (softfloat_denormalsAreZeros(status))
+ a = a & UINT64_C(0x8000000000000000);
+ else
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+
+ if (bClass == softfloat_denormal) {
+ if (softfloat_denormalsAreZeros(status))
+ b = b & UINT64_C(0x8000000000000000);
+ else
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+
+ if ((a == b) || ((uint64_t) ((a | b)<<1) == 0)) return softfloat_relation_equal;
+
+ signA = signF64UI(a);
+ signB = signF64UI(b);
+ if (signA != signB)
+ return (signA) ? softfloat_relation_less : softfloat_relation_greater;
+
+ if (signA ^ (a < b)) return softfloat_relation_less;
+ return softfloat_relation_greater;
+}
diff --git a/src/cpu/softfloat3e/f64_div.c b/src/cpu/softfloat3e/f64_div.c
new file mode 100644
index 000000000..89f74f1b1
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_div.c
@@ -0,0 +1,165 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f64_div(float64 a, float64 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ bool signB;
+ int16_t expB;
+ uint64_t sigB;
+ bool signZ;
+ struct exp16_sig64 normExpSig;
+ int16_t expZ;
+ uint32_t recip32, sig32Z, doubleTerm;
+ uint64_t rem;
+ uint32_t q;
+ uint64_t sigZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+ signB = signF64UI(b);
+ expB = expF64UI(b);
+ sigB = fracF64UI(b);
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FF) {
+ if (sigA) goto propagateNaN;
+ if (expB == 0x7FF) {
+ if (sigB) goto propagateNaN;
+ goto invalid;
+ }
+ if (sigB && !expB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infinity;
+ }
+ if (expB == 0x7FF) {
+ if (sigB) goto propagateNaN;
+ if (sigA && !expA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expB) {
+ if (! sigB) {
+ if (! (expA | sigA)) goto invalid;
+ softfloat_raiseFlags(status, softfloat_flag_infinite);
+ goto infinity;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ if (! expA) {
+ if (! sigA) goto zero;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA - expB + 0x3FE;
+ sigA |= UINT64_C(0x0010000000000000);
+ sigB |= UINT64_C(0x0010000000000000);
+ if (sigA < sigB) {
+ --expZ;
+ sigA <<= 11;
+ } else {
+ sigA <<= 10;
+ }
+ sigB <<= 11;
+ recip32 = softfloat_approxRecip32_1(sigB>>32) - 2;
+ sig32Z = ((uint32_t) (sigA>>32) * (uint64_t) recip32)>>32;
+ doubleTerm = sig32Z<<1;
+ rem =
+ ((sigA - (uint64_t) doubleTerm * (uint32_t) (sigB>>32))<<28)
+ - (uint64_t) doubleTerm * ((uint32_t) sigB>>4);
+ q = (((uint32_t) (rem>>32) * (uint64_t) recip32)>>32) + 4;
+ sigZ = ((uint64_t) sig32Z<<32) + ((uint64_t) q<<4);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((sigZ & 0x1FF) < 4<<4) {
+ q &= ~7;
+ sigZ &= ~(uint64_t) 0x7F;
+ doubleTerm = q<<1;
+ rem =
+ ((rem - (uint64_t) doubleTerm * (uint32_t) (sigB>>32))<<28)
+ - (uint64_t) doubleTerm * ((uint32_t) sigB>>4);
+ if (rem & UINT64_C(0x8000000000000000)) {
+ sigZ -= 1<<7;
+ } else {
+ if (rem) sigZ |= 1;
+ }
+ }
+ return softfloat_roundPackToF64(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF64UI(a, b, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infinity:
+ return packToF64UI(signZ, 0x7FF, 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ return packToF64UI(signZ, 0, 0);
+}
diff --git a/src/cpu/softfloat3e/f64_frc.c b/src/cpu/softfloat3e/f64_frc.c
new file mode 100644
index 000000000..46c21ac4f
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_frc.c
@@ -0,0 +1,101 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the fractional portion of double-precision floating-point value `a',
+| and returns the result as a double-precision floating-point value. The
+| fractional results are precise. The operation is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float64 f64_frc(float64 a, struct softfloat_status_t *status)
+{
+ int roundingMode = softfloat_getRoundingMode(status);
+
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ uint64_t lastBitMask;
+ uint64_t roundBitsMask;
+
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+
+ if (expA == 0x7FF) {
+ if (sigA) return softfloat_propagateNaNF64UI(a, 0, status);
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+ }
+
+ if (expA >= 0x433) {
+ return packToF64UI(roundingMode == softfloat_round_down, 0, 0);
+ }
+
+ if (expA < 0x3FF) {
+ if (! expA) {
+ if (! sigA || softfloat_denormalsAreZeros(status))
+ return packToF64UI(roundingMode == softfloat_round_down, 0, 0);
+
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ if (! softfloat_isMaskedException(status, softfloat_flag_underflow))
+ softfloat_raiseFlags(status, softfloat_flag_underflow);
+
+ if (softfloat_flushUnderflowToZero(status)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
+ return packToF64UI(signA, 0, 0);
+ }
+ }
+ return a;
+ }
+
+ lastBitMask = UINT64_C(1) << (0x433 - expA);
+ roundBitsMask = lastBitMask - 1;
+
+ sigA &= roundBitsMask;
+ sigA <<= 10;
+ expA--;
+
+ if (! sigA)
+ return packToF64UI(roundingMode == softfloat_round_down, 0, 0);
+
+ return softfloat_normRoundPackToF64(signA, expA, sigA, status);
+}
diff --git a/src/cpu/softfloat3e/f64_getExp.c b/src/cpu/softfloat3e/f64_getExp.c
new file mode 100644
index 000000000..b76cc996d
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_getExp.c
@@ -0,0 +1,73 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the exponent portion of double-precision floating-point value 'a',
+| and returns the result as a double-precision floating-point value
+| representing unbiased integer exponent. The operation is performed according
+| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float64 f64_getExp(float64 a, struct softfloat_status_t *status)
+{
+ int16_t expA;
+ uint64_t sigA;
+ struct exp16_sig64 normExpSig;
+
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+
+ if (expA == 0x7FF) {
+ if (sigA) return softfloat_propagateNaNF64UI(a, 0, status);
+ return packToF64UI(0, 0x7FF, 0);
+ }
+
+ if (! expA) {
+ if (! sigA || softfloat_denormalsAreZeros(status))
+ return packToF64UI(1, 0x7FF, 0);
+
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigA);
+ expA = normExpSig.exp;
+ }
+
+ return i32_to_f64((int32_t)(expA) - 0x3FF);
+}
diff --git a/src/cpu/softfloat3e/f64_getMant.c b/src/cpu/softfloat3e/f64_getMant.c
new file mode 100644
index 000000000..84077e314
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_getMant.c
@@ -0,0 +1,108 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Extracts the mantissa of double-precision floating-point value 'a' and
+| returns the result as a double-precision floating-point after applying
+| the mantissa interval normalization and sign control. The operation is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float64 f64_getMant(float64 a, struct softfloat_status_t *status, int sign_ctrl, int interv)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ struct exp16_sig64 normExpSig;
+
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+
+ if (expA == 0x7FF) {
+ if (sigA) return softfloat_propagateNaNF64UI(a, 0, status);
+ if (signA) {
+ if (sign_ctrl & 0x2) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+ }
+ }
+ return packToF64UI(~sign_ctrl & signA, 0x3FF, 0);
+ }
+
+ if (! expA && (! sigA || softfloat_denormalsAreZeros(status))) {
+ return packToF64UI(~sign_ctrl & signA, 0x3FF, 0);
+ }
+
+ if (signA) {
+ if (sign_ctrl & 0x2) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+ }
+ }
+
+ if (expA == 0) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ sigA &= UINT64_C(0xFFFFFFFFFFFFF);
+ }
+
+ switch(interv) {
+ case 0x0: // interval [1,2)
+ expA = 0x3FF;
+ break;
+ case 0x1: // interval [1/2,2)
+ expA -= 0x3FF;
+ expA = 0x3FF - (expA & 0x1);
+ break;
+ case 0x2: // interval [1/2,1)
+ expA = 0x3FE;
+ break;
+ case 0x3: // interval [3/4,3/2)
+ expA = 0x3FF - ((sigA >> 51) & 0x1);
+ break;
+ }
+
+ return packToF64UI(~sign_ctrl & signA, expA, sigA);
+}
diff --git a/src/cpu/softfloat3e/f64_minmax.c b/src/cpu/softfloat3e/f64_minmax.c
new file mode 100644
index 000000000..3c927410a
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_minmax.c
@@ -0,0 +1,69 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Compare between two double precision floating point numbers and return the
+| smaller of them.
+*----------------------------------------------------------------------------*/
+
+float64 f64_min(float64 a, float64 b, struct softfloat_status_t *status)
+{
+ if (softfloat_denormalsAreZeros(status)) {
+ a = f64_denormal_to_zero(a);
+ b = f64_denormal_to_zero(b);
+ }
+
+ return (f64_compare_normal(a, b, status) == softfloat_relation_less) ? a : b;
+}
+
+/*----------------------------------------------------------------------------
+| Compare between two double precision floating point numbers and return the
+| larger of them.
+*----------------------------------------------------------------------------*/
+
+float64 f64_max(float64 a, float64 b, struct softfloat_status_t *status)
+{
+ if (softfloat_denormalsAreZeros(status)) {
+ a = f64_denormal_to_zero(a);
+ b = f64_denormal_to_zero(b);
+ }
+
+ return (f64_compare_normal(a, b, status) == softfloat_relation_greater) ? a : b;
+}
diff --git a/src/cpu/softfloat3e/f64_mul.c b/src/cpu/softfloat3e/f64_mul.c
new file mode 100644
index 000000000..c1e98f2b6
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_mul.c
@@ -0,0 +1,139 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f64_mul(float64 a, float64 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ bool signB;
+ int16_t expB;
+ uint64_t sigB;
+ bool signZ;
+ uint64_t magBits;
+ struct exp16_sig64 normExpSig;
+ int16_t expZ;
+ struct uint128 sig128Z;
+ uint64_t sigZ, uiZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+ signB = signF64UI(b);
+ expB = expF64UI(b);
+ sigB = fracF64UI(b);
+ signZ = signA ^ signB;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FF) {
+ if (sigA || ((expB == 0x7FF) && sigB)) goto propagateNaN;
+ magBits = expB | sigB;
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infArg;
+ }
+ if (expB == 0x7FF) {
+ if (sigB) goto propagateNaN;
+ magBits = expA | sigA;
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto infArg;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) {
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! sigB) {
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ goto zero;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA + expB - 0x3FF;
+ sigA = (sigA | UINT64_C(0x0010000000000000))<<10;
+ sigB = (sigB | UINT64_C(0x0010000000000000))<<11;
+ sig128Z = softfloat_mul64To128(sigA, sigB);
+ sigZ = sig128Z.v64 | (sig128Z.v0 != 0);
+ if (sigZ < UINT64_C(0x4000000000000000)) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ return softfloat_roundPackToF64(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF64UI(a, b, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infArg:
+ if (! magBits) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ = defaultNaNF64UI;
+ } else {
+ uiZ = packToF64UI(signZ, 0x7FF, 0);
+ }
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zero:
+ return packToF64UI(signZ, 0, 0);
+}
diff --git a/src/cpu/softfloat3e/f64_mulAdd.c b/src/cpu/softfloat3e/f64_mulAdd.c
new file mode 100644
index 000000000..9623b4980
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_mulAdd.c
@@ -0,0 +1,243 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+#include "specialize.h"
+
+float64 f64_mulAdd(float64 a, float64 b, float64 c, uint8_t op, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ bool signB;
+ int16_t expB;
+ uint64_t sigB;
+ bool signC;
+ int16_t expC;
+ uint64_t sigC;
+ bool signZ;
+ uint64_t magBits, uiA, uiB, uiC, uiZ;
+ struct exp16_sig64 normExpSig;
+ int16_t expZ;
+ struct uint128 sig128Z;
+ uint64_t sigZ;
+ int16_t expDiff;
+ struct uint128 sig128C;
+ int8_t shiftDist;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiA = a;
+ uiB = b;
+ uiC = c;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF64UI(uiA);
+ expA = expF64UI(uiA);
+ sigA = fracF64UI(uiA);
+ signB = signF64UI(uiB);
+ expB = expF64UI(uiB);
+ sigB = fracF64UI(uiB);
+ signC = signF64UI(uiC) ^ ((op & softfloat_mulAdd_subC) != 0);
+ expC = expF64UI(uiC);
+ sigC = fracF64UI(uiC);
+ signZ = signA ^ signB ^ ((op & softfloat_mulAdd_subProd) != 0);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ bool aisNaN = (expA == 0x7FF) && sigA;
+ bool bisNaN = (expB == 0x7FF) && sigB;
+ bool cisNaN = (expC == 0x7FF) && sigC;
+ if (aisNaN | bisNaN | cisNaN) {
+ uiZ = (aisNaN | bisNaN) ? softfloat_propagateNaNF64UI(uiA, uiB, status) : 0;
+ return softfloat_propagateNaNF64UI(uiZ, uiC, status);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ if (!expC) sigC = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FF) {
+ magBits = expB | sigB;
+ goto infProdArg;
+ }
+ if (expB == 0x7FF) {
+ magBits = expA | sigA;
+ goto infProdArg;
+ }
+ if (expC == 0x7FF) {
+ if ((sigA && !expA) || (sigB && !expB)) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ return packToF64UI(signC, 0x7FF, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ if (! expB) {
+ if (! sigB) goto zeroProd;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigB);
+ expB = normExpSig.exp;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expZ = expA + expB - 0x3FE;
+ sigA = (sigA | UINT64_C(0x0010000000000000))<<10;
+ sigB = (sigB | UINT64_C(0x0010000000000000))<<10;
+ sig128Z = softfloat_mul64To128(sigA, sigB);
+ if (sig128Z.v64 < UINT64_C(0x2000000000000000)) {
+ --expZ;
+ sig128Z = softfloat_add128(sig128Z.v64, sig128Z.v0, sig128Z.v64, sig128Z.v0);
+ }
+ if (! expC) {
+ if (! sigC) {
+ --expZ;
+ sigZ = sig128Z.v64<<1 | (sig128Z.v0 != 0);
+ goto roundPack;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigC);
+ expC = normExpSig.exp;
+ sigC = normExpSig.sig;
+ }
+ sigC = (sigC | UINT64_C(0x0010000000000000))<<9;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expZ - expC;
+ if (expDiff < 0) {
+ expZ = expC;
+ if ((signZ == signC) || (expDiff < -1)) {
+ sig128Z.v64 = softfloat_shiftRightJam64(sig128Z.v64, -expDiff);
+ } else {
+ sig128Z = softfloat_shortShiftRightJam128(sig128Z.v64, sig128Z.v0, 1);
+ }
+ } else if (expDiff) {
+ sig128C = softfloat_shiftRightJam128(sigC, 0, expDiff);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (signZ == signC) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (expDiff <= 0) {
+ sigZ = (sigC + sig128Z.v64) | (sig128Z.v0 != 0);
+ } else {
+ sig128Z = softfloat_add128(sig128Z.v64, sig128Z.v0, sig128C.v64, sig128C.v0);
+ sigZ = sig128Z.v64 | (sig128Z.v0 != 0);
+ }
+ if (sigZ < UINT64_C(0x4000000000000000)) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (expDiff < 0) {
+ signZ = signC;
+ sig128Z = softfloat_sub128(sigC, 0, sig128Z.v64, sig128Z.v0);
+ } else if (! expDiff) {
+ sig128Z.v64 = sig128Z.v64 - sigC;
+ if (! (sig128Z.v64 | sig128Z.v0)) goto completeCancellation;
+ if (sig128Z.v64 & UINT64_C(0x8000000000000000)) {
+ signZ = ! signZ;
+ sig128Z = softfloat_sub128(0, 0, sig128Z.v64, sig128Z.v0);
+ }
+ } else {
+ sig128Z = softfloat_sub128(sig128Z.v64, sig128Z.v0, sig128C.v64, sig128C.v0);
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (! sig128Z.v64) {
+ expZ -= 64;
+ sig128Z.v64 = sig128Z.v0;
+ sig128Z.v0 = 0;
+ }
+ shiftDist = softfloat_countLeadingZeros64(sig128Z.v64) - 1;
+ expZ -= shiftDist;
+ if (shiftDist < 0) {
+ sigZ = softfloat_shortShiftRightJam64(sig128Z.v64, -shiftDist);
+ } else {
+ sig128Z = softfloat_shortShiftLeft128(sig128Z.v64, sig128Z.v0, shiftDist);
+ sigZ = sig128Z.v64;
+ }
+ sigZ |= (sig128Z.v0 != 0);
+ }
+ roundPack:
+ return softfloat_roundPackToF64(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ infProdArg:
+ if (magBits) {
+ uiZ = packToF64UI(signZ, 0x7FF, 0);
+ if (signZ == signC || expC != 0x7FF) {
+ if ((sigA && !expA) || (sigB && !expB) || (sigC && !expC))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return uiZ;
+ }
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ uiZ = defaultNaNF64UI;
+ return softfloat_propagateNaNF64UI(uiZ, uiC, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ zeroProd:
+ uiZ = packToF64UI(signC, expC, sigC);
+ if (!expC && sigC) {
+ /* Exact zero plus a denormal */
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ if (softfloat_flushUnderflowToZero(status)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
+ return packToF64UI(signC, 0, 0);
+ }
+ }
+ if (! (expC | sigC) && (signZ != signC)) {
+ completeCancellation:
+ uiZ = packToF64UI((softfloat_getRoundingMode(status) == softfloat_round_min), 0, 0);
+ }
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f64_range.c b/src/cpu/softfloat3e/f64_range.c
new file mode 100644
index 000000000..6f01c84cc
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_range.c
@@ -0,0 +1,135 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f64_range(float64 a, float64 b, bool is_max, bool is_abs, int sign_ctrl, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ bool signB;
+ int16_t expB;
+ uint64_t sigB;
+ bool aIsNaN, bIsNaN;
+ uint64_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+ signB = signF64UI(b);
+ expB = expF64UI(b);
+ sigB = fracF64UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_isSigNaNF64UI(a)) {
+ return softfloat_propagateNaNF64UI(a, 0, status);
+ }
+ if (softfloat_isSigNaNF64UI(b)) {
+ return softfloat_propagateNaNF64UI(b, 0, status);
+ }
+
+ aIsNaN = isNaNF64UI(a);
+ bIsNaN = isNaNF64UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA && sigA) {
+ if (softfloat_denormalsAreZeros(status)) {
+ a = packToF64UI(signA, 0, 0);
+ }
+ else if (! bIsNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ }
+
+ if (! expB && sigB) {
+ if (softfloat_denormalsAreZeros(status)) {
+ b = packToF64UI(signB, 0, 0);
+ }
+ else if (! aIsNaN) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (bIsNaN) {
+ z = a;
+ }
+ else if (aIsNaN) {
+ z = b;
+ }
+ else if (signA != signB && ! is_abs) {
+ if (! is_max) {
+ z = signA ? a : b;
+ } else {
+ z = signA ? b : a;
+ }
+ } else {
+ float64 tmp_a = a, tmp_b = b;
+ if (is_abs) {
+ tmp_a = tmp_a & ~UINT64_C(0x8000000000000000); // clear the sign bit
+ tmp_b = tmp_b & ~UINT64_C(0x8000000000000000);
+ signA = 0;
+ }
+
+ if (! is_max) {
+ z = (signA ^ (tmp_a < tmp_b)) ? a : b;
+ } else {
+ z = (signA ^ (tmp_a < tmp_b)) ? b : a;
+ }
+ }
+
+ switch(sign_ctrl) {
+ case 0:
+ z = (z & ~UINT64_C(0x8000000000000000)) | (a & UINT64_C(0x8000000000000000)); // keep sign of a
+ break;
+ case 1:
+ break; // preserve sign of compare result
+ case 2:
+ z = z & ~UINT64_C(0x8000000000000000); // zero out the sign bit
+ break;
+ case 3:
+ z = z | UINT64_C(0x8000000000000000); // set the sign bit
+ break;
+ }
+
+ return z;
+}
diff --git a/src/cpu/softfloat3e/f64_roundToInt.c b/src/cpu/softfloat3e/f64_roundToInt.c
new file mode 100644
index 000000000..3c5f7fb8c
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_roundToInt.c
@@ -0,0 +1,112 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f64_roundToInt(float64 a, uint8_t scale, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ int64_t frac;
+ bool sign;
+ uint64_t uiZ, lastBitMask, roundBitsMask;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ scale &= 0xF;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF64UI(a);
+ frac = fracF64UI(a);
+ sign = signF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (0x433 <= (exp + scale)) {
+ if ((exp == 0x7FF) && frac) {
+ return softfloat_propagateNaNF64UI(a, 0, status);
+ }
+ return a;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!exp) {
+ frac = 0;
+ a = packToF64UI(sign, 0, 0);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((exp + scale) <= 0x3FE) {
+ if (!(exp | frac)) return a;
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ uiZ = packToF64UI(sign, 0, 0);
+ switch (roundingMode) {
+ case softfloat_round_near_even:
+ if (!frac) break;
+ case softfloat_round_near_maxMag:
+ if ((exp + scale) == 0x3FE) uiZ |= packToF64UI(0, 0x3FF - scale, 0);
+ break;
+ case softfloat_round_min:
+ if (uiZ) uiZ = packToF64UI(1, 0x3FF - scale, 0);
+ break;
+ case softfloat_round_max:
+ if (!uiZ) uiZ = packToF64UI(0, 0x3FF - scale, 0);
+ break;
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ = a;
+ lastBitMask = (uint64_t) 1<<(0x433 - exp - scale);
+ roundBitsMask = lastBitMask - 1;
+ if (roundingMode == softfloat_round_near_maxMag) {
+ uiZ += lastBitMask>>1;
+ } else if (roundingMode == softfloat_round_near_even) {
+ uiZ += lastBitMask>>1;
+ if (!(uiZ & roundBitsMask)) uiZ &= ~lastBitMask;
+ } else if (roundingMode == (signF64UI(uiZ) ? softfloat_round_min : softfloat_round_max)) {
+ uiZ += roundBitsMask;
+ }
+ uiZ &= ~roundBitsMask;
+ if (uiZ != a) {
+ if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f64_scalef.c b/src/cpu/softfloat3e/f64_scalef.c
new file mode 100644
index 000000000..7a552ccc3
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_scalef.c
@@ -0,0 +1,156 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Return the result of a floating point scale of the double-precision floating
+| point value `a' by multiplying it by 2 power of the double-precision
+| floating point value 'b' converted to integral value. If the result cannot
+| be represented in double precision, then the proper overflow response (for
+| positive scaling operand), or the proper underflow response (for negative
+| scaling operand) is issued. The operation is performed according to the
+| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+float64 f64_scalef(float64 a, float64 b, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ bool signB;
+ int16_t expB;
+ uint64_t sigB;
+ int shiftCount;
+ int scale = 0;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+ signB = signF64UI(b);
+ expB = expF64UI(b);
+ sigB = fracF64UI(b);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expB == 0x7FF) {
+ if (sigB) return softfloat_propagateNaNF64UI(a, b, status);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) sigA = 0;
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FF) {
+ if (sigA) {
+ int aIsSignalingNaN = (sigA & UINT64_C(0x0008000000000000)) == 0;
+ if (aIsSignalingNaN || expB != 0x7FF || sigB)
+ return softfloat_propagateNaNF64UI(a, b, status);
+
+ return signB ? 0 : packToF64UI(0, 0x7FF, 0);
+ }
+
+ if (expB == 0x7FF && signB) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+ }
+
+ return a;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) {
+ if (expB == 0x7FF && ! signB) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+ }
+ return packToF64UI(signA, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((expB | sigB) == 0) return a;
+
+ if (expB == 0x7FF) {
+ if (signB) return packToF64UI(signA, 0, 0);
+ return packToF64UI(signA, 0x7FF, 0);
+ }
+
+ if (0x40F <= expB) {
+ // handle obvious overflow/underflow result
+ return softfloat_roundPackToF64(signA, signB ? -0x3FF : 0x7FF, sigA, status);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expB < 0x3FF) {
+ if (expB == 0)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ scale = -signB;
+ }
+ else {
+ sigB |= UINT64_C(0x0010000000000000);
+ shiftCount = 0x433 - expB;
+ uint64_t prev_sigB = sigB;
+ sigB >>= shiftCount;
+ scale = (int32_t) sigB;
+ if (signB) {
+ if ((sigB< 0x1000) scale = 0x1000;
+ if (scale < -0x1000) scale = -0x1000;
+ }
+
+ if (expA != 0) {
+ sigA |= UINT64_C(0x0010000000000000);
+ } else {
+ expA++;
+ }
+
+ expA += scale - 1;
+ sigA <<= 10;
+ return softfloat_normRoundPackToF64(signA, expA, sigA, status);
+}
diff --git a/src/cpu/softfloat3e/f64_sqrt.c b/src/cpu/softfloat3e/f64_sqrt.c
new file mode 100644
index 000000000..d3ea81af8
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_sqrt.c
@@ -0,0 +1,130 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float64 f64_sqrt(float64 a, struct softfloat_status_t *status)
+{
+ bool signA;
+ int16_t expA;
+ uint64_t sigA;
+ struct exp16_sig64 normExpSig;
+ int16_t expZ;
+ uint32_t sig32A, recipSqrt32, sig32Z;
+ uint64_t rem;
+ uint32_t q;
+ uint64_t sigZ, shiftedSigZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ signA = signF64UI(a);
+ expA = expF64UI(a);
+ sigA = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FF) {
+ if (sigA) {
+ return softfloat_propagateNaNF64UI(a, 0, status);
+ }
+ if (! signA) return a;
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) {
+ sigA = 0;
+ a = packToF64UI(signA, 0, 0);
+ }
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (signA) {
+ if (! (expA | sigA)) return a;
+ goto invalid;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) return a;
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(sigA);
+ expA = normExpSig.exp;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ | (`sig32Z' is guaranteed to be a lower bound on the square root of
+ | `sig32A', which makes `sig32Z' also a lower bound on the square root of
+ | `sigA'.)
+ *------------------------------------------------------------------------*/
+ expZ = ((expA - 0x3FF)>>1) + 0x3FE;
+ expA &= 1;
+ sigA |= UINT64_C(0x0010000000000000);
+ sig32A = sigA>>21;
+ recipSqrt32 = softfloat_approxRecipSqrt32_1(expA, sig32A);
+ sig32Z = ((uint64_t) sig32A * recipSqrt32)>>32;
+ if (expA) {
+ sigA <<= 8;
+ sig32Z >>= 1;
+ } else {
+ sigA <<= 9;
+ }
+ rem = sigA - (uint64_t) sig32Z * sig32Z;
+ q = ((uint32_t) (rem>>2) * (uint64_t) recipSqrt32)>>32;
+ sigZ = ((uint64_t) sig32Z<<32 | 1<<5) + ((uint64_t) q<<3);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ((sigZ & 0x1FF) < 0x22) {
+ sigZ &= ~(uint64_t) 0x3F;
+ shiftedSigZ = sigZ>>6;
+ rem = (sigA<<52) - shiftedSigZ * shiftedSigZ;
+ if (rem & UINT64_C(0x8000000000000000)) {
+ --sigZ;
+ } else {
+ if (rem) sigZ |= 1;
+ }
+ }
+ return softfloat_roundPackToF64(0, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return defaultNaNF64UI;
+}
diff --git a/src/cpu/softfloat3e/f64_to_extF80.cc b/src/cpu/softfloat3e/f64_to_extF80.cc
new file mode 100644
index 000000000..88b27f9d3
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_extF80.cc
@@ -0,0 +1,88 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t f64_to_extF80(float64 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t frac;
+ struct commonNaN commonNaN;
+ struct uint128 uiZ;
+ uint16_t uiZ64;
+ uint64_t uiZ0;
+ struct exp16_sig64 normExpSig;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ frac = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FF) {
+ if (frac) {
+ softfloat_f64UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToExtF80UI(&commonNaN);
+ uiZ64 = uiZ.v64;
+ uiZ0 = uiZ.v0;
+ } else {
+ uiZ64 = packToExtF80UI64(sign, 0x7FFF);
+ uiZ0 = UINT64_C(0x8000000000000000);
+ }
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac) {
+ return packToExtF80(sign, 0, 0);
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(frac);
+ exp = normExpSig.exp;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ uiZ64 = packToExtF80UI64(sign, exp + 0x3C00);
+ uiZ0 = (frac | UINT64_C(0x0010000000000000))<<11;
+ return packToExtF80_twoargs(uiZ64, uiZ0);
+}
diff --git a/src/cpu/softfloat3e/f64_to_f128.cc b/src/cpu/softfloat3e/f64_to_f128.cc
new file mode 100644
index 000000000..cfae72824
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_f128.cc
@@ -0,0 +1,89 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float128_t f64_to_f128(float64 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t frac;
+ struct commonNaN commonNaN;
+ struct uint128 uiZ;
+ struct exp16_sig64 normExpSig;
+ struct uint128 frac128;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ frac = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FF) {
+ if (frac) {
+ softfloat_f64UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF128UI(&commonNaN);
+ } else {
+ uiZ.v64 = packToF128UI64(sign, 0x7FFF, 0);
+ uiZ.v0 = 0;
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! exp) {
+ if (! frac) {
+ uiZ.v64 = packToF128UI64(sign, 0, 0);
+ uiZ.v0 = 0;
+ return uiZ;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalF64Sig(frac);
+ exp = normExpSig.exp - 1;
+ frac = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ frac128 = softfloat_shortShiftLeft128(0, frac, 60);
+ uiZ.v64 = packToF128UI64(sign, exp + 0x3C00, frac128.v64);
+ uiZ.v0 = frac128.v0;
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/f64_to_f16.c b/src/cpu/softfloat3e/f64_to_f16.c
new file mode 100644
index 000000000..fe8dea057
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_f16.c
@@ -0,0 +1,83 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float16 f64_to_f16(float64 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t frac;
+ struct commonNaN commonNaN;
+ uint16_t uiZ, frac16;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ frac = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FF) {
+ if (frac) {
+ softfloat_f64UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF16UI(&commonNaN);
+ } else {
+ uiZ = packToF16UI(sign, 0x1F, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (!exp && frac) {
+ if (softfloat_denormalsAreZeros(status))
+ return packToF16UI(sign, 0, 0);
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ frac16 = softfloat_shortShiftRightJam64(frac, 38);
+ if (! (exp | frac16)) {
+ return packToF16UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ return softfloat_roundPackToF16(sign, exp - 0x3F1, frac16 | 0x4000, status);
+}
diff --git a/src/cpu/softfloat3e/f64_to_f32.c b/src/cpu/softfloat3e/f64_to_f32.c
new file mode 100644
index 000000000..7ebbf428f
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_f32.c
@@ -0,0 +1,83 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float32 f64_to_f32(float64 a, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t frac;
+ struct commonNaN commonNaN;
+ uint32_t uiZ, frac32;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ frac = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp == 0x7FF) {
+ if (frac) {
+ softfloat_f64UIToCommonNaN(a, &commonNaN, status);
+ uiZ = softfloat_commonNaNToF32UI(&commonNaN);
+ } else {
+ uiZ = packToF32UI(sign, 0xFF, 0);
+ }
+ return uiZ;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (!exp && frac) {
+ if (softfloat_denormalsAreZeros(status))
+ return packToF32UI(sign, 0, 0);
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ frac32 = softfloat_shortShiftRightJam64(frac, 22);
+ if (! (exp | frac32)) {
+ return packToF32UI(sign, 0, 0);
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ return softfloat_roundPackToF32(sign, exp - 0x381, frac32 | 0x40000000, status);
+}
diff --git a/src/cpu/softfloat3e/f64_to_i32.c b/src/cpu/softfloat3e/f64_to_i32.c
new file mode 100644
index 000000000..c296e0bd5
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_i32.c
@@ -0,0 +1,77 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f64_to_i32(float64 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow)
+ if ((exp == 0x7FF) && sig) {
+#if (i32_fromNaN == i32_fromPosOverflow)
+ sign = 0;
+#elif (i32_fromNaN == i32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return i32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= UINT64_C(0x0010000000000000);
+ else if (softfloat_denormalsAreZeros(status)) sig = 0;
+ shiftDist = 0x427 - exp;
+ if (0 < shiftDist) sig = softfloat_shiftRightJam64(sig, shiftDist);
+ return softfloat_roundToI32(sign, sig, roundingMode, exact, status);
+}
+
diff --git a/src/cpu/softfloat3e/f64_to_i32_r_minMag.c b/src/cpu/softfloat3e/f64_to_i32_r_minMag.c
new file mode 100644
index 000000000..80e2d6bc3
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_i32_r_minMag.c
@@ -0,0 +1,89 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int32_t f64_to_i32_r_minMag(float64 a, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+ bool sign;
+ int32_t absZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x433 - exp;
+ if (53 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ if (shiftDist < 22) {
+ if (sign && (exp == 0x41E) && (sig < UINT64_C(0x0000000000200000))) {
+ if (exact && sig) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return -0x7FFFFFFF - 1;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x7FF) && sig
+ ? i32_fromNaN
+ : sign ? i32_fromNegOverflow : i32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig |= UINT64_C(0x0010000000000000);
+ absZ = sig>>shiftDist;
+ if (exact && ((uint64_t) (uint32_t) absZ<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f64_to_i64(float64 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+ struct uint64_extra sigExtra;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= UINT64_C(0x0010000000000000);
+ else if (softfloat_denormalsAreZeros(status)) sig = 0;
+ shiftDist = 0x433 - exp;
+ if (shiftDist <= 0) {
+ if (shiftDist < -11) goto invalid;
+ sigExtra.v = sig<<-shiftDist;
+ sigExtra.extra = 0;
+ } else {
+ sigExtra = softfloat_shiftRightJam64Extra(sig, 0, shiftDist);
+ }
+ return softfloat_roundToI64(sign, sigExtra.v, sigExtra.extra, roundingMode, exact, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x7FF) && fracF64UI(a)
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+}
+
diff --git a/src/cpu/softfloat3e/f64_to_i64_r_minMag.c b/src/cpu/softfloat3e/f64_to_i64_r_minMag.c
new file mode 100644
index 000000000..eb633eb22
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_i64_r_minMag.c
@@ -0,0 +1,95 @@
+
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+int64_t f64_to_i64_r_minMag(float64 a, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+ uint64_t absZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x433 - exp;
+ if (shiftDist <= 0) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (shiftDist < -10) {
+ if (a == packToF64UI(1, 0x43E, 0)) {
+ return -INT64_C(0x7FFFFFFFFFFFFFFF) - 1;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x7FF) && sig
+ ? i64_fromNaN
+ : sign ? i64_fromNegOverflow : i64_fromPosOverflow;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig |= UINT64_C(0x0010000000000000);
+ absZ = sig<<-shiftDist;
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (53 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sig |= UINT64_C(0x0010000000000000);
+ absZ = sig>>shiftDist;
+ if (exact && (absZ<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f64_to_ui32(float64 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow)
+ if ((exp == 0x7FF) && sig) {
+#if (ui32_fromNaN == ui32_fromPosOverflow)
+ sign = 0;
+#elif (ui32_fromNaN == ui32_fromNegOverflow)
+ sign = 1;
+#else
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return ui32_fromNaN;
+#endif
+ }
+#endif
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= UINT64_C(0x0010000000000000);
+ else if (softfloat_denormalsAreZeros(status)) sig = 0;
+ shiftDist = 0x427 - exp;
+ if (0 < shiftDist) sig = softfloat_shiftRightJam64(sig, shiftDist);
+ return softfloat_roundToUI32(sign, sig, roundingMode, exact, status);
+}
diff --git a/src/cpu/softfloat3e/f64_to_ui32_r_minMag.c b/src/cpu/softfloat3e/f64_to_ui32_r_minMag.c
new file mode 100644
index 000000000..7610d7c37
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_ui32_r_minMag.c
@@ -0,0 +1,83 @@
+
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint32_t f64_to_ui32_r_minMag(float64 a, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+ bool sign;
+ uint32_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x433 - exp;
+ if (53 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ if (sign || (shiftDist < 21)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x7FF) && sig
+ ? ui32_fromNaN
+ : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sig |= UINT64_C(0x0010000000000000);
+ z = sig>>shiftDist;
+ if (exact && ((uint64_t) z<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f64_to_ui64(float64 a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
+{
+ bool sign;
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+ struct uint64_extra sigExtra;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (exp) sig |= UINT64_C(0x0010000000000000);
+ else if (softfloat_denormalsAreZeros(status)) sig = 0;
+ shiftDist = 0x433 - exp;
+ if (shiftDist <= 0) {
+ if (shiftDist < -11) goto invalid;
+ sigExtra.v = sig<<-shiftDist;
+ sigExtra.extra = 0;
+ } else {
+ sigExtra = softfloat_shiftRightJam64Extra(sig, 0, shiftDist);
+ }
+ return softfloat_roundToUI64(sign, sigExtra.v, sigExtra.extra, roundingMode, exact, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return (exp == 0x7FF) && fracF64UI(a)
+ ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+}
diff --git a/src/cpu/softfloat3e/f64_to_ui64_r_minMag.c b/src/cpu/softfloat3e/f64_to_ui64_r_minMag.c
new file mode 100644
index 000000000..e7bda4c67
--- /dev/null
+++ b/src/cpu/softfloat3e/f64_to_ui64_r_minMag.c
@@ -0,0 +1,87 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+uint64_t f64_to_ui64_r_minMag(float64 a, bool exact, struct softfloat_status_t *status)
+{
+ int16_t exp;
+ uint64_t sig;
+ int16_t shiftDist;
+ bool sign;
+ uint64_t z;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ exp = expF64UI(a);
+ sig = fracF64UI(a);
+ if (softfloat_denormalsAreZeros(status))
+ if (!exp && sig) sig = 0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftDist = 0x433 - exp;
+ if (53 <= shiftDist) {
+ if (exact && (exp | sig)) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ return 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ sign = signF64UI(a);
+ if (sign) goto invalid;
+ if (shiftDist <= 0) {
+ if (shiftDist < -11) goto invalid;
+ z = (sig | UINT64_C(0x0010000000000000))<<-shiftDist;
+ } else {
+ sig |= UINT64_C(0x0010000000000000);
+ z = sig>>shiftDist;
+ if (exact && (uint64_t) (sig<<(-shiftDist & 63))) {
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ }
+ }
+ return z;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ invalid:
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
+ return
+ (exp == 0x7FF) && sig ? ui64_fromNaN
+ : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow;
+}
diff --git a/src/cpu/softfloat/fpatan.cc b/src/cpu/softfloat3e/fpatan.cc
similarity index 59%
rename from src/cpu/softfloat/fpatan.cc
rename to src/cpu/softfloat3e/fpatan.cc
index f33a3ff66..207dc320a 100644
--- a/src/cpu/softfloat/fpatan.cc
+++ b/src/cpu/softfloat3e/fpatan.cc
@@ -25,27 +25,31 @@ these four paragraphs for those parts of this code that are retained.
#define FLOAT128
-#include "softfloatx80.h"
-#include "softfloat-round-pack.h"
+#include "config.h"
+#include "softfloat.h"
+#include "specialize.h"
+
+#include "fpu_trans.h"
#include "fpu_constant.h"
+#include "poly.h"
#define FPATAN_ARR_SIZE 11
-static const float128 float128_one =
+static const float128_t float128_one =
packFloat128(BX_CONST64(0x3fff000000000000), BX_CONST64(0x0000000000000000));
-static const float128 float128_sqrt3 =
+static const float128_t float128_sqrt3 =
packFloat128(BX_CONST64(0x3fffbb67ae8584ca), BX_CONST64(0xa73b25742d7078b8));
static const floatx80 floatx80_pi =
packFloatx80(0, 0x4000, BX_CONST64(0xc90fdaa22168c235));
-static const float128 float128_pi2 =
+static const float128_t float128_pi2 =
packFloat128(BX_CONST64(0x3fff921fb54442d1), BX_CONST64(0x8469898CC5170416));
-static const float128 float128_pi4 =
+static const float128_t float128_pi4 =
packFloat128(BX_CONST64(0x3ffe921fb54442d1), BX_CONST64(0x8469898CC5170416));
-static const float128 float128_pi6 =
+static const float128_t float128_pi6 =
packFloat128(BX_CONST64(0x3ffe0c152382d736), BX_CONST64(0x58465BB32E0F580F));
-static float128 atan_arr[FPATAN_ARR_SIZE] =
+static float128_t atan_arr[FPATAN_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
PACK_FLOAT_128(0xbffd555555555555, 0x5555555555555555), /* 3 */
@@ -60,10 +64,10 @@ static float128 atan_arr[FPATAN_ARR_SIZE] =
PACK_FLOAT_128(0x3ffa861861861861, 0x8618618618618618) /* 21 */
};
-extern float128 OddPoly(float128 x, float128 *arr, int n, struct float_status_t *status);
+extern float128_t OddPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status);
/* |x| < 1/4 */
-static float128 poly_atan(float128 x1, struct float_status_t *status)
+static float128_t poly_atan(float128_t x1, softfloat_status_t &status)
{
/*
// 3 5 7 9 11 13 15 17
@@ -86,12 +90,11 @@ static float128 poly_atan(float128 x1, struct float_status_t *status)
// atan(x) ~ x * [ p(x) + x * q(x) ]
//
*/
- return OddPoly(x1, atan_arr, FPATAN_ARR_SIZE, status);
+ return OddPoly(x1, (const float128_t*) atan_arr, FPATAN_ARR_SIZE, status);
}
// =================================================
-// FPATAN Compute y * log (x)
-// 2
+// FPATAN Compute arctan(y/x)
// =================================================
//
@@ -134,125 +137,129 @@ static float128 poly_atan(float128 x1, struct float_status_t *status)
// 3 5 7 9 2n+1
//
-floatx80 fpatan(floatx80 a, floatx80 b, struct float_status_t *status)
+floatx80 fpatan(floatx80 a, floatx80 b, softfloat_status_t &status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
+ const floatx80 floatx80_default_nan =
+ packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
// handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) {
- float_raise(status, float_flag_invalid);
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+ softfloat_raiseFlags(&status, softfloat_flag_invalid);
return floatx80_default_nan;
}
- Bit64u aSig = extractFloatx80Frac(a);
- Bit32s aExp = extractFloatx80Exp(a);
- int aSign = extractFloatx80Sign(a);
- Bit64u bSig = extractFloatx80Frac(b);
- Bit32s bExp = extractFloatx80Exp(b);
- int bSign = extractFloatx80Sign(b);
+ uint64_t aSig = extF80_fraction(a);
+ int32_t aExp = extF80_exp(a);
+ int aSign = extF80_sign(a);
+ uint64_t bSig = extF80_fraction(b);
+ int32_t bExp = extF80_exp(b);
+ int bSign = extF80_sign(b);
int zSign = aSign ^ bSign;
if (bExp == 0x7FFF)
{
- if ((Bit64u) (bSig<<1))
- return propagateFloatx80NaN(a, b, status);
+ if (bSig<<1)
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status);
if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1))
- return propagateFloatx80NaN(a, b, status);
+ if (aSig<<1)
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status);
- if (aSign) { /* return 3PI/4 */
- return roundAndPackFloatx80(80, bSign,
- FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, status);
- }
- else { /* return PI/4 */
- return roundAndPackFloatx80(80, bSign,
- FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
- }
+ if (aSign) /* return 3PI/4 */
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, 80, &status);
+ else /* return PI/4 */
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status);
}
- if (aSig && (aExp == 0))
- float_raise(status, float_flag_denormal);
+ if (aSig && ! aExp)
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
/* return PI/2 */
- return roundAndPackFloatx80(80, bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status);
}
if (aExp == 0x7FFF)
{
- if ((Bit64u) (aSig<<1))
- return propagateFloatx80NaN(a, b, status);
+ if (aSig<<1)
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status);
- if (bSig && (bExp == 0))
- float_raise(status, float_flag_denormal);
+ if (bSig && ! bExp)
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
return_PI_or_ZERO:
- if (aSign) { /* return PI */
- return roundAndPackFloatx80(80, bSign, FLOATX80_PI_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
- } else { /* return 0 */
- return packFloatx80(bSign, 0, 0);
- }
+ if (aSign) /* return PI */
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status);
+ else /* return 0 */
+ return packToExtF80(bSign, 0, 0);
}
- if (bExp == 0)
+ if (! bExp)
{
- if (bSig == 0) {
- if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
+ if (! bSig) {
+ if (aSig && ! aExp) softfloat_raiseFlags(&status, softfloat_flag_denormal);
goto return_PI_or_ZERO;
}
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(bSig);
+ bExp = normExpSig.exp + 1;
+ bSig = normExpSig.sig;
}
- if (aExp == 0)
+ if (! aExp)
{
- if (aSig == 0) /* return PI/2 */
- return roundAndPackFloatx80(80, bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
+ if (! aSig) /* return PI/2 */
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status);
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig);
+ aExp = normExpSig.exp + 1;
+ aSig = normExpSig.sig;
}
- float_raise(status, float_flag_inexact);
+ softfloat_raiseFlags(&status, softfloat_flag_inexact);
/* |a| = |b| ==> return PI/4 */
- if (aSig == bSig && aExp == bExp)
- return roundAndPackFloatx80(80, bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status);
+ if (aSig == bSig && aExp == bExp) {
+ if (aSign)
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, 80, &status);
+ else
+ return softfloat_roundPackToExtF80(bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status);
+ }
/* ******************************** */
/* using float128 for approximation */
/* ******************************** */
- float128 a128 = normalizeRoundAndPackFloat128(0, aExp-0x10, aSig, 0, status);
- float128 b128 = normalizeRoundAndPackFloat128(0, bExp-0x10, bSig, 0, status);
- float128 x;
+ float128_t a128 = softfloat_normRoundPackToF128(0, aExp-0x10, aSig, 0, &status);
+ float128_t b128 = softfloat_normRoundPackToF128(0, bExp-0x10, bSig, 0, &status);
+ float128_t x;
int swap = 0, add_pi6 = 0, add_pi4 = 0;
if (aExp > bExp || (aExp == bExp && aSig > bSig))
{
- x = float128_div(b128, a128, status);
+ x = f128_div(b128, a128, &status);
}
else {
- x = float128_div(a128, b128, status);
+ x = f128_div(a128, b128, &status);
swap = 1;
}
- Bit32s xExp = extractFloat128Exp(x);
+ int32_t xExp = expF128UI64(x.v64);
if (xExp <= FLOATX80_EXP_BIAS-40)
goto approximation_completed;
- if (x.hi >= BX_CONST64(0x3ffe800000000000)) // 3/4 < x < 1
+ if (x.v64 >= BX_CONST64(0x3ffe800000000000)) // 3/4 < x < 1
{
/*
arctan(x) = arctan((x-1)/(x+1)) + pi/4
*/
- float128 t1 = float128_sub(x, float128_one, status);
- float128 t2 = float128_add(x, float128_one, status);
- x = float128_div(t1, t2, status);
+ float128_t t1 = f128_sub(x, float128_one, &status);
+ float128_t t2 = f128_add(x, float128_one, &status);
+ x = f128_div(t1, t2, &status);
add_pi4 = 1;
}
else
@@ -263,26 +270,26 @@ return_PI_or_ZERO:
/*
arctan(x) = arctan((x*sqrt(3)-1)/(x+sqrt(3))) + pi/6
*/
- float128 t1 = float128_mul(x, float128_sqrt3, status);
- float128 t2 = float128_add(x, float128_sqrt3, status);
- x = float128_sub(t1, float128_one, status);
- x = float128_div(x, t2, status);
+ float128_t t1 = f128_mul(x, float128_sqrt3, &status);
+ float128_t t2 = f128_add(x, float128_sqrt3, &status);
+ x = f128_sub(t1, float128_one, &status);
+ x = f128_div(x, t2, &status);
add_pi6 = 1;
}
}
x = poly_atan(x, status);
- if (add_pi6) x = float128_add(x, float128_pi6, status);
- if (add_pi4) x = float128_add(x, float128_pi4, status);
+ if (add_pi6) x = f128_add(x, float128_pi6, &status);
+ if (add_pi4) x = f128_add(x, float128_pi4, &status);
approximation_completed:
- if (swap) x = float128_sub(float128_pi2, x, status);
- floatx80 result = float128_to_floatx80(x, status);
+ if (swap) x = f128_sub(float128_pi2, x, &status);
+ floatx80 result = f128_to_extF80(x, &status);
if (zSign) floatx80_chs(result);
- int rSign = extractFloatx80Sign(result);
+ int rSign = extF80_sign(result);
if (!bSign && rSign)
- return floatx80_add(result, floatx80_pi, status);
+ return extF80_add(result, floatx80_pi, &status);
if (bSign && !rSign)
- return floatx80_sub(result, floatx80_pi, status);
+ return extF80_sub(result, floatx80_pi, &status);
return result;
}
diff --git a/src/cpu/softfloat/fprem.cc b/src/cpu/softfloat3e/fprem.cc
similarity index 53%
rename from src/cpu/softfloat/fprem.cc
rename to src/cpu/softfloat3e/fprem.cc
index 26637c5c5..2252f1230 100644
--- a/src/cpu/softfloat/fprem.cc
+++ b/src/cpu/softfloat3e/fprem.cc
@@ -23,100 +23,109 @@ these four paragraphs for those parts of this code that are retained.
* Stanislav Shwartsman [sshwarts at sourceforge net]
* ==========================================================================*/
-#include "softfloatx80.h"
-#include "softfloat-round-pack.h"
+#include "fpu_trans.h"
#define USE_estimateDiv128To64
-#include "softfloat-macros.h"
+#include "softfloat-helpers.h"
+
+#include "specialize.h" // for softfloat_propagateNaNExtF80UI
/* executes single exponent reduction cycle */
-static Bit64u remainder_kernel(Bit64u aSig0, Bit64u bSig, int expDiff, Bit64u *zSig0, Bit64u *zSig1)
+static uint64_t remainder_kernel(uint64_t aSig0, uint64_t bSig, int expDiff, uint64_t *zSig0, uint64_t *zSig1)
{
- Bit64u term0, term1;
- Bit64u aSig1 = 0;
-
+ uint128 term, z;
+ uint64_t aSig1 = 0;
shortShift128Left(aSig1, aSig0, expDiff, &aSig1, &aSig0);
- Bit64u q = estimateDiv128To64(aSig1, aSig0, bSig);
- mul64To128(bSig, q, &term0, &term1);
- sub128(aSig1, aSig0, term0, term1, zSig1, zSig0);
- while ((Bit64s)(*zSig1) < 0) {
+ uint64_t q = estimateDiv128To64(aSig1, aSig0, bSig);
+ term = softfloat_mul64To128(bSig, q);
+ z = softfloat_sub128(aSig1, aSig0, term.v64, term.v0);
+ while ((int64_t) z.v64 < 0) {
--q;
- add128(*zSig1, *zSig0, 0, bSig, zSig1, zSig0);
+ z = softfloat_add128(z.v64, z.v0, 0, bSig);
}
+ *zSig0 = z.v0;
+ *zSig1 = z.v64;
return q;
}
-static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, int rounding_mode, struct float_status_t *status)
+static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, int rounding_mode, struct softfloat_status_t *status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
+ static const floatx80 floatx80_default_nan =
+ packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
- Bit32s aExp, bExp, zExp, expDiff;
- Bit64u aSig0, aSig1, bSig;
+ int32_t aExp, bExp, zExp, expDiff;
+ uint64_t aSig0, aSig1 = 0, bSig;
int aSign;
+ struct exp32_sig64 normExpSig;
+ uint128 term;
+
*q = 0;
// handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
- {
- float_raise(status, float_flag_invalid);
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
*r = floatx80_default_nan;
return -1;
}
- aSig0 = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- aSign = extractFloatx80Sign(a);
- bSig = extractFloatx80Frac(b);
- bExp = extractFloatx80Exp(b);
+ aSig0 = extF80_fraction(a);
+ aExp = extF80_exp(a);
+ aSign = extF80_sign(a);
+ bSig = extF80_fraction(b);
+ bExp = extF80_exp(b);
if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig0<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1))) {
- *r = propagateFloatx80NaN(a, b, status);
+ if ((aSig0<<1) || ((bExp == 0x7FFF) && (bSig<<1))) {
+ *r = softfloat_propagateNaNExtF80UI(a.signExp, a.signif, b.signExp, b.signif, status);
return -1;
}
- float_raise(status, float_flag_invalid);
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
*r = floatx80_default_nan;
return -1;
}
if (bExp == 0x7FFF) {
- if ((Bit64u) (bSig<<1)) {
- *r = propagateFloatx80NaN(a, b, status);
+ if (bSig << 1) {
+ *r = softfloat_propagateNaNExtF80UI(a.signExp, a.signif, b.signExp, b.signif, status);
return -1;
}
- if (aExp == 0 && aSig0) {
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
- *r = (a.fraction & BX_CONST64(0x8000000000000000)) ?
- packFloatx80(aSign, aExp, aSig0) : a;
+ if (! aExp && aSig0) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(aSig0);
+ aExp = normExpSig.exp + 1;
+ aSig0 = normExpSig.sig;
+ *r = (a.signif & BX_CONST64(0x8000000000000000)) ? packToExtF80(aSign, aExp, aSig0) : a;
return 0;
}
*r = a;
return 0;
}
- if (bExp == 0) {
- if (bSig == 0) {
- float_raise(status, float_flag_invalid);
+ if (! bExp) {
+ if (! bSig) {
+ softfloat_raiseFlags(status, softfloat_flag_invalid);
*r = floatx80_default_nan;
return -1;
}
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(bSig);
+ bExp = normExpSig.exp + 1;
+ bSig = normExpSig.sig;
}
- if (aExp == 0) {
- if (aSig0 == 0) {
+ if (! aExp) {
+ if (! aSig0) {
*r = a;
return 0;
}
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(aSig0);
+ aExp = normExpSig.exp + 1;
+ aSig0 = normExpSig.sig;
}
- expDiff = aExp - bExp;
- aSig1 = 0;
- Bit32u overflow = 0;
+ expDiff = aExp - bExp;
+ int overflow = 0;
if (expDiff >= 64) {
int n = (expDiff & 0x1f) | 0x20;
@@ -129,11 +138,10 @@ static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, int rounding
if (expDiff < 0) {
if (expDiff < -1) {
- *r = (a.fraction & BX_CONST64(0x8000000000000000)) ?
- packFloatx80(aSign, aExp, aSig0) : a;
+ *r = (a.signif & BX_CONST64(0x8000000000000000)) ? packToExtF80(aSign, aExp, aSig0) : a;
return 0;
}
- shift128Right(aSig0, 0, 1, &aSig0, &aSig1);
+ shortShift128Right(aSig0, 0, 1, &aSig0, &aSig1);
expDiff = 0;
}
@@ -147,26 +155,28 @@ static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, int rounding
}
}
- if (rounding_mode == float_round_nearest_even)
- {
- Bit64u term0, term1;
- shift128Right(bSig, 0, 1, &term0, &term1);
+ if (rounding_mode == softfloat_round_near_even) {
+ uint64_t term0, term1;
+ shortShift128Right(bSig, 0, 1, &term0, &term1);
- if (! lt128(aSig0, aSig1, term0, term1))
- {
- int lt = lt128(term0, term1, aSig0, aSig1);
- int eq = eq128(aSig0, aSig1, term0, term1);
+ if (! softfloat_lt128(aSig0, aSig1, term0, term1)) {
+ int lt = softfloat_lt128(term0, term1, aSig0, aSig1);
+ int eq = softfloat_eq128(aSig0, aSig1, term0, term1);
- if ((eq && ((*q) & 1)) || lt) {
- aSign = !aSign;
- ++(*q);
- }
- if (lt) sub128(bSig, 0, aSig0, aSig1, &aSig0, &aSig1);
+ if ((eq && ((*q) & 1)) || lt) {
+ aSign = !aSign;
+ ++(*q);
+ }
+ if (lt) {
+ term = softfloat_sub128(bSig, 0, aSig0, aSig1);
+ aSig0 = term.v64;
+ aSig1 = term.v0;
+ }
}
}
}
- *r = normalizeRoundAndPackFloatx80(80, aSign, zExp, aSig0, aSig1, status);
+ *r = softfloat_normRoundPackToExtF80(aSign, zExp, aSig0, aSig1, 80, status);
return overflow;
}
@@ -176,9 +186,9 @@ static int do_fprem(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, int rounding
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
-int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, struct float_status_t *status)
+int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, struct softfloat_status_t *status)
{
- return do_fprem(a, b, r, q, float_round_nearest_even, status);
+ return do_fprem(a, b, r, q, softfloat_round_near_even, status);
}
/*----------------------------------------------------------------------------
@@ -190,7 +200,7 @@ int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, s
| quotient of 'a' divided by 'b' to an integer.
*----------------------------------------------------------------------------*/
-int floatx80_remainder(floatx80 a, floatx80 b, floatx80 *r, Bit64u *q, struct float_status_t *status)
+int floatx80_remainder(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, struct softfloat_status_t *status)
{
- return do_fprem(a, b, r, q, float_round_to_zero, status);
+ return do_fprem(a, b, r, q, softfloat_round_to_zero, status);
}
diff --git a/src/cpu/softfloat/fpu_constant.h b/src/cpu/softfloat3e/fpu_constant.h
similarity index 98%
rename from src/cpu/softfloat/fpu_constant.h
rename to src/cpu/softfloat3e/fpu_constant.h
index 7a7fc6f1a..d7d44ee3c 100644
--- a/src/cpu/softfloat/fpu_constant.h
+++ b/src/cpu/softfloat3e/fpu_constant.h
@@ -24,7 +24,7 @@ these four paragraphs for those parts of this code that are retained.
#include "config.h"
// Pentium CPU uses only 68-bit precision M_PI approximation
-//#define BETTER_THAN_PENTIUM
+// #define BETTER_THAN_PENTIUM
/*============================================================================
* Written for Bochs (x86 achitecture simulator) by
diff --git a/src/cpu/softfloat3e/fpu_trans.h b/src/cpu/softfloat3e/fpu_trans.h
new file mode 100644
index 000000000..bd3d3cecb
--- /dev/null
+++ b/src/cpu/softfloat3e/fpu_trans.h
@@ -0,0 +1,117 @@
+/////////////////////////////////////////////////////////////////////////
+// $Id$
+/////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2003-2018 Stanislav Shwartsman
+// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+/////////////////////////////////////////////////////////////////////////
+
+#ifndef _FPU_TRANS_H_
+#define _FPU_TRANS_H_
+
+#include "softfloat.h"
+#include "softfloat-specialize.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision operations.
+*----------------------------------------------------------------------------*/
+
+int floatx80_remainder(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, struct softfloat_status_t *status);
+int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 *r, uint64_t *q, struct softfloat_status_t *status);
+
+floatx80 f2xm1(floatx80 a, struct softfloat_status_t *status);
+#ifdef __cplusplus
+floatx80 fyl2x(floatx80 a, floatx80 b, softfloat_status_t &status);
+floatx80 fyl2xp1(floatx80 a, floatx80 b, softfloat_status_t &status);
+floatx80 fpatan(floatx80 a, floatx80 b, softfloat_status_t &status);
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision trigonometric functions.
+*----------------------------------------------------------------------------*/
+
+int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, softfloat_status_t &status);
+int fsin(floatx80 &a, softfloat_status_t &status);
+int fcos(floatx80 &a, softfloat_status_t &status);
+int ftan(floatx80 &a, softfloat_status_t &status);
+#else
+floatx80 fyl2x(floatx80 a, floatx80 b, struct softfloat_status_t *status);
+floatx80 fyl2xp1(floatx80 a, floatx80 b, struct softfloat_status_t *status);
+floatx80 fpatan(floatx80 a, floatx80 b, struct softfloat_status_t *status);
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision trigonometric functions.
+*----------------------------------------------------------------------------*/
+
+int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct softfloat_status_t *status);
+int fsin(floatx80 *a, struct softfloat_status_t *status);
+int fcos(floatx80 *a, struct softfloat_status_t *status);
+int ftan(floatx80 *a, struct softfloat_status_t *status);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/*-----------------------------------------------------------------------------
+| Calculates the absolute value of the extended double-precision floating-point
+| value `a'. The operation is performed according to the IEC/IEEE Standard
+| for Binary Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+static __inline floatx80 &floatx80_abs(floatx80 ®)
+#else
+static __inline floatx80 floatx80_abs(floatx80 reg)
+#endif
+{
+ reg.signExp &= 0x7FFF;
+ return reg;
+}
+
+/*-----------------------------------------------------------------------------
+| Changes the sign of the extended double-precision floating-point value 'a'.
+| The operation is performed according to the IEC/IEEE Standard for Binary
+| Floating-Point Arithmetic.
+*----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+static __inline floatx80 &floatx80_chs(floatx80 ®)
+#else
+static __inline floatx80 floatx80_chs(floatx80 reg)
+#endif
+{
+ reg.signExp ^= 0x8000;
+ return reg;
+}
+
+#ifdef __cplusplus
+static __inline floatx80 FPU_round_const(const floatx80 &a, int adj)
+#else
+static __inline floatx80 FPU_round_const(const floatx80 a, int adj)
+#endif
+{
+ floatx80 result = a;
+ result.signif += adj;
+ return result;
+}
+
+#endif
diff --git a/src/cpu/softfloat/fsincos.cc b/src/cpu/softfloat3e/fsincos.cc
similarity index 68%
rename from src/cpu/softfloat/fsincos.cc
rename to src/cpu/softfloat3e/fsincos.cc
index f5b33a823..1a2a018de 100644
--- a/src/cpu/softfloat/fsincos.cc
+++ b/src/cpu/softfloat3e/fsincos.cc
@@ -26,24 +26,29 @@ these four paragraphs for those parts of this code that are retained.
#define FLOAT128
#define USE_estimateDiv128To64
-#include "softfloatx80.h"
-#include "softfloat-round-pack.h"
+#include "config.h"
+#include "specialize.h"
+
+#include "fpu_trans.h"
+#include "softfloat-helpers.h"
#include "fpu_constant.h"
+#include "poly.h"
+
static const floatx80 floatx80_one = packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000));
/* reduce trigonometric function argument using 128-bit precision
M_PI approximation */
-static Bit64u argument_reduction_kernel(Bit64u aSig0, int Exp, Bit64u *zSig0, Bit64u *zSig1)
+static uint64_t argument_reduction_kernel(uint64_t aSig0, int Exp, uint64_t *zSig0, uint64_t *zSig1)
{
- Bit64u term0, term1, term2;
- Bit64u aSig1 = 0;
+ uint64_t term0, term1, term2;
+ uint64_t aSig1 = 0;
shortShift128Left(aSig1, aSig0, Exp, &aSig1, &aSig0);
- Bit64u q = estimateDiv128To64(aSig1, aSig0, FLOAT_PI_HI);
+ uint64_t q = estimateDiv128To64(aSig1, aSig0, FLOAT_PI_HI);
mul128By64To192(FLOAT_PI_HI, FLOAT_PI_LO, q, &term0, &term1, &term2);
sub128(aSig1, aSig0, term0, term1, zSig1, zSig0);
- while ((Bit64s)(*zSig1) < 0) {
+ while ((int64_t)(*zSig1) < 0) {
--q;
add192(*zSig1, *zSig0, term2, 0, FLOAT_PI_HI, FLOAT_PI_LO, zSig1, zSig0, &term2);
}
@@ -51,35 +56,35 @@ static Bit64u argument_reduction_kernel(Bit64u aSig0, int Exp, Bit64u *zSig0, Bi
return q;
}
-static int reduce_trig_arg(int expDiff, int *zSign, Bit64u *aSig0, Bit64u *aSig1)
+static int reduce_trig_arg(int expDiff, int &zSign, uint64_t &aSig0, uint64_t &aSig1)
{
- Bit64u term0, term1, q = 0;
+ uint64_t term0, term1, q = 0;
if (expDiff < 0) {
- shift128Right(*aSig0, 0, 1, aSig0, aSig1);
+ shortShift128Right(aSig0, 0, 1, &aSig0, &aSig1);
expDiff = 0;
}
if (expDiff > 0) {
- q = argument_reduction_kernel(*aSig0, expDiff, aSig0, aSig1);
+ q = argument_reduction_kernel(aSig0, expDiff, &aSig0, &aSig1);
}
else {
- if (FLOAT_PI_HI <= *aSig0) {
- *aSig0 -= FLOAT_PI_HI;
+ if (FLOAT_PI_HI <= aSig0) {
+ aSig0 -= FLOAT_PI_HI;
q = 1;
}
}
- shift128Right(FLOAT_PI_HI, FLOAT_PI_LO, 1, &term0, &term1);
- if (! lt128(*aSig0, *aSig1, term0, term1))
+ shortShift128Right(FLOAT_PI_HI, FLOAT_PI_LO, 1, &term0, &term1);
+ if (! softfloat_lt128(aSig0, aSig1, term0, term1))
{
- int lt = lt128(term0, term1, *aSig0, *aSig1);
- int eq = eq128(*aSig0, *aSig1, term0, term1);
+ int lt = softfloat_lt128(term0, term1, aSig0, aSig1);
+ int eq = softfloat_eq128(aSig0, aSig1, term0, term1);
if ((eq && (q & 1)) || lt) {
- *zSign = !(*zSign);
+ zSign = !zSign;
++q;
}
- if (lt) sub128(FLOAT_PI_HI, FLOAT_PI_LO, *aSig0, *aSig1, aSig0, aSig1);
+ if (lt) sub128(FLOAT_PI_HI, FLOAT_PI_LO, aSig0, aSig1, &aSig0, &aSig1);
}
return (int)(q & 3);
@@ -88,7 +93,7 @@ static int reduce_trig_arg(int expDiff, int *zSign, Bit64u *aSig0, Bit64u *aSig1
#define SIN_ARR_SIZE 11
#define COS_ARR_SIZE 11
-static float128 sin_arr[SIN_ARR_SIZE] =
+static float128_t sin_arr[SIN_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
PACK_FLOAT_128(0xbffc555555555555, 0x5555555555555555), /* 3 */
@@ -103,7 +108,7 @@ static float128 sin_arr[SIN_ARR_SIZE] =
PACK_FLOAT_128(0x3fbd71b8ef6dcf57, 0x18bef146fcee6e45) /* 21 */
};
-static float128 cos_arr[COS_ARR_SIZE] =
+static float128_t cos_arr[COS_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 0 */
PACK_FLOAT_128(0xbffe000000000000, 0x0000000000000000), /* 2 */
@@ -118,10 +123,8 @@ static float128 cos_arr[COS_ARR_SIZE] =
PACK_FLOAT_128(0x3fc1e542ba402022, 0x507a9cad2bf8f0bb) /* 20 */
};
-extern float128 OddPoly (float128 x, float128 *arr, int n, struct float_status_t *status);
-
/* 0 <= x <= pi/4 */
-BX_CPP_INLINE float128 poly_sin(float128 x, struct float_status_t *status)
+static __inline float128_t poly_sin(float128_t x, softfloat_status_t &status)
{
// 3 5 7 9 11 13 15
// x x x x x x x
@@ -143,13 +146,11 @@ BX_CPP_INLINE float128 poly_sin(float128 x, struct float_status_t *status)
// sin(x) ~ x * [ p(x) + x * q(x) ]
//
- return OddPoly(x, sin_arr, SIN_ARR_SIZE, status);
+ return OddPoly(x, (const float128_t*) sin_arr, SIN_ARR_SIZE, status);
}
-extern float128 EvenPoly(float128 x, float128 *arr, int n, struct float_status_t *status);
-
/* 0 <= x <= pi/4 */
-BX_CPP_INLINE float128 poly_cos(float128 x, struct float_status_t *status)
+static __inline float128_t poly_cos(float128_t x, softfloat_status_t &status)
{
// 2 4 6 8 10 12 14
// x x x x x x x
@@ -166,22 +167,22 @@ BX_CPP_INLINE float128 poly_cos(float128 x, struct float_status_t *status)
// cos(x) ~ [ p(x) + x * q(x) ]
//
- return EvenPoly(x, cos_arr, COS_ARR_SIZE, status);
+ return EvenPoly(x, (const float128_t*) cos_arr, COS_ARR_SIZE, status);
}
-BX_CPP_INLINE void sincos_invalid(floatx80 *sin_a, floatx80 *cos_a, floatx80 a)
+static __inline void sincos_invalid(floatx80 *sin_a, floatx80 *cos_a, floatx80 a)
{
if (sin_a) *sin_a = a;
if (cos_a) *cos_a = a;
}
-BX_CPP_INLINE void sincos_tiny_argument(floatx80 *sin_a, floatx80 *cos_a, floatx80 a)
+static __inline void sincos_tiny_argument(floatx80 *sin_a, floatx80 *cos_a, floatx80 a)
{
if (sin_a) *sin_a = a;
if (cos_a) *cos_a = floatx80_one;
}
-static floatx80 sincos_approximation(int neg, float128 r, Bit64u quotient, struct float_status_t *status)
+static floatx80 sincos_approximation(int neg, float128_t r, uint64_t quotient, softfloat_status_t &status)
{
if (quotient & 0x1) {
r = poly_cos(r, status);
@@ -190,7 +191,7 @@ static floatx80 sincos_approximation(int neg, float128 r, Bit64u quotient, struc
r = poly_sin(r, status);
}
- floatx80 result = float128_to_floatx80(r, status);
+ floatx80 result = f128_to_extF80(r, &status);
if (quotient & 0x2)
neg = ! neg;
@@ -220,59 +221,62 @@ static floatx80 sincos_approximation(int neg, float128 r, Bit64u quotient, struc
// sin(x+2pi) = sin(x)
//
-int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t *status)
+int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, softfloat_status_t &status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
+ const floatx80 floatx80_default_nan =
+ packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
- Bit64u aSig0, aSig1 = 0;
- Bit32s aExp, zExp, expDiff;
+ uint64_t aSig0, aSig1 = 0;
+ int32_t aExp, zExp, expDiff;
int aSign, zSign;
int q = 0;
// handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a)) {
+ if (extF80_isUnsupported(a)) {
goto invalid;
}
- aSig0 = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- aSign = extractFloatx80Sign(a);
+ aSig0 = extF80_fraction(a);
+ aExp = extF80_exp(a);
+ aSign = extF80_sign(a);
/* invalid argument */
if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig0<<1)) {
- sincos_invalid(sin_a, cos_a, propagateFloatx80NaNOne(a, status));
+ if (aSig0 << 1) {
+ sincos_invalid(sin_a, cos_a, softfloat_propagateNaNExtF80UI(a.signExp, aSig0, 0, 0, &status));
return 0;
}
invalid:
- float_raise(status, float_flag_invalid);
+ softfloat_raiseFlags(&status, softfloat_flag_invalid);
sincos_invalid(sin_a, cos_a, floatx80_default_nan);
return 0;
}
- if (aExp == 0) {
- if (aSig0 == 0) {
+ if (! aExp) {
+ if (! aSig0) {
sincos_tiny_argument(sin_a, cos_a, a);
return 0;
}
- float_raise(status, float_flag_denormal);
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
/* handle pseudo denormals */
if (! (aSig0 & BX_CONST64(0x8000000000000000)))
{
- float_raise(status, float_flag_inexact);
+ softfloat_raiseFlags(&status, softfloat_flag_inexact);
if (sin_a)
- float_raise(status, float_flag_underflow);
+ softfloat_raiseFlags(&status, softfloat_flag_underflow);
sincos_tiny_argument(sin_a, cos_a, a);
return 0;
}
- normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig0);
+ aExp = normExpSig.exp + 1;
+ aSig0 = normExpSig.sig;
}
zSign = aSign;
@@ -283,7 +287,7 @@ int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t
if (expDiff >= 63)
return -1;
- float_raise(status, float_flag_inexact);
+ softfloat_raiseFlags(&status, softfloat_flag_inexact);
if (expDiff < -1) { // doesn't require reduction
if (expDiff <= -68) {
@@ -294,7 +298,7 @@ int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t
zExp = aExp;
}
else {
- q = reduce_trig_arg(expDiff, &zSign, &aSig0, &aSig1);
+ q = reduce_trig_arg(expDiff, zSign, aSig0, aSig1);
}
/* **************************** */
@@ -302,7 +306,7 @@ int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t
/* **************************** */
/* using float128 for approximation */
- float128 r = normalizeRoundAndPackFloat128(0, zExp-0x10, aSig0, aSig1, status);
+ float128_t r = softfloat_normRoundPackToF128(0, zExp-0x10, aSig0, aSig1, &status);
if (aSign) q = -q;
if (sin_a) *sin_a = sincos_approximation(zSign, r, q, status);
@@ -311,14 +315,14 @@ int fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a, struct float_status_t
return 0;
}
-int fsin(floatx80 *a, struct float_status_t *status)
+int fsin(floatx80 &a, softfloat_status_t &status)
{
- return fsincos(*a, a, 0, status);
+ return fsincos(a, &a, 0, status);
}
-int fcos(floatx80 *a, struct float_status_t *status)
+int fcos(floatx80 &a, softfloat_status_t &status)
{
- return fsincos(*a, 0, a, status);
+ return fsincos(a, 0, &a, status);
}
// =================================================
@@ -348,51 +352,55 @@ int fcos(floatx80 *a, struct float_status_t *status)
// cos(x)
//
-int ftan(floatx80 *a, struct float_status_t *status)
+int ftan(floatx80 &a, softfloat_status_t &status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
- const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
+ const floatx80 floatx80_default_nan =
+ packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
- Bit64u aSig0, aSig1 = 0;
- Bit32s aExp, zExp, expDiff;
+ uint64_t aSig0, aSig1 = 0;
+ int32_t aExp, zExp, expDiff;
int aSign, zSign;
int q = 0;
// handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(*a)) {
+ if (extF80_isUnsupported(a)) {
goto invalid;
}
- aSig0 = extractFloatx80Frac(*a);
- aExp = extractFloatx80Exp(*a);
- aSign = extractFloatx80Sign(*a);
+ aSig0 = extF80_fraction(a);
+ aExp = extF80_exp(a);
+ aSign = extF80_sign(a);
/* invalid argument */
if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig0<<1))
+ if (aSig0 << 1)
{
- *a = propagateFloatx80NaNOne(*a, status);
+ a = softfloat_propagateNaNExtF80UI(a.signExp, aSig0, 0, 0, &status);
return 0;
}
invalid:
- float_raise(status, float_flag_invalid);
- *a = floatx80_default_nan;
+ softfloat_raiseFlags(&status, softfloat_flag_invalid);
+ a = floatx80_default_nan;
return 0;
}
- if (aExp == 0) {
- if (aSig0 == 0) return 0;
- float_raise(status, float_flag_denormal);
+ if (! aExp) {
+ if (! aSig0) return 0;
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
/* handle pseudo denormals */
if (! (aSig0 & BX_CONST64(0x8000000000000000)))
{
- float_raise(status, float_flag_inexact | float_flag_underflow);
+ softfloat_raiseFlags(&status, softfloat_flag_inexact | softfloat_flag_underflow);
return 0;
}
- normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
+
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig0);
+ aExp = normExpSig.exp + 1;
+ aSig0 = normExpSig.sig;
}
zSign = aSign;
@@ -403,17 +411,17 @@ int ftan(floatx80 *a, struct float_status_t *status)
if (expDiff >= 63)
return -1;
- float_raise(status, float_flag_inexact);
+ softfloat_raiseFlags(&status, softfloat_flag_inexact);
if (expDiff < -1) { // doesn't require reduction
if (expDiff <= -68) {
- *a = packFloatx80(aSign, aExp, aSig0);
+ a = packFloatx80(aSign, aExp, aSig0);
return 0;
}
zExp = aExp;
}
else {
- q = reduce_trig_arg(expDiff, &zSign, &aSig0, &aSig1);
+ q = reduce_trig_arg(expDiff, zSign, aSig0, aSig1);
}
/* **************************** */
@@ -421,21 +429,21 @@ int ftan(floatx80 *a, struct float_status_t *status)
/* **************************** */
/* using float128 for approximation */
- float128 r = normalizeRoundAndPackFloat128(0, zExp-0x10, aSig0, aSig1, status);
+ float128_t r = softfloat_normRoundPackToF128(0, zExp-0x10, aSig0, aSig1, &status);
- float128 sin_r = poly_sin(r, status);
- float128 cos_r = poly_cos(r, status);
+ float128_t sin_r = poly_sin(r, status);
+ float128_t cos_r = poly_cos(r, status);
if (q & 0x1) {
- r = float128_div(cos_r, sin_r, status);
+ r = f128_div(cos_r, sin_r, &status);
zSign = ! zSign;
} else {
- r = float128_div(sin_r, cos_r, status);
+ r = f128_div(sin_r, cos_r, &status);
}
- *a = float128_to_floatx80(r, status);
+ a = f128_to_extF80(r, &status);
if (zSign)
- floatx80_chs(*a);
+ floatx80_chs(a);
return 0;
}
diff --git a/src/cpu/softfloat/fyl2x.cc b/src/cpu/softfloat3e/fyl2x.cc
similarity index 61%
rename from src/cpu/softfloat/fyl2x.cc
rename to src/cpu/softfloat3e/fyl2x.cc
index 875f866a9..7c90e6207 100644
--- a/src/cpu/softfloat/fyl2x.cc
+++ b/src/cpu/softfloat3e/fyl2x.cc
@@ -24,29 +24,28 @@ these four paragraphs for those parts of this code that are retained.
* ==========================================================================*/
#define FLOAT128
-
-#include "softfloatx80.h"
-#include "softfloat-round-pack.h"
+#include "config.h"
+#include "fpu_trans.h"
+#include "specialize.h"
+#include "softfloat-helpers.h"
#include "fpu_constant.h"
+#include "poly.h"
-static const floatx80 floatx80_one =
- packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000));
+static const floatx80 floatx80_one = packFloatx80(0, 0x3fff, BX_CONST64(0x8000000000000000));
-static const float128 float128_one =
+static const float128_t float128_one =
packFloat128(BX_CONST64(0x3fff000000000000), BX_CONST64(0x0000000000000000));
-static const float128 float128_two =
+static const float128_t float128_two =
packFloat128(BX_CONST64(0x4000000000000000), BX_CONST64(0x0000000000000000));
-static const float128 float128_ln2inv2 =
+static const float128_t float128_ln2inv2 =
packFloat128(BX_CONST64(0x400071547652b82f), BX_CONST64(0xe1777d0ffda0d23a));
#define SQRT2_HALF_SIG BX_CONST64(0xb504f333f9de6484)
-extern float128 OddPoly(float128 x, float128 *arr, int n, struct float_status_t *status);
-
#define L2_ARR_SIZE 9
-static float128 ln_arr[L2_ARR_SIZE] =
+static float128_t ln_arr[L2_ARR_SIZE] =
{
PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */
PACK_FLOAT_128(0x3ffd555555555555, 0x5555555555555555), /* 3 */
@@ -59,7 +58,7 @@ static float128 ln_arr[L2_ARR_SIZE] =
PACK_FLOAT_128(0x3ffae1e1e1e1e1e1, 0xe1e1e1e1e1e1e1e2) /* 17 */
};
-static float128 poly_ln(float128 x1, struct float_status_t *status)
+static float128_t poly_ln(float128_t x1, softfloat_status_t &status)
{
/*
//
@@ -84,28 +83,28 @@ static float128 poly_ln(float128 x1, struct float_status_t *status)
// 1-u
//
*/
- return OddPoly(x1, ln_arr, L2_ARR_SIZE, status);
+ return OddPoly(x1, (const float128_t*) ln_arr, L2_ARR_SIZE, status);
}
/* required sqrt(2)/2 < x < sqrt(2) */
-static float128 poly_l2(float128 x, struct float_status_t *status)
+static float128_t poly_l2(float128_t x, softfloat_status_t &status)
{
/* using float128 for approximation */
- float128 x_p1 = float128_add(x, float128_one, status);
- float128 x_m1 = float128_sub(x, float128_one, status);
- x = float128_div(x_m1, x_p1, status);
+ float128_t x_p1 = f128_add(x, float128_one, &status);
+ float128_t x_m1 = f128_sub(x, float128_one, &status);
+ x = f128_div(x_m1, x_p1, &status);
x = poly_ln(x, status);
- x = float128_mul(x, float128_ln2inv2, status);
+ x = f128_mul(x, float128_ln2inv2, &status);
return x;
}
-static float128 poly_l2p1(float128 x, struct float_status_t *status)
+static float128_t poly_l2p1(float128_t x, softfloat_status_t &status)
{
/* using float128 for approximation */
- float128 x_p2 = float128_add(x, float128_two, status);
- x = float128_div(x, x_p2, status);
+ float128_t x_plus2 = f128_add(x, float128_two, &status);
+ x = f128_div(x, x_plus2, &status);
x = poly_ln(x, status);
- x = float128_mul(x, float128_ln2inv2, status);
+ x = f128_mul(x, float128_ln2inv2, &status);
return x;
}
@@ -134,7 +133,7 @@ static float128 poly_l2p1(float128 x, struct float_status_t *status)
// 1-u 3 5 7 2n+1
//
-floatx80 fyl2x(floatx80 a, floatx80 b, struct float_status_t *status)
+floatx80 fyl2x(floatx80 a, floatx80 b, softfloat_status_t &status)
{
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
@@ -142,71 +141,73 @@ floatx80 fyl2x(floatx80 a, floatx80 b, struct float_status_t *status)
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
// handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) {
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
invalid:
- float_raise(status, float_flag_invalid);
+ softfloat_raiseFlags(&status, softfloat_flag_invalid);
return floatx80_default_nan;
}
- Bit64u aSig = extractFloatx80Frac(a);
- Bit32s aExp = extractFloatx80Exp(a);
- int aSign = extractFloatx80Sign(a);
- Bit64u bSig = extractFloatx80Frac(b);
- Bit32s bExp = extractFloatx80Exp(b);
- int bSign = extractFloatx80Sign(b);
+ uint64_t aSig = extF80_fraction(a);
+ int32_t aExp = extF80_exp(a);
+ int aSign = extF80_sign(a);
+ uint64_t bSig = extF80_fraction(b);
+ int32_t bExp = extF80_exp(b);
+ int bSign = extF80_sign(b);
int zSign = bSign ^ 1;
if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1)
- || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
- {
- return propagateFloatx80NaN(a, b, status);
+ if ((aSig<<1) || ((bExp == 0x7FFF) && (bSig<<1))) {
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status);
}
if (aSign) goto invalid;
else {
- if (bExp == 0) {
- if (bSig == 0) goto invalid;
- float_raise(status, float_flag_denormal);
+ if (! bExp) {
+ if (! bSig) goto invalid;
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
}
return packFloatx80(bSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
}
- if (bExp == 0x7FFF)
- {
- if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
- if (aSign && (Bit64u)(aExp | aSig)) goto invalid;
- if (aSig && (aExp == 0))
- float_raise(status, float_flag_denormal);
+ if (bExp == 0x7FFF) {
+ if (bSig << 1)
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status);
+ if (aSign && (uint64_t)(aExp | aSig)) goto invalid;
+ if (aSig && ! aExp)
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
if (aExp < 0x3FFF) {
return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
- if (aExp == 0x3FFF && ((Bit64u) (aSig<<1) == 0)) goto invalid;
+ if (aExp == 0x3FFF && ! (aSig<<1)) goto invalid;
return packFloatx80(bSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
- if (aExp == 0) {
- if (aSig == 0) {
+ if (! aExp) {
+ if (! aSig) {
if ((bExp | bSig) == 0) goto invalid;
- float_raise(status, float_flag_divbyzero);
+ softfloat_raiseFlags(&status, softfloat_flag_divbyzero);
return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
if (aSign) goto invalid;
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig);
+ aExp = normExpSig.exp + 1;
+ aSig = normExpSig.sig;
}
if (aSign) goto invalid;
- if (bExp == 0) {
- if (bSig == 0) {
+ if (! bExp) {
+ if (! bSig) {
if (aExp < 0x3FFF) return packFloatx80(zSign, 0, 0);
return packFloatx80(bSign, 0, 0);
}
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(bSig);
+ bExp = normExpSig.exp + 1;
+ bSig = normExpSig.sig;
}
- if (aExp == 0x3FFF && ((Bit64u) (aSig<<1) == 0))
+ if (aExp == 0x3FFF && ! (aSig<<1))
return packFloatx80(bSign, 0, 0);
- float_raise(status, float_flag_inexact);
+ softfloat_raiseFlags(&status, softfloat_flag_inexact);
int ExpDiff = aExp - 0x3FFF;
aExp = 0;
@@ -219,12 +220,15 @@ invalid:
/* using float128 for approximation */
/* ******************************** */
- Bit64u zSig0, zSig1;
- shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
- float128 x = packFloat128Four(0, aExp+0x3FFF, zSig0, zSig1);
+ float128_t b128 = softfloat_normRoundPackToF128(bSign, bExp-0x10, bSig, 0, &status);
+
+ uint64_t zSig0, zSig1;
+ shortShift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
+ float128_t x = packFloat128(0, aExp+0x3FFF, zSig0, zSig1);
x = poly_l2(x, status);
- x = float128_add(x, int64_to_float128((Bit64s) ExpDiff), status);
- return floatx80_128_mul(b, x, status);
+ x = f128_add(x, i32_to_f128(ExpDiff), &status);
+ x = f128_mul(x, b128, &status);
+ return f128_to_extF80(x, &status);
}
// =================================================
@@ -252,112 +256,117 @@ invalid:
// 1-u 3 5 7 2n+1
//
-floatx80 fyl2xp1(floatx80 a, floatx80 b, struct float_status_t *status)
+floatx80 fyl2xp1(floatx80 a, floatx80 b, softfloat_status_t &status)
{
+ int32_t aExp, bExp;
+ uint64_t aSig, bSig, zSig0, zSig1, zSig2;
+ int aSign, bSign;
+
/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
const floatx80 floatx80_default_nan = packFloatx80(0, floatx80_default_nan_exp, floatx80_default_nan_fraction);
- Bit32s aExp, bExp;
- Bit64u aSig, bSig, zSig0, zSig1, zSig2;
- int aSign, bSign;
-
// handle unsupported extended double-precision floating encodings
- if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) {
+ if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) {
invalid:
- float_raise(status, float_flag_invalid);
+ softfloat_raiseFlags(&status, softfloat_flag_invalid);
return floatx80_default_nan;
}
- aSig = extractFloatx80Frac(a);
- aExp = extractFloatx80Exp(a);
- aSign = extractFloatx80Sign(a);
- bSig = extractFloatx80Frac(b);
- bExp = extractFloatx80Exp(b);
- bSign = extractFloatx80Sign(b);
+
+ aSig = extF80_fraction(a);
+ aExp = extF80_exp(a);
+ aSign = extF80_sign(a);
+ bSig = extF80_fraction(b);
+ bExp = extF80_exp(b);
+ bSign = extF80_sign(b);
int zSign = aSign ^ bSign;
if (aExp == 0x7FFF) {
- if ((Bit64u) (aSig<<1)
- || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
- {
- return propagateFloatx80NaN(a, b, status);
+ if ((aSig<<1) != 0 || ((bExp == 0x7FFF) && (bSig<<1) != 0)) {
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status);
}
if (aSign) goto invalid;
else {
- if (bExp == 0) {
- if (bSig == 0) goto invalid;
- float_raise(status, float_flag_denormal);
+ if (! bExp) {
+ if (! bSig) goto invalid;
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
}
return packFloatx80(bSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
}
if (bExp == 0x7FFF)
{
- if ((Bit64u) (bSig<<1))
- return propagateFloatx80NaN(a, b, status);
+ if (bSig << 1)
+ return softfloat_propagateNaNExtF80UI(a.signExp, aSig, b.signExp, bSig, &status);
- if (aExp == 0) {
- if (aSig == 0) goto invalid;
- float_raise(status, float_flag_denormal);
+ if (! aExp) {
+ if (! aSig) goto invalid;
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
}
return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
- if (aExp == 0) {
- if (aSig == 0) {
- if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
+ if (! aExp) {
+ if (! aSig) {
+ if (bSig && ! bExp) softfloat_raiseFlags(&status, softfloat_flag_denormal);
return packFloatx80(zSign, 0, 0);
}
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(aSig);
+ aExp = normExpSig.exp + 1;
+ aSig = normExpSig.sig;
}
- if (bExp == 0) {
- if (bSig == 0) return packFloatx80(zSign, 0, 0);
- float_raise(status, float_flag_denormal);
- normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
+ if (! bExp) {
+ if (! bSig) return packFloatx80(zSign, 0, 0);
+ softfloat_raiseFlags(&status, softfloat_flag_denormal);
+ struct exp32_sig64 normExpSig = softfloat_normSubnormalExtF80Sig(bSig);
+ bExp = normExpSig.exp + 1;
+ bSig = normExpSig.sig;
}
- float_raise(status, float_flag_inexact);
+ softfloat_raiseFlags(&status, softfloat_flag_inexact);
if (aSign && aExp >= 0x3FFF)
return a;
if (aExp >= 0x3FFC) // big argument
{
- return fyl2x(floatx80_add(a, floatx80_one, status), b, status);
+ return fyl2x(extF80_add(a, floatx80_one, &status), b, status);
}
// handle tiny argument
if (aExp < FLOATX80_EXP_BIAS-70)
{
// first order approximation, return (a*b)/ln(2)
- Bit32s zExp = aExp + FLOAT_LN2INV_EXP - 0x3FFE;
+ int32_t zExp = aExp + FLOAT_LN2INV_EXP - 0x3FFE;
- mul128By64To192(FLOAT_LN2INV_HI, FLOAT_LN2INV_LO, aSig, &zSig0, &zSig1, &zSig2);
- if (0 < (Bit64s) zSig0) {
+ mul128By64To192(FLOAT_LN2INV_HI, FLOAT_LN2INV_LO, aSig, &zSig0, &zSig1, &zSig2);
+ if (0 < (int64_t) zSig0) {
shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
--zExp;
}
zExp = zExp + bExp - 0x3FFE;
- mul128By64To192(zSig0, zSig1, bSig, &zSig0, &zSig1, &zSig2);
- if (0 < (Bit64s) zSig0) {
+ mul128By64To192(zSig0, zSig1, bSig, &zSig0, &zSig1, &zSig2);
+ if (0 < (int64_t) zSig0) {
shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1);
--zExp;
}
- return
- roundAndPackFloatx80(80, aSign ^ bSign, zExp, zSig0, zSig1, status);
+ return softfloat_roundPackToExtF80(aSign ^ bSign, zExp, zSig0, zSig1, 80, &status);
}
/* ******************************** */
/* using float128 for approximation */
/* ******************************** */
- shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
- float128 x = packFloat128Four(aSign, aExp, zSig0, zSig1);
+ float128_t b128 = softfloat_normRoundPackToF128(bSign, bExp-0x10, bSig, 0, &status);
+
+ shortShift128Right(aSig<<1, 0, 16, &zSig0, &zSig1);
+ float128_t x = packFloat128(aSign, aExp, zSig0, zSig1);
x = poly_l2p1(x, status);
- return floatx80_128_mul(b, x, status);
+ x = f128_mul(x, b128, &status);
+ return f128_to_extF80(x, &status);
}
diff --git a/src/cpu/softfloat3e/i32_to_extF80.cc b/src/cpu/softfloat3e/i32_to_extF80.cc
new file mode 100644
index 000000000..edd92ced0
--- /dev/null
+++ b/src/cpu/softfloat3e/i32_to_extF80.cc
@@ -0,0 +1,62 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+extFloat80_t i32_to_extF80(int32_t a)
+{
+ uint16_t uiZ64;
+ uint32_t absA;
+ bool sign;
+ int8_t shiftDist;
+ extFloat80_t z;
+
+ uiZ64 = 0;
+ absA = 0;
+ if (a) {
+ sign = (a < 0);
+ absA = sign ? -(uint32_t) a : (uint32_t) a;
+ shiftDist = softfloat_countLeadingZeros32(absA);
+ uiZ64 = packToExtF80UI64(sign, 0x401E - shiftDist);
+ absA <<= shiftDist;
+ }
+ z.signExp = uiZ64;
+ z.signif = (uint64_t) absA<<32;
+ return z;
+}
diff --git a/src/cpu/softfloat3e/i32_to_f128.cc b/src/cpu/softfloat3e/i32_to_f128.cc
new file mode 100644
index 000000000..1ae64e46b
--- /dev/null
+++ b/src/cpu/softfloat3e/i32_to_f128.cc
@@ -0,0 +1,59 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+float128_t i32_to_f128(int32_t a)
+{
+ uint64_t uiZ64;
+ bool sign;
+ uint32_t absA;
+ int8_t shiftDist;
+ float128_t z;
+
+ uiZ64 = 0;
+ if (a) {
+ sign = (a < 0);
+ absA = sign ? -(uint32_t) a : (uint32_t) a;
+ shiftDist = softfloat_countLeadingZeros32(absA) + 17;
+ uiZ64 = packToF128UI64(sign, 0x402E - shiftDist, (uint64_t) absA<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+float16 i32_to_f16(int32_t a, struct softfloat_status_t *status)
+{
+ bool sign;
+ uint32_t absA;
+ int8_t shiftDist;
+ uint16_t sig;
+
+ sign = (a < 0);
+ absA = sign ? -(uint32_t) a : (uint32_t) a;
+ shiftDist = softfloat_countLeadingZeros32(absA) - 21;
+ if (0 <= shiftDist) {
+ return a ? packToF16UI(sign, 0x18 - shiftDist, (uint16_t) absA<>(-shiftDist) | ((uint32_t) (absA<<(shiftDist & 31)) != 0)
+ : (uint16_t) absA<
+#include
+#include "internals.h"
+#include "softfloat.h"
+
+float32 i32_to_f32(int32_t a, struct softfloat_status_t *status)
+{
+ bool sign;
+ uint32_t absA;
+
+ sign = (a < 0);
+ if (! (a & 0x7FFFFFFF)) {
+ return sign ? packToF32UI(1, 0x9E, 0) : 0;
+ }
+ absA = sign ? -(uint32_t) a : (uint32_t) a;
+ return softfloat_normRoundPackToF32(sign, 0x9C, absA, status);
+}
diff --git a/src/cpu/softfloat3e/i32_to_f64.c b/src/cpu/softfloat3e/i32_to_f64.c
new file mode 100644
index 000000000..7aaa4e1c2
--- /dev/null
+++ b/src/cpu/softfloat3e/i32_to_f64.c
@@ -0,0 +1,56 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+float64 i32_to_f64(int32_t a)
+{
+ bool sign;
+ uint32_t absA;
+ int8_t shiftDist;
+
+ if (! a) {
+ return 0;
+ } else {
+ sign = (a < 0);
+ absA = sign ? -(uint32_t) a : (uint32_t) a;
+ shiftDist = softfloat_countLeadingZeros32(absA) + 21;
+ return packToF64UI(sign, 0x432 - shiftDist, (uint64_t) absA<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+extFloat80_t i64_to_extF80(int64_t a)
+{
+ uint16_t uiZ64;
+ uint64_t absA;
+ bool sign;
+ int8_t shiftDist;
+ extFloat80_t z;
+
+ uiZ64 = 0;
+ absA = 0;
+ if (a) {
+ sign = (a < 0);
+ absA = sign ? -(uint64_t) a : (uint64_t) a;
+ shiftDist = softfloat_countLeadingZeros64(absA);
+ uiZ64 = packToExtF80UI64(sign, 0x403E - shiftDist);
+ absA <<= shiftDist;
+ }
+ z.signExp = uiZ64;
+ z.signif = absA;
+ return z;
+}
diff --git a/src/cpu/softfloat3e/i64_to_f128.cc b/src/cpu/softfloat3e/i64_to_f128.cc
new file mode 100644
index 000000000..4d80a9e7a
--- /dev/null
+++ b/src/cpu/softfloat3e/i64_to_f128.cc
@@ -0,0 +1,69 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+float128_t i64_to_f128(int64_t a)
+{
+ uint64_t uiZ64, uiZ0;
+ bool sign;
+ uint64_t absA;
+ int8_t shiftDist;
+ struct uint128 zSig;
+ float128_t z;
+
+ if (! a) {
+ uiZ64 = 0;
+ uiZ0 = 0;
+ } else {
+ sign = (a < 0);
+ absA = sign ? -(uint64_t) a : (uint64_t) a;
+ shiftDist = softfloat_countLeadingZeros64(absA) + 49;
+ if (64 <= shiftDist) {
+ zSig.v64 = absA<<(shiftDist - 64);
+ zSig.v0 = 0;
+ } else {
+ zSig = softfloat_shortShiftLeft128(0, absA, shiftDist);
+ }
+ uiZ64 = packToF128UI64(sign, 0x406E - shiftDist, zSig.v64);
+ uiZ0 = zSig.v0;
+ }
+ z.v64 = uiZ64;
+ z.v0 = uiZ0;
+ return z;
+}
diff --git a/src/cpu/softfloat3e/i64_to_f16.c b/src/cpu/softfloat3e/i64_to_f16.c
new file mode 100644
index 000000000..43873610a
--- /dev/null
+++ b/src/cpu/softfloat3e/i64_to_f16.c
@@ -0,0 +1,61 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+float16 i64_to_f16(int64_t a, struct softfloat_status_t *status)
+{
+ bool sign;
+ uint64_t absA;
+ int8_t shiftDist;
+ uint16_t sig;
+
+ sign = (a < 0);
+ absA = sign ? -(uint64_t) a : (uint64_t) a;
+ shiftDist = softfloat_countLeadingZeros64(absA) - 53;
+ if (0 <= shiftDist) {
+ return a ? packToF16UI(sign, 0x18 - shiftDist, (uint16_t) absA<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+float32 i64_to_f32(int64_t a, struct softfloat_status_t *status)
+{
+ bool sign;
+ uint64_t absA;
+ int8_t shiftDist;
+ uint32_t sig;
+
+ sign = (a < 0);
+ absA = sign ? -(uint64_t) a : (uint64_t) a;
+ shiftDist = softfloat_countLeadingZeros64(absA) - 40;
+ if (0 <= shiftDist) {
+ return a ? packToF32UI(sign, 0x95 - shiftDist, (uint32_t) absA<
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "softfloat.h"
+
+float64 i64_to_f64(int64_t a, struct softfloat_status_t *status)
+{
+ bool sign;
+ uint64_t absA;
+
+ sign = (a < 0);
+ if (! (a & UINT64_C(0x7FFFFFFFFFFFFFFF))) {
+ return sign ? packToF64UI(1, 0x43E, 0) : 0;
+ }
+ absA = sign ? -(uint64_t) a : (uint64_t) a;
+ return softfloat_normRoundPackToF64(sign, 0x43C, absA, status);
+}
diff --git a/src/cpu/softfloat3e/internals.h b/src/cpu/softfloat3e/internals.h
new file mode 100644
index 000000000..3b5d7aa4d
--- /dev/null
+++ b/src/cpu/softfloat3e/internals.h
@@ -0,0 +1,150 @@
+/*============================================================================
+
+This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+
+=============================================================================*/
+
+#ifndef _INTERNALS_H_
+#define _INTERNALS_H_
+
+#include
+#include
+//#include "primitives.h"
+#include "softfloat_types.h"
+
+struct softfloat_status_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+uint32_t softfloat_roundToUI32(bool, uint64_t, uint8_t, bool, struct softfloat_status_t *);
+uint64_t softfloat_roundToUI64(bool, uint64_t, uint64_t, uint8_t, bool, struct softfloat_status_t *);
+
+int32_t softfloat_roundToI32(bool, uint64_t, uint8_t, bool, struct softfloat_status_t *);
+int64_t softfloat_roundToI64(bool, uint64_t, uint64_t, uint8_t, bool, struct softfloat_status_t *);
+
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+
+
+#define signF16UI(a) ((bool) ((uint16_t) (a)>>15))
+#define expF16UI(a) ((int8_t) ((a)>>10) & 0x1F)
+#define fracF16UI(a) ((a) & 0x03FF)
+#define packToF16UI(sign, exp, sig) (((uint16_t) (sign)<<15) + ((uint16_t) (exp)<<10) + (sig))
+
+#define isNaNF16UI(a) (((~(a) & 0x7C00) == 0) && ((a) & 0x03FF))
+
+struct exp8_sig16 { int8_t exp; uint16_t sig; };
+struct exp8_sig16 softfloat_normSubnormalF16Sig(uint16_t);
+
+float16 softfloat_roundPackToF16(bool, int16_t, uint16_t, struct softfloat_status_t *);
+float16 softfloat_normRoundPackToF16(bool, int16_t, uint16_t, struct softfloat_status_t *);
+
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+#define signF32UI(a) ((bool) ((uint32_t) (a)>>31))
+#define expF32UI(a) ((int16_t) ((a)>>23) & 0xFF)
+#define fracF32UI(a) ((a) & 0x007FFFFF)
+#define packToF32UI(sign, exp, sig) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<23) + (sig))
+
+#define isNaNF32UI(a) (((~(a) & 0x7F800000) == 0) && ((a) & 0x007FFFFF))
+
+struct exp16_sig32 { int16_t exp; uint32_t sig; };
+struct exp16_sig32 softfloat_normSubnormalF32Sig(uint32_t);
+
+float32 softfloat_roundPackToF32(bool, int16_t, uint32_t, struct softfloat_status_t *);
+float32 softfloat_normRoundPackToF32(bool, int16_t, uint32_t, struct softfloat_status_t *);
+
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+#define signF64UI(a) ((bool) ((uint64_t) (a)>>63))
+#define expF64UI(a) ((int16_t) ((a)>>52) & 0x7FF)
+#define fracF64UI(a) ((a) & UINT64_C(0x000FFFFFFFFFFFFF))
+#define packToF64UI(sign, exp, sig) ((uint64_t) (((uint64_t) (sign)<<63) + ((uint64_t) (exp)<<52) + (sig)))
+
+#define isNaNF64UI(a) (((~(a) & UINT64_C(0x7FF0000000000000)) == 0) && ((a) & UINT64_C(0x000FFFFFFFFFFFFF)))
+
+struct exp16_sig64 { int16_t exp; uint64_t sig; };
+struct exp16_sig64 softfloat_normSubnormalF64Sig(uint64_t);
+
+float64 softfloat_roundPackToF64(bool, int16_t, uint64_t, struct softfloat_status_t *);
+float64 softfloat_normRoundPackToF64(bool, int16_t, uint64_t, struct softfloat_status_t *);
+
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+
+extFloat80_t softfloat_addMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB64, uint64_t uiB0, bool signZ, struct softfloat_status_t *status);
+extFloat80_t softfloat_subMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB64, uint64_t uiB0, bool signZ, struct softfloat_status_t *status);
+
+#define signExtF80UI64(a64) ((bool) ((uint16_t) (a64)>>15))
+#define expExtF80UI64(a64) ((a64) & 0x7FFF)
+#define packToExtF80UI64(sign, exp) ((uint16_t) (sign)<<15 | (exp))
+
+#define isNaNExtF80UI(a64, a0) ((((a64) & 0x7FFF) == 0x7FFF) && ((a0) & UINT64_C(0x7FFFFFFFFFFFFFFF)))
+
+extFloat80_t packToExtF80(bool, uint16_t, uint64_t);
+extFloat80_t packToExtF80_twoargs(uint16_t, uint64_t);
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+
+struct exp32_sig64 { int32_t exp; uint64_t sig; };
+struct exp32_sig64 softfloat_normSubnormalExtF80Sig(uint64_t);
+
+extFloat80_t
+ softfloat_roundPackToExtF80(bool, int32_t, uint64_t, uint64_t, uint8_t, struct softfloat_status_t *);
+extFloat80_t
+ softfloat_normRoundPackToExtF80(bool, int32_t, uint64_t, uint64_t, uint8_t, struct softfloat_status_t *);
+
+/*----------------------------------------------------------------------------
+*----------------------------------------------------------------------------*/
+#define signF128UI64(a64) ((bool) ((uint64_t) (a64)>>63))
+#define expF128UI64(a64) ((int32_t) ((a64)>>48) & 0x7FFF)
+#define fracF128UI64(a64) ((a64) & UINT64_C(0x0000FFFFFFFFFFFF))
+#define packToF128UI64(sign, exp, sig64) (((uint64_t) (sign)<<63) + ((uint64_t) (exp)<<48) + (sig64))
+
+#define isNaNF128UI(a64, a0) (((~(a64) & UINT64_C(0x7FFF000000000000)) == 0) && (a0 || ((a64) & UINT64_C(0x0000FFFFFFFFFFFF))))
+
+struct exp32_sig128 { int32_t exp; struct uint128 sig; };
+struct exp32_sig128 softfloat_normSubnormalF128Sig(uint64_t, uint64_t);
+
+float128_t
+ softfloat_roundPackToF128(bool, int32_t, uint64_t, uint64_t, uint64_t, struct softfloat_status_t *);
+float128_t
+ softfloat_normRoundPackToF128(bool, int32_t, uint64_t, uint64_t, struct softfloat_status_t *);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/cpu/softfloat3e/isNaN.cc b/src/cpu/softfloat3e/isNaN.cc
new file mode 100644
index 000000000..8c0bd1912
--- /dev/null
+++ b/src/cpu/softfloat3e/isNaN.cc
@@ -0,0 +1,63 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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 "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+bool f16_isNaN(float16 a)
+{
+ return isNaNF16UI(a);
+}
+
+bool f32_isNaN(float32 a)
+{
+ return isNaNF32UI(a);
+}
+
+bool f64_isNaN(float64 a)
+{
+ return isNaNF64UI(a);
+}
+
+bool extF80_isNaN(extFloat80_t a)
+{
+ return isNaNExtF80UI(a.signExp, a.signif);
+}
+
+bool f128_isNaN(float128_t a)
+{
+ return isNaNF128UI(a.v64, a.v0);
+}
diff --git a/src/cpu/softfloat3e/isSignalingNaN.cc b/src/cpu/softfloat3e/isSignalingNaN.cc
new file mode 100644
index 000000000..994ac3784
--- /dev/null
+++ b/src/cpu/softfloat3e/isSignalingNaN.cc
@@ -0,0 +1,63 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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 "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+bool f16_isSignalingNaN(float16 a)
+{
+ return softfloat_isSigNaNF16UI(a);
+}
+
+bool f32_isSignalingNaN(float32 a)
+{
+ return softfloat_isSigNaNF32UI(a);
+}
+
+bool f64_isSignalingNaN(float64 a)
+{
+ return softfloat_isSigNaNF64UI(a);
+}
+
+bool extF80_isSignalingNaN(extFloat80_t a)
+{
+ return softfloat_isSigNaNExtF80UI(a.signExp, a.signif);
+}
+
+bool f128_isSignalingNaN(float128_t a)
+{
+ return softfloat_isSigNaNF128UI(a.v64, a.v0);
+}
diff --git a/src/cpu/softfloat3e/opts-GCC.h b/src/cpu/softfloat3e/opts-GCC.h
new file mode 100644
index 000000000..dd6c0ab64
--- /dev/null
+++ b/src/cpu/softfloat3e/opts-GCC.h
@@ -0,0 +1,110 @@
+
+/*============================================================================
+
+This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2017 The Regents of the University of California. All rights
+reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+
+=============================================================================*/
+
+#ifndef _OPTS_GCC_H_
+#define _OPTS_GCC_H_
+
+#include
+#include "primitiveTypes.h"
+
+#ifdef SOFTFLOAT_BUILTIN_CLZ
+
+static __inline uint8_t softfloat_countLeadingZeros16(uint16_t a)
+ { return a ? __builtin_clz(a) - 16 : 16; }
+#define softfloat_countLeadingZeros16 softfloat_countLeadingZeros16
+
+static __inline uint8_t softfloat_countLeadingZeros32(uint32_t a)
+ { return a ? __builtin_clz(a) : 32; }
+#define softfloat_countLeadingZeros32 softfloat_countLeadingZeros32
+
+static __inline uint8_t softfloat_countLeadingZeros64(uint64_t a)
+ { return a ? __builtin_clzll(a) : 64; }
+#define softfloat_countLeadingZeros64 softfloat_countLeadingZeros64
+
+#endif
+
+#ifdef SOFTFLOAT_INTRINSIC_INT128
+
+static __inline struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b)
+{
+ union { unsigned __int128 ui; struct uint128 s; } uZ;
+ uZ.ui = (unsigned __int128) a * ((uint64_t) b<<32);
+ return uZ.s;
+}
+#define softfloat_mul64ByShifted32To128 softfloat_mul64ByShifted32To128
+
+static __inline struct uint128 softfloat_mul64To128(uint64_t a, uint64_t b)
+{
+ union { unsigned __int128 ui; struct uint128 s; } uZ;
+ uZ.ui = (unsigned __int128) a * b;
+ return uZ.s;
+}
+#define softfloat_mul64To128 softfloat_mul64To128
+
+static __inline
+struct uint128 softfloat_mul128By32(uint64_t a64, uint64_t a0, uint32_t b)
+{
+ union { unsigned __int128 ui; struct uint128 s; } uZ;
+ uZ.ui = ((unsigned __int128) a64<<64 | a0) * b;
+ return uZ.s;
+}
+#define softfloat_mul128By32 softfloat_mul128By32
+
+static __inline
+void
+ softfloat_mul128To256M(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr)
+{
+ unsigned __int128 z0, mid1, mid, z128;
+ z0 = (unsigned __int128) a0 * b0;
+ mid1 = (unsigned __int128) a64 * b0;
+ mid = mid1 + (unsigned __int128) a0 * b64;
+ z128 = (unsigned __int128) a64 * b64;
+ z128 += (unsigned __int128) (mid < mid1)<<64 | mid>>64;
+ mid <<= 64;
+ z0 += mid;
+ z128 += (z0 < mid);
+ zPtr[indexWord(4, 0)] = z0;
+ zPtr[indexWord(4, 1)] = z0>>64;
+ zPtr[indexWord(4, 2)] = z128;
+ zPtr[indexWord(4, 3)] = z128>>64;
+}
+#define softfloat_mul128To256M softfloat_mul128To256M
+
+#endif
+
+#endif
+
+#endif
diff --git a/src/cpu/softfloat/softfloat_poly.cc b/src/cpu/softfloat3e/poly.cc
similarity index 84%
rename from src/cpu/softfloat/softfloat_poly.cc
rename to src/cpu/softfloat3e/poly.cc
index 5c7079353..a89d7f03f 100644
--- a/src/cpu/softfloat/softfloat_poly.cc
+++ b/src/cpu/softfloat3e/poly.cc
@@ -23,10 +23,10 @@ these four paragraphs for those parts of this code that are retained.
* Stanislav Shwartsman [sshwarts at sourceforge net]
* ==========================================================================*/
-#define FLOAT128
-
#include
+
#include "softfloat.h"
+#include "poly.h"
// 2 3 4 n
// f(x) ~ C + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x)
@@ -39,13 +39,15 @@ these four paragraphs for those parts of this code that are retained.
// f(x) ~ [ p(x) + x * q(x) ]
//
-float128 EvalPoly(float128 x, float128 *arr, int n, struct float_status_t *status)
+float128_t EvalPoly(float128_t x, const float128_t *arr, int n, struct softfloat_status_t *status)
{
- float128 r = arr[--n];
+ float128_t r = arr[--n];
do {
- r = float128_mul(r, x, status);
- r = float128_add(r, arr[--n], status);
+ r = f128_mulAdd(r, x, arr[--n], 0, status);
+// r = f128_mul(r, x, &status);
+// r = f128_add(r, arr[--n], &status);
+
} while (n > 0);
return r;
@@ -63,9 +65,9 @@ float128 EvalPoly(float128 x, float128 *arr, int n, struct float_status_t *statu
// f(x) ~ [ p(x) + x * q(x) ]
//
-float128 EvenPoly(float128 x, float128 *arr, int n, struct float_status_t *status)
+float128_t EvenPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status)
{
- return EvalPoly(float128_mul(x, x, status), arr, n, status);
+ return EvalPoly(f128_mul(x, x, &status), arr, n, &status);
}
// 3 5 7 9 2n+1
@@ -83,7 +85,7 @@ float128 EvenPoly(float128 x, float128 *arr, int n, struct float_status_t *statu
// f(x) ~ x * [ p(x) + x * q(x) ]
//
-float128 OddPoly(float128 x, float128 *arr, int n, struct float_status_t *status)
+float128_t OddPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status)
{
- return float128_mul(x, EvenPoly(x, arr, n, status), status);
+ return f128_mul(x, EvenPoly(x, arr, n, status), &status);
}
diff --git a/src/cpu/softfloat3e/poly.h b/src/cpu/softfloat3e/poly.h
new file mode 100644
index 000000000..1d6c3170c
--- /dev/null
+++ b/src/cpu/softfloat3e/poly.h
@@ -0,0 +1,43 @@
+/////////////////////////////////////////////////////////////////////////
+// $Id$
+/////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2003-2018 Stanislav Shwartsman
+// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+/////////////////////////////////////////////////////////////////////////
+
+#ifndef _POLY_H_
+#define _POLY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+float128_t EvenPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status);
+float128_t OddPoly(float128_t x, const float128_t *arr, int n, softfloat_status_t &status);
+#else
+float128_t EvenPoly(float128_t x, const float128_t *arr, int n, struct softfloat_status_t *status);
+float128_t OddPoly(float128_t x, const float128_t *arr, int n, struct float_status_t *status);
+#endif // __cplusplus
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _POLY_H_
diff --git a/src/cpu/softfloat3e/primitiveTypes.h b/src/cpu/softfloat3e/primitiveTypes.h
new file mode 100644
index 000000000..67751372f
--- /dev/null
+++ b/src/cpu/softfloat3e/primitiveTypes.h
@@ -0,0 +1,54 @@
+/*============================================================================
+
+This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+
+=============================================================================*/
+
+#ifndef primitiveTypes_h
+#define primitiveTypes_h
+
+/*----------------------------------------------------------------------------
+| These macros are used to isolate the differences in word order between big-
+| endian and little-endian platforms.
+*----------------------------------------------------------------------------*/
+#define wordIncr 1
+#define indexWord(total, n) (n)
+#define indexWordHi(total) ((total) - 1)
+#define indexWordLo(total) 0
+#define indexMultiword(total, m, n) (n)
+#define indexMultiwordHi(total, n) ((total) - (n))
+#define indexMultiwordLo(total, n) 0
+#define indexMultiwordHiBut(total, n) (n)
+#define indexMultiwordLoBut(total, n) 0
+#define INIT_UINTM4(v3, v2, v1, v0) { v0, v1, v2, v3 }
+
+#endif
diff --git a/src/cpu/softfloat3e/primitives.h b/src/cpu/softfloat3e/primitives.h
new file mode 100644
index 000000000..993067996
--- /dev/null
+++ b/src/cpu/softfloat3e/primitives.h
@@ -0,0 +1,535 @@
+/*============================================================================
+
+This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+
+=============================================================================*/
+
+#ifndef _PRIMITIVES_H_
+#define _PRIMITIVES_H_
+
+#include
+#include
+#include "softfloat_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SOFTFLOAT_FAST_DIV64TO32
+
+#ifndef softfloat_shortShiftRightJam64
+/*----------------------------------------------------------------------------
+| Shifts 'a' right by the number of bits given in 'dist', which must be in
+| the range 1 to 63. If any nonzero bits are shifted off, they are "jammed"
+| into the least-significant bit of the shifted value by setting the least-
+| significant bit to 1. This shifted-and-jammed value is returned.
+*----------------------------------------------------------------------------*/
+static __inline
+uint64_t softfloat_shortShiftRightJam64(uint64_t a, uint8_t dist)
+{
+ return a>>dist | ((a & (((uint64_t) 1<>dist | ((uint32_t) (a<<(-dist & 31)) != 0) : (a != 0);
+}
+#endif
+
+#ifndef softfloat_shiftRightJam64
+/*----------------------------------------------------------------------------
+| Shifts 'a' right by the number of bits given in 'dist', which must not
+| be zero. If any nonzero bits are shifted off, they are "jammed" into the
+| least-significant bit of the shifted value by setting the least-significant
+| bit to 1. This shifted-and-jammed value is returned.
+| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is
+| greater than 64, the result will be either 0 or 1, depending on whether 'a'
+| is zero or nonzero.
+*----------------------------------------------------------------------------*/
+static __inline uint64_t softfloat_shiftRightJam64(uint64_t a, uint32_t dist)
+{
+ return (dist < 63) ? a>>dist | ((uint64_t) (a<<(-dist & 63)) != 0) : (a != 0);
+}
+#endif
+
+/*----------------------------------------------------------------------------
+| A constant table that translates an 8-bit unsigned integer (the array index)
+| into the number of leading 0 bits before the most-significant 1 of that
+| integer. For integer zero (index 0), the corresponding table element is 8.
+*----------------------------------------------------------------------------*/
+extern const uint_least8_t softfloat_countLeadingZeros8[256];
+
+#ifndef softfloat_countLeadingZeros16
+/*----------------------------------------------------------------------------
+| Returns the number of leading 0 bits before the most-significant 1 bit of
+| 'a'. If 'a' is zero, 16 is returned.
+*----------------------------------------------------------------------------*/
+static __inline uint8_t softfloat_countLeadingZeros16(uint16_t a)
+{
+ uint8_t count = 8;
+ if (0x100 <= a) {
+ count = 0;
+ a >>= 8;
+ }
+ count += softfloat_countLeadingZeros8[a];
+ return count;
+}
+#endif
+
+#ifndef softfloat_countLeadingZeros32
+/*----------------------------------------------------------------------------
+| Returns the number of leading 0 bits before the most-significant 1 bit of
+| 'a'. If 'a' is zero, 32 is returned.
+*----------------------------------------------------------------------------*/
+static __inline uint8_t softfloat_countLeadingZeros32(uint32_t a)
+{
+ uint8_t count = 0;
+ if (a < 0x10000) {
+ count = 16;
+ a <<= 16;
+ }
+ if (a < 0x1000000) {
+ count += 8;
+ a <<= 8;
+ }
+ count += softfloat_countLeadingZeros8[a>>24];
+ return count;
+}
+#endif
+
+#ifndef softfloat_countLeadingZeros64
+/*----------------------------------------------------------------------------
+| Returns the number of leading 0 bits before the most-significant 1 bit of
+| 'a'. If 'a' is zero, 64 is returned.
+*----------------------------------------------------------------------------*/
+uint8_t softfloat_countLeadingZeros64(uint64_t a);
+#endif
+
+extern const uint16_t softfloat_approxRecip_1k0s[16];
+extern const uint16_t softfloat_approxRecip_1k1s[16];
+
+#ifndef softfloat_approxRecip32_1
+/*----------------------------------------------------------------------------
+| Returns an approximation to the reciprocal of the number represented by 'a',
+| where 'a' is interpreted as an unsigned fixed-point number with one integer
+| bit and 31 fraction bits. The 'a' input must be "normalized", meaning that
+| its most-significant bit (bit 31) must be 1. Thus, if A is the value of
+| the fixed-point interpretation of 'a', then 1 <= A < 2. The returned value
+| is interpreted as a pure unsigned fraction, having no integer bits and 32
+| fraction bits. The approximation returned is never greater than the true
+| reciprocal 1/A, and it differs from the true reciprocal by at most 2.006 ulp
+| (units in the last place).
+*----------------------------------------------------------------------------*/
+#ifdef SOFTFLOAT_FAST_DIV64TO32
+#define softfloat_approxRecip32_1(a) ((uint32_t) (UINT64_C(0x7FFFFFFFFFFFFFFF) / (uint32_t) (a)))
+#endif
+#endif
+
+extern const uint16_t softfloat_approxRecipSqrt_1k0s[16];
+extern const uint16_t softfloat_approxRecipSqrt_1k1s[16];
+
+/*----------------------------------------------------------------------------
+| Returns an approximation to the reciprocal of the square root of the number
+| represented by 'a', where 'a' is interpreted as an unsigned fixed-point
+| number either with one integer bit and 31 fraction bits or with two integer
+| bits and 30 fraction bits. The format of 'a' is determined by 'oddExpA',
+| which must be either 0 or 1. If 'oddExpA' is 1, 'a' is interpreted as
+| having one integer bit, and if 'oddExpA' is 0, 'a' is interpreted as having
+| two integer bits. The 'a' input must be "normalized", meaning that its
+| most-significant bit (bit 31) must be 1. Thus, if A is the value of the
+| fixed-point interpretation of 'a', it follows that 1 <= A < 2 when 'oddExpA'
+| is 1, and 2 <= A < 4 when 'oddExpA' is 0.
+| The returned value is interpreted as a pure unsigned fraction, having
+| no integer bits and 32 fraction bits. The approximation returned is never
+| greater than the true reciprocal 1/sqrt(A), and it differs from the true
+| reciprocal by at most 2.06 ulp (units in the last place). The approximation
+| returned is also always within the range 0.5 to 1; thus, the most-
+| significant bit of the result is always set.
+*----------------------------------------------------------------------------*/
+uint32_t softfloat_approxRecipSqrt32_1(unsigned int oddExpA, uint32_t a);
+
+/*----------------------------------------------------------------------------
+| Returns true if the 128-bit unsigned integer formed by concatenating 'a64'
+| and 'a0' is equal to the 128-bit unsigned integer formed by concatenating
+| 'b64' and 'b0'.
+*----------------------------------------------------------------------------*/
+static __inline
+bool softfloat_eq128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
+{
+ return (a64 == b64) && (a0 == b0);
+}
+
+/*----------------------------------------------------------------------------
+| Returns true if the 128-bit unsigned integer formed by concatenating 'a64'
+| and 'a0' is less than or equal to the 128-bit unsigned integer formed by
+| concatenating 'b64' and 'b0'.
+*----------------------------------------------------------------------------*/
+static __inline
+bool softfloat_le128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
+{
+ return (a64 < b64) || ((a64 == b64) && (a0 <= b0));
+}
+
+/*----------------------------------------------------------------------------
+| Returns true if the 128-bit unsigned integer formed by concatenating 'a64'
+| and 'a0' is less than the 128-bit unsigned integer formed by concatenating
+| 'b64' and 'b0'.
+*----------------------------------------------------------------------------*/
+static __inline
+bool softfloat_lt128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
+{
+ return (a64 < b64) || ((a64 == b64) && (a0 < b0));
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 128 bits formed by concatenating 'a64' and 'a0' left by the
+| number of bits given in 'dist', which must be in the range 1 to 63.
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint128 softfloat_shortShiftLeft128(uint64_t a64, uint64_t a0, uint8_t dist)
+{
+ struct uint128 z;
+ z.v64 = a64<>(-dist & 63);
+ z.v0 = a0<>dist;
+ z.v0 = a64<<(-dist & 63) | a0>>dist;
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| This function is the same as 'softfloat_shiftRightJam64Extra' (below),
+| except that 'dist' must be in the range 1 to 63.
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint64_extra softfloat_shortShiftRightJam64Extra(uint64_t a, uint64_t extra, uint8_t dist)
+{
+ struct uint64_extra z;
+ z.v = a>>dist;
+ z.extra = a<<(-dist & 63) | (extra != 0);
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 128 bits formed by concatenating 'a64' and 'a0' right by the
+| number of bits given in 'dist', which must be in the range 1 to 63. If any
+| nonzero bits are shifted off, they are "jammed" into the least-significant
+| bit of the shifted value by setting the least-significant bit to 1. This
+| shifted-and-jammed value is returned.
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint128 softfloat_shortShiftRightJam128(uint64_t a64, uint64_t a0, uint8_t dist)
+{
+ uint8_t negDist = -dist;
+ struct uint128 z;
+ z.v64 = a64>>dist;
+ z.v0 =
+ a64<<(negDist & 63) | a0>>dist
+ | ((uint64_t) (a0<<(negDist & 63)) != 0);
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| This function is the same as 'softfloat_shiftRightJam128Extra' (below),
+| except that 'dist' must be in the range 1 to 63.
+*----------------------------------------------------------------------------*/
+struct uint128_extra softfloat_shortShiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint8_t dist)
+{
+ uint8_t negDist = -dist;
+ struct uint128_extra z;
+ z.v.v64 = a64>>dist;
+ z.v.v0 = a64<<(negDist & 63) | a0>>dist;
+ z.extra = a0<<(negDist & 63) | (extra != 0);
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 128 bits formed by concatenating 'a' and 'extra' right by 64
+| _plus_ the number of bits given in 'dist', which must not be zero. This
+| shifted value is at most 64 nonzero bits and is returned in the 'v' field
+| of the 'struct uint64_extra' result. The 64-bit 'extra' field of the result
+| contains a value formed as follows from the bits that were shifted off: The
+| _last_ bit shifted off is the most-significant bit of the 'extra' field, and
+| the other 63 bits of the 'extra' field are all zero if and only if _all_but_
+| _the_last_ bits shifted off were all zero.
+| (This function makes more sense if 'a' and 'extra' are considered to form
+| an unsigned fixed-point number with binary point between 'a' and 'extra'.
+| This fixed-point value is shifted right by the number of bits given in
+| 'dist', and the integer part of this shifted value is returned in the 'v'
+| field of the result. The fractional part of the shifted value is modified
+| as described above and returned in the 'extra' field of the result.)
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint64_extra
+ softfloat_shiftRightJam64Extra(uint64_t a, uint64_t extra, uint32_t dist)
+{
+ struct uint64_extra z;
+ if (dist < 64) {
+ z.v = a>>dist;
+ z.extra = a<<(-dist & 63);
+ } else {
+ z.v = 0;
+ z.extra = (dist == 64) ? a : (a != 0);
+ }
+ z.extra |= (extra != 0);
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 128 bits formed by concatenating 'a64' and 'a0' right by the
+| number of bits given in 'dist', which must not be zero. If any nonzero bits
+| are shifted off, they are "jammed" into the least-significant bit of the
+| shifted value by setting the least-significant bit to 1. This shifted-and-
+| jammed value is returned.
+| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is
+| greater than 128, the result will be either 0 or 1, depending on whether the
+| original 128 bits are all zeros.
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint128
+ softfloat_shiftRightJam128(uint64_t a64, uint64_t a0, uint32_t dist)
+{
+ uint8_t u8NegDist;
+ struct uint128 z;
+
+ if (dist < 64) {
+ u8NegDist = -dist;
+ z.v64 = a64>>dist;
+ z.v0 =
+ a64<<(u8NegDist & 63) | a0>>dist
+ | ((uint64_t) (a0<<(u8NegDist & 63)) != 0);
+ } else {
+ z.v64 = 0;
+ z.v0 =
+ (dist < 127)
+ ? a64>>(dist & 63)
+ | (((a64 & (((uint64_t) 1<<(dist & 63)) - 1)) | a0)
+ != 0)
+ : ((a64 | a0) != 0);
+ }
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 192 bits formed by concatenating 'a64', 'a0', and 'extra' right
+| by 64 _plus_ the number of bits given in 'dist', which must not be zero.
+| This shifted value is at most 128 nonzero bits and is returned in the 'v'
+| field of the 'struct uint128_extra' result. The 64-bit 'extra' field of the
+| result contains a value formed as follows from the bits that were shifted
+| off: The _last_ bit shifted off is the most-significant bit of the 'extra'
+| field, and the other 63 bits of the 'extra' field are all zero if and only
+| if _all_but_the_last_ bits shifted off were all zero.
+| (This function makes more sense if 'a64', 'a0', and 'extra' are considered
+| to form an unsigned fixed-point number with binary point between 'a0' and
+| 'extra'. This fixed-point value is shifted right by the number of bits
+| given in 'dist', and the integer part of this shifted value is returned
+| in the 'v' field of the result. The fractional part of the shifted value
+| is modified as described above and returned in the 'extra' field of the
+| result.)
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint128_extra
+ softfloat_shiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint32_t dist)
+{
+ uint8_t u8NegDist;
+ struct uint128_extra z;
+
+ u8NegDist = -dist;
+ if (dist < 64) {
+ z.v.v64 = a64>>dist;
+ z.v.v0 = a64<<(u8NegDist & 63) | a0>>dist;
+ z.extra = a0<<(u8NegDist & 63);
+ } else {
+ z.v.v64 = 0;
+ if (dist == 64) {
+ z.v.v0 = a64;
+ z.extra = a0;
+ } else {
+ extra |= a0;
+ if (dist < 128) {
+ z.v.v0 = a64>>(dist & 63);
+ z.extra = a64<<(u8NegDist & 63);
+ } else {
+ z.v.v0 = 0;
+ z.extra = (dist == 128) ? a64 : (a64 != 0);
+ }
+ }
+ }
+ z.extra |= (extra != 0);
+ return z;
+
+}
+
+/*----------------------------------------------------------------------------
+| Shifts the 256-bit unsigned integer pointed to by 'aPtr' right by the number
+| of bits given in 'dist', which must not be zero. If any nonzero bits are
+| shifted off, they are "jammed" into the least-significant bit of the shifted
+| value by setting the least-significant bit to 1. This shifted-and-jammed
+| value is stored at the location pointed to by 'zPtr'. Each of 'aPtr' and
+| 'zPtr' points to an array of four 64-bit elements that concatenate in the
+| platform's normal endian order to form a 256-bit integer.
+| The value of 'dist' can be arbitrarily large. In particular, if 'dist'
+| is greater than 256, the stored result will be either 0 or 1, depending on
+| whether the original 256 bits are all zeros.
+*----------------------------------------------------------------------------*/
+void
+ softfloat_shiftRightJam256M(const uint64_t *aPtr, uint32_t dist, uint64_t *zPtr);
+
+#ifndef softfloat_add128
+/*----------------------------------------------------------------------------
+| Returns the sum of the 128-bit integer formed by concatenating 'a64' and
+| 'a0' and the 128-bit integer formed by concatenating 'b64' and 'b0'. The
+| addition is modulo 2^128, so any carry out is lost.
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint128 softfloat_add128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
+{
+ struct uint128 z;
+ z.v0 = a0 + b0;
+ z.v64 = a64 + b64 + (z.v0 < a0);
+ return z;
+}
+#endif
+
+#ifndef softfloat_add256M
+/*----------------------------------------------------------------------------
+| Adds the two 256-bit integers pointed to by 'aPtr' and 'bPtr'. The addition
+| is modulo 2^256, so any carry out is lost. The sum is stored at the
+| location pointed to by 'zPtr'. Each of 'aPtr', 'bPtr', and 'zPtr' points to
+| an array of four 64-bit elements that concatenate in the platform's normal
+| endian order to form a 256-bit integer.
+*----------------------------------------------------------------------------*/
+void
+ softfloat_add256M(const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr);
+#endif
+
+#ifndef softfloat_sub128
+/*----------------------------------------------------------------------------
+| Returns the difference of the 128-bit integer formed by concatenating 'a64'
+| and 'a0' and the 128-bit integer formed by concatenating 'b64' and 'b0'.
+| The subtraction is modulo 2^128, so any borrow out (carry out) is lost.
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint128 softfloat_sub128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
+{
+ struct uint128 z;
+ z.v0 = a0 - b0;
+ z.v64 = a64 - b64;
+ z.v64 -= (a0 < b0);
+ return z;
+}
+#endif
+
+#ifndef softfloat_sub256M
+/*----------------------------------------------------------------------------
+| Subtracts the 256-bit integer pointed to by 'bPtr' from the 256-bit integer
+| pointed to by 'aPtr'. The addition is modulo 2^256, so any borrow out
+| (carry out) is lost. The difference is stored at the location pointed to
+| by 'zPtr'. Each of 'aPtr', 'bPtr', and 'zPtr' points to an array of four
+| 64-bit elements that concatenate in the platform's normal endian order to
+| form a 256-bit integer.
+*----------------------------------------------------------------------------*/
+void
+ softfloat_sub256M(const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr);
+#endif
+
+/*----------------------------------------------------------------------------
+| Returns the 128-bit product of 'a', 'b', and 2^32.
+*----------------------------------------------------------------------------*/
+static __inline struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b)
+{
+ uint64_t mid;
+ struct uint128 z;
+ mid = (uint64_t) (uint32_t) a * b;
+ z.v0 = mid<<32;
+ z.v64 = (uint64_t) (uint32_t) (a>>32) * b + (mid>>32);
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| Returns the 128-bit product of 'a' and 'b'.
+*----------------------------------------------------------------------------*/
+struct uint128 softfloat_mul64To128(uint64_t a, uint64_t b);
+
+/*----------------------------------------------------------------------------
+| Returns the product of the 128-bit integer formed by concatenating 'a64' and
+| 'a0', multiplied by 'b'. The multiplication is modulo 2^128; any overflow
+| bits are discarded.
+*----------------------------------------------------------------------------*/
+static __inline
+struct uint128 softfloat_mul128By32(uint64_t a64, uint64_t a0, uint32_t b)
+{
+ struct uint128 z;
+ uint64_t mid;
+ uint32_t carry;
+ z.v0 = a0 * b;
+ mid = (uint64_t) (uint32_t) (a0>>32) * b;
+ carry = (uint32_t) ((uint32_t) (z.v0>>32) - (uint32_t) mid);
+ z.v64 = a64 * b + (uint32_t) ((mid + carry)>>32);
+ return z;
+}
+
+/*----------------------------------------------------------------------------
+| Multiplies the 128-bit unsigned integer formed by concatenating 'a64' and
+| 'a0' by the 128-bit unsigned integer formed by concatenating 'b64' and
+| 'b0'. The 256-bit product is stored at the location pointed to by 'zPtr'.
+| Argument 'zPtr' points to an array of four 64-bit elements that concatenate
+| in the platform's normal endian order to form a 256-bit integer.
+*----------------------------------------------------------------------------*/
+void
+ softfloat_mul128To256M(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr);
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _PRIMITIVES_H_
diff --git a/src/cpu/softfloat3e/s_add128.cc b/src/cpu/softfloat3e/s_add128.cc
new file mode 100644
index 000000000..8efabb850
--- /dev/null
+++ b/src/cpu/softfloat3e/s_add128.cc
@@ -0,0 +1,51 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "softfloat_types.h"
+
+#ifndef softfloat_add128
+
+struct uint128 softfloat_add128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0)
+{
+ struct uint128 z;
+
+ z.v0 = a0 + b0;
+ z.v64 = a64 + b64 + (z.v0 < a0);
+ return z;
+}
+
+#endif
+
diff --git a/src/cpu/softfloat3e/s_add256M.c b/src/cpu/softfloat3e/s_add256M.c
new file mode 100644
index 000000000..32fdf122f
--- /dev/null
+++ b/src/cpu/softfloat3e/s_add256M.c
@@ -0,0 +1,60 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "primitiveTypes.h"
+
+#ifndef softfloat_add256M
+
+void softfloat_add256M(const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr)
+{
+ unsigned int index;
+ uint8_t carry;
+ uint64_t wordA, wordZ;
+
+ index = indexWordLo(4);
+ carry = 0;
+ for (;;) {
+ wordA = aPtr[index];
+ wordZ = wordA + bPtr[index] + carry;
+ zPtr[index] = wordZ;
+ if (index == indexWordHi(4)) break;
+ if (wordZ != wordA) carry = (wordZ < wordA);
+ index += wordIncr;
+ }
+}
+
+#endif
+
diff --git a/src/cpu/softfloat3e/s_addMagsExtF80.cc b/src/cpu/softfloat3e/s_addMagsExtF80.cc
new file mode 100644
index 000000000..5cc969198
--- /dev/null
+++ b/src/cpu/softfloat3e/s_addMagsExtF80.cc
@@ -0,0 +1,146 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+extFloat80_t softfloat_addMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB64, uint64_t uiB0, bool signZ, struct softfloat_status_t *status)
+{
+ int32_t expA;
+ uint64_t sigA;
+ int32_t expB;
+ uint64_t sigB;
+ int32_t expDiff;
+ uint64_t sigZ, sigZExtra;
+ struct exp32_sig64 normExpSig;
+ int32_t expZ;
+ struct uint64_extra sig64Extra;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expA = expExtF80UI64(uiA64);
+ sigA = uiA0;
+ expB = expExtF80UI64(uiB64);
+ sigB = uiB0;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expA == 0x7FFF) {
+ if ((sigA << 1) || ((expB == 0x7FFF) && (sigB << 1)))
+ goto propagateNaN;
+ if (sigB && ! expB)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToExtF80_twoargs(uiA64, uiA0);
+ }
+ if (expB == 0x7FFF) {
+ if (sigB << 1) goto propagateNaN;
+ if (sigA && ! expA)
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToExtF80(signZ, 0x7FFF, UINT64_C(0x8000000000000000));
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (! expA) {
+ if (! sigA) {
+ if (! expB && sigB) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
+ expB = normExpSig.exp + 1;
+ sigB = normExpSig.sig;
+ }
+ expZ = expB;
+ sigZ = sigB;
+ sigZExtra = 0;
+ goto roundAndPack;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
+ expA = normExpSig.exp + 1;
+ sigA = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expB == 0) {
+ if (sigB == 0) {
+ expZ = expA;
+ sigZ = sigA;
+ sigZExtra = 0;
+ goto roundAndPack;
+ }
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ normExpSig = softfloat_normSubnormalExtF80Sig(sigB);
+ expB = normExpSig.exp + 1;
+ sigB = normExpSig.sig;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expA - expB;
+ if (! expDiff) {
+ sigZ = sigA + sigB;
+ sigZExtra = 0;
+ expZ = expA;
+ goto shiftRight1;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (expDiff < 0) {
+ expZ = expB;
+ sig64Extra = softfloat_shiftRightJam64Extra(sigA, 0, -expDiff);
+ sigA = sig64Extra.v;
+ sigZExtra = sig64Extra.extra;
+ } else {
+ expZ = expA;
+ sig64Extra = softfloat_shiftRightJam64Extra(sigB, 0, expDiff);
+ sigB = sig64Extra.v;
+ sigZExtra = sig64Extra.extra;
+ }
+ sigZ = sigA + sigB;
+ if (sigZ & UINT64_C(0x8000000000000000)) goto roundAndPack;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ shiftRight1:
+ sig64Extra = softfloat_shortShiftRightJam64Extra(sigZ, sigZExtra, 1);
+ sigZ = sig64Extra.v | UINT64_C(0x8000000000000000);
+ sigZExtra = sig64Extra.extra;
+ ++expZ;
+ roundAndPack:
+ return softfloat_roundPackToExtF80(signZ, expZ, sigZ, sigZExtra, softfloat_extF80_roundingPrecision(status), status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNExtF80UI(uiA64, uiA0, uiB64, uiB0, status);
+}
diff --git a/src/cpu/softfloat3e/s_addMagsF128.cc b/src/cpu/softfloat3e/s_addMagsF128.cc
new file mode 100644
index 000000000..b831796cc
--- /dev/null
+++ b/src/cpu/softfloat3e/s_addMagsF128.cc
@@ -0,0 +1,138 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+
+float128_t softfloat_addMagsF128(uint64_t uiA64, uint64_t uiA0, uint64_t uiB64, uint64_t uiB0, bool signZ, struct softfloat_status_t *status)
+{
+ int32_t expA;
+ struct uint128 sigA;
+ int32_t expB;
+ struct uint128 sigB;
+ int32_t expDiff;
+ struct uint128 uiZ, sigZ;
+ int32_t expZ;
+ uint64_t sigZExtra;
+ struct uint128_extra sig128Extra;
+
+ expA = expF128UI64(uiA64);
+ sigA.v64 = fracF128UI64(uiA64);
+ sigA.v0 = uiA0;
+ expB = expF128UI64(uiB64);
+ sigB.v64 = fracF128UI64(uiB64);
+ sigB.v0 = uiB0;
+ expDiff = expA - expB;
+ if (! expDiff) {
+ if (expA == 0x7FFF) {
+ if (sigA.v64 | sigA.v0 | sigB.v64 | sigB.v0) goto propagateNaN;
+ uiZ.v64 = uiA64;
+ uiZ.v0 = uiA0;
+ return uiZ;
+ }
+ sigZ = softfloat_add128(sigA.v64, sigA.v0, sigB.v64, sigB.v0);
+ if (! expA) {
+ uiZ.v64 = packToF128UI64(signZ, 0, sigZ.v64);
+ uiZ.v0 = sigZ.v0;
+ return uiZ;
+ }
+ expZ = expA;
+ sigZ.v64 |= UINT64_C(0x0002000000000000);
+ sigZExtra = 0;
+ goto shiftRight1;
+ }
+ if (expDiff < 0) {
+ if (expB == 0x7FFF) {
+ if (sigB.v64 | sigB.v0) goto propagateNaN;
+ uiZ.v64 = packToF128UI64(signZ, 0x7FFF, 0);
+ uiZ.v0 = 0;
+ return uiZ;
+ }
+ expZ = expB;
+ if (expA) {
+ sigA.v64 |= UINT64_C(0x0001000000000000);
+ } else {
+ ++expDiff;
+ sigZExtra = 0;
+ if (! expDiff) goto newlyAligned;
+ }
+ sig128Extra =
+ softfloat_shiftRightJam128Extra(sigA.v64, sigA.v0, 0, -expDiff);
+ sigA = sig128Extra.v;
+ sigZExtra = sig128Extra.extra;
+ } else {
+ if (expA == 0x7FFF) {
+ if (sigA.v64 | sigA.v0) goto propagateNaN;
+ uiZ.v64 = uiA64;
+ uiZ.v0 = uiA0;
+ return uiZ;
+ }
+ expZ = expA;
+ if (expB) {
+ sigB.v64 |= UINT64_C(0x0001000000000000);
+ } else {
+ --expDiff;
+ sigZExtra = 0;
+ if (! expDiff) goto newlyAligned;
+ }
+ sig128Extra = softfloat_shiftRightJam128Extra(sigB.v64, sigB.v0, 0, expDiff);
+ sigB = sig128Extra.v;
+ sigZExtra = sig128Extra.extra;
+ }
+ newlyAligned:
+ sigZ =
+ softfloat_add128(
+ sigA.v64 | UINT64_C(0x0001000000000000),
+ sigA.v0,
+ sigB.v64,
+ sigB.v0
+ );
+ --expZ;
+ if (sigZ.v64 < UINT64_C(0x0002000000000000)) goto roundAndPack;
+ ++expZ;
+ shiftRight1:
+ sig128Extra = softfloat_shortShiftRightJam128Extra(sigZ.v64, sigZ.v0, sigZExtra, 1);
+ sigZ = sig128Extra.v;
+ sigZExtra = sig128Extra.extra;
+ roundAndPack:
+ return
+ softfloat_roundPackToF128(signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra, status);
+ propagateNaN:
+ uiZ = softfloat_propagateNaNF128UI(uiA64, uiA0, uiB64, uiB0, status);
+ return uiZ;
+}
diff --git a/src/cpu/softfloat3e/s_addMagsF16.c b/src/cpu/softfloat3e/s_addMagsF16.c
new file mode 100644
index 000000000..022f254a8
--- /dev/null
+++ b/src/cpu/softfloat3e/s_addMagsF16.c
@@ -0,0 +1,192 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
+University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+float16 softfloat_addMagsF16(uint16_t uiA, uint16_t uiB, struct softfloat_status_t *status)
+{
+ int8_t expA;
+ uint16_t sigA;
+ int8_t expB;
+ uint16_t sigB;
+ int8_t expDiff;
+ uint16_t uiZ;
+ bool signZ;
+ int8_t expZ;
+ uint16_t sigZ;
+ uint16_t sigX, sigY;
+ int8_t shiftDist;
+ uint32_t sig32Z;
+ int8_t roundingMode;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expA = expF16UI(uiA);
+ sigA = fracF16UI(uiA);
+ expB = expF16UI(uiB);
+ sigB = fracF16UI(uiB);
+ signZ = signF16UI(uiA);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) {
+ sigA = 0;
+ uiA = packToF16UI(signZ, 0, 0);
+ }
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expA - expB;
+ if (! expDiff) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (! expA) {
+ uiZ = uiA + sigB;
+ if (sigA | sigB) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ bool isTiny = (expF16UI(uiZ) == 0);
+ if (isTiny) {
+ if (softfloat_flushUnderflowToZero(status)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
+ return packToF16UI(signZ, 0, 0);
+ }
+ if (! softfloat_isMaskedException(status, softfloat_flag_underflow)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow);
+ }
+ }
+ }
+ return uiZ;
+ }
+ if (expA == 0x1F) {
+ if (sigA | sigB) goto propagateNaN;
+ return uiA;
+ }
+ expZ = expA;
+ sigZ = 0x0800 + sigA + sigB;
+ if (! (sigZ & 1) && (expZ < 0x1E)) {
+ sigZ >>= 1;
+ goto pack;
+ }
+ sigZ <<= 3;
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (expDiff < 0) {
+ /*----------------------------------------------------------------
+ *----------------------------------------------------------------*/
+ if (expB == 0x1F) {
+ if (sigB) goto propagateNaN;
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToF16UI(signZ, 0x1F, 0);
+ }
+
+ if ((!expA && sigA) || (!expB && sigB))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+
+ if (expDiff <= -13) {
+ uiZ = packToF16UI(signZ, expB, sigB);
+ if (expA | sigA) goto addEpsilon;
+ return uiZ;
+ }
+ expZ = expB;
+ sigX = sigB | 0x0400;
+ sigY = sigA + (expA ? 0x0400 : sigA);
+ shiftDist = 19 + expDiff;
+ } else {
+ /*----------------------------------------------------------------
+ *----------------------------------------------------------------*/
+ uiZ = uiA;
+ if (expA == 0x1F) {
+ if (sigA) goto propagateNaN;
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return uiZ;
+ }
+
+ if ((!expA && sigA) || (!expB && sigB))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+
+ if (13 <= expDiff) {
+ if (expB | sigB) goto addEpsilon;
+ return uiZ;
+ }
+ expZ = expA;
+ sigX = sigA | 0x0400;
+ sigY = sigB + (expB ? 0x0400 : sigB);
+ shiftDist = 19 - expDiff;
+ }
+ sig32Z = ((uint32_t) sigX<<19) + ((uint32_t) sigY<>16;
+ if (sig32Z & 0xFFFF) {
+ sigZ |= 1;
+ } else {
+ if (! (sigZ & 0xF) && (expZ < 0x1E)) {
+ sigZ >>= 4;
+ goto pack;
+ }
+ }
+ }
+ return softfloat_roundPackToF16(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF16UI(uiA, uiB, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ addEpsilon:
+ roundingMode = softfloat_getRoundingMode(status);
+ if (roundingMode != softfloat_round_near_even) {
+ if (roundingMode == (signF16UI(uiZ) ? softfloat_round_min : softfloat_round_max)) {
+ ++uiZ;
+ if ((uint16_t) (uiZ<<1) == 0xF800) {
+ softfloat_raiseFlags(status, softfloat_flag_overflow | softfloat_flag_inexact);
+ }
+ }
+ }
+ softfloat_raiseFlags(status, softfloat_flag_inexact);
+ return uiZ;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ pack:
+ return packToF16UI(signZ, expZ, sigZ);
+}
diff --git a/src/cpu/softfloat3e/s_addMagsF32.c b/src/cpu/softfloat3e/s_addMagsF32.c
new file mode 100644
index 000000000..df902348a
--- /dev/null
+++ b/src/cpu/softfloat3e/s_addMagsF32.c
@@ -0,0 +1,147 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+
+float32 softfloat_addMagsF32(uint32_t uiA, uint32_t uiB, struct softfloat_status_t *status)
+{
+ int16_t expA;
+ uint32_t sigA;
+ int16_t expB;
+ uint32_t sigB;
+ int16_t expDiff;
+ uint32_t uiZ;
+ bool signZ;
+ int16_t expZ;
+ uint32_t sigZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expA = expF32UI(uiA);
+ sigA = fracF32UI(uiA);
+ expB = expF32UI(uiB);
+ sigB = fracF32UI(uiB);
+ signZ = signF32UI(uiA);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) {
+ sigA = 0;
+ uiA = packToF32UI(signZ, 0, 0);
+ }
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expA - expB;
+ if (! expDiff) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (! expA) {
+ uiZ = uiA + sigB;
+ if (sigA | sigB) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ bool isTiny = (expF32UI(uiZ) == 0);
+ if (isTiny) {
+ if (softfloat_flushUnderflowToZero(status)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
+ return packToF32UI(signZ, 0, 0);
+ }
+ if (! softfloat_isMaskedException(status, softfloat_flag_underflow)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow);
+ }
+ }
+ }
+ return uiZ;
+ }
+ if (expA == 0xFF) {
+ if (sigA | sigB) goto propagateNaN;
+ return uiA;
+ }
+ expZ = expA;
+ sigZ = 0x01000000 + sigA + sigB;
+ if (! (sigZ & 1) && (expZ < 0xFE)) {
+ return packToF32UI(signZ, expZ, sigZ>>1);
+ }
+ sigZ <<= 6;
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ signZ = signF32UI(uiA);
+ sigA <<= 6;
+ sigB <<= 6;
+ if (expDiff < 0) {
+ if (expB == 0xFF) {
+ if (sigB) goto propagateNaN;
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToF32UI(signZ, 0xFF, 0);
+ }
+
+ if ((!expA && sigA) || (!expB && sigB))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+
+ expZ = expB;
+ sigA += expA ? 0x20000000 : sigA;
+ sigA = softfloat_shiftRightJam32(sigA, -expDiff);
+ } else {
+ if (expA == 0xFF) {
+ if (sigA) goto propagateNaN;
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return uiA;
+ }
+
+ if ((!expA && sigA) || (!expB && sigB))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+
+ expZ = expA;
+ sigB += expB ? 0x20000000 : sigB;
+ sigB = softfloat_shiftRightJam32(sigB, expDiff);
+ }
+ sigZ = 0x20000000 + sigA + sigB;
+ if (sigZ < 0x40000000) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ }
+ return softfloat_roundPackToF32(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF32UI(uiA, uiB, status);
+}
diff --git a/src/cpu/softfloat3e/s_addMagsF64.c b/src/cpu/softfloat3e/s_addMagsF64.c
new file mode 100644
index 000000000..a315860f6
--- /dev/null
+++ b/src/cpu/softfloat3e/s_addMagsF64.c
@@ -0,0 +1,149 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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
+#include
+#include "internals.h"
+#include "primitives.h"
+#include "specialize.h"
+
+float64 softfloat_addMagsF64(uint64_t uiA, uint64_t uiB, bool signZ, struct softfloat_status_t *status)
+{
+ int16_t expA;
+ uint64_t sigA;
+ int16_t expB;
+ uint64_t sigB;
+ int16_t expDiff;
+ uint64_t uiZ;
+ int16_t expZ;
+ uint64_t sigZ;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expA = expF64UI(uiA);
+ sigA = fracF64UI(uiA);
+ expB = expF64UI(uiB);
+ sigB = fracF64UI(uiB);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if (softfloat_denormalsAreZeros(status)) {
+ if (!expA) {
+ sigA = 0;
+ uiA = packToF64UI(signZ, 0, 0);
+ }
+ if (!expB) sigB = 0;
+ }
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ expDiff = expA - expB;
+ if (! expDiff) {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ if (! expA) {
+ uiZ = uiA + sigB;
+ if (sigA | sigB) {
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+ bool isTiny = (expF64UI(uiZ) == 0);
+ if (isTiny) {
+ if (softfloat_flushUnderflowToZero(status)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow | softfloat_flag_inexact);
+ return packToF64UI(signZ, 0, 0);
+ }
+ if (! softfloat_isMaskedException(status, softfloat_flag_underflow)) {
+ softfloat_raiseFlags(status, softfloat_flag_underflow);
+ }
+ }
+ }
+ return uiZ;
+ }
+ if (expA == 0x7FF) {
+ if (sigA | sigB) goto propagateNaN;
+ return uiA;
+ }
+ expZ = expA;
+ sigZ = UINT64_C(0x0020000000000000) + sigA + sigB;
+ sigZ <<= 9;
+ } else {
+ /*--------------------------------------------------------------------
+ *--------------------------------------------------------------------*/
+ sigA <<= 9;
+ sigB <<= 9;
+ if (expDiff < 0) {
+ if (expB == 0x7FF) {
+ if (sigB) goto propagateNaN;
+ if (sigA && !expA) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return packToF64UI(signZ, 0x7FF, 0);
+ }
+
+ if ((!expA && sigA) || (!expB && sigB))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+
+ expZ = expB;
+ if (expA) {
+ sigA += UINT64_C(0x2000000000000000);
+ } else {
+ sigA <<= 1;
+ }
+ sigA = softfloat_shiftRightJam64(sigA, -expDiff);
+ } else {
+ if (expA == 0x7FF) {
+ if (sigA) goto propagateNaN;
+ if (sigB && !expB) softfloat_raiseFlags(status, softfloat_flag_denormal);
+ return uiA;
+ }
+
+ if ((!expA && sigA) || (!expB && sigB))
+ softfloat_raiseFlags(status, softfloat_flag_denormal);
+
+ expZ = expA;
+ if (expB) {
+ sigB += UINT64_C(0x2000000000000000);
+ } else {
+ sigB <<= 1;
+ }
+ sigB = softfloat_shiftRightJam64(sigB, expDiff);
+ }
+ sigZ = UINT64_C(0x2000000000000000) + sigA + sigB;
+ if (sigZ < UINT64_C(0x4000000000000000)) {
+ --expZ;
+ sigZ <<= 1;
+ }
+ }
+ return softfloat_roundPackToF64(signZ, expZ, sigZ, status);
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ propagateNaN:
+ return softfloat_propagateNaNF64UI(uiA, uiB, status);
+}
diff --git a/src/cpu/softfloat3e/s_approxRecipSqrt32_1.c b/src/cpu/softfloat3e/s_approxRecipSqrt32_1.c
new file mode 100644
index 000000000..776c146ef
--- /dev/null
+++ b/src/cpu/softfloat3e/s_approxRecipSqrt32_1.c
@@ -0,0 +1,63 @@
+/*============================================================================
+
+This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
+Package, Release 3e, by John R. Hauser.
+
+Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
+California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions, and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the University 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 REGENTS 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 REGENTS 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