Add vcode test for floating-point, and fix two FP bugs.
- Added a filetest for the vcode output of lowering every handled FP opcode.
- Fixed two bugs that were discovered while going through the lowerings:
- Saturating FP->int operators would return `u{32,64}::MIN` rather than
`0` for a NaN input.
- `fcopysign` did not mask off the sign bit of the value whose sign is
overwritten.
These probably would have been caught by Wasm conformance tests soon
(and the validity of these lowerings will ultimately be tested this way)
but let's get them right by inspection, too!
This commit is contained in:
@@ -2019,6 +2019,7 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(ctx: &mut C, insn: IRInst) {
|
||||
// MOV Xtmp1, Dinput0
|
||||
// MOV Xtmp2, Dinput1
|
||||
// AND Xtmp2, 0x8000_0000_0000_0000
|
||||
// BIC Xtmp1, 0x8000_0000_0000_0000
|
||||
// ORR Xtmp1, Xtmp1, Xtmp2
|
||||
// MOV Doutput, Xtmp1
|
||||
|
||||
@@ -2052,6 +2053,13 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(ctx: &mut C, insn: IRInst) {
|
||||
alu_op,
|
||||
rd: tmp2,
|
||||
rn: tmp2.to_reg(),
|
||||
imml: imml.clone(),
|
||||
});
|
||||
let alu_op = choose_32_64(ty, ALUOp::AndNot32, ALUOp::AndNot64);
|
||||
ctx.emit(Inst::AluRRImmLogic {
|
||||
alu_op,
|
||||
rd: tmp1,
|
||||
rn: tmp1.to_reg(),
|
||||
imml,
|
||||
});
|
||||
let alu_op = choose_32_64(ty, ALUOp::Orr32, ALUOp::Orr64);
|
||||
@@ -2127,6 +2135,7 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(ctx: &mut C, insn: IRInst) {
|
||||
// FMIN Vtmp2, Vin, Vtmp1
|
||||
// FIMM Vtmp1, 0 or 0 or i32::MIN or i64::MIN
|
||||
// FMAX Vtmp2, Vtmp2, Vtmp
|
||||
// (if signed) FIMM Vtmp1, 0
|
||||
// FCMP Vin, Vin
|
||||
// FCSEL Vtmp2, Vtmp1, Vtmp2, NE // on NaN, select 0
|
||||
// convert Rout, Vtmp2
|
||||
@@ -2187,6 +2196,19 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(ctx: &mut C, insn: IRInst) {
|
||||
rn: rtmp2.to_reg(),
|
||||
rm: rtmp1.to_reg(),
|
||||
});
|
||||
if out_signed {
|
||||
if in_bits == 32 {
|
||||
ctx.emit(Inst::LoadFpuConst32 {
|
||||
rd: rtmp1,
|
||||
const_data: 0.0,
|
||||
});
|
||||
} else {
|
||||
ctx.emit(Inst::LoadFpuConst64 {
|
||||
rd: rtmp1,
|
||||
const_data: 0.0,
|
||||
});
|
||||
}
|
||||
}
|
||||
if in_bits == 32 {
|
||||
ctx.emit(Inst::FpuCmp32 { rn: rn, rm: rn });
|
||||
ctx.emit(Inst::FpuCSel32 {
|
||||
|
||||
Reference in New Issue
Block a user