Browse Source

Remove lower_br_fcmp from the riscv64 backend (#5519)

Remove the lower_br_fcmp function from the riscv64 backend. This PR only affects the emit implementation for FloatRound, replacing the uses of lower_br_fcmp with direct uses of FpuRRR and CondBr.

Any changes in behavior here should be already covered by the runtests for ceil, floor, trunc, and nearest.
pull/5521/head
Trevor Elliott 2 years ago
committed by GitHub
parent
commit
e2e98f694f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 194
      cranelift/codegen/src/isa/riscv64/inst/emit.rs

194
cranelift/codegen/src/isa/riscv64/inst/emit.rs

@ -270,163 +270,6 @@ impl Inst {
} }
} }
pub(crate) fn lower_br_fcmp(
cc: FloatCC,
x: Reg,
y: Reg,
taken: BranchTarget,
not_taken: BranchTarget,
ty: Type,
tmp: Writable<Reg>,
) -> SmallInstVec<Inst> {
assert!(tmp.to_reg().class() == RegClass::Int);
let mut insts = SmallInstVec::new();
let mut cc_args = FloatCCArgs::from_floatcc(cc);
let eq_op = if ty == F32 {
FpuOPRRR::FeqS
} else {
FpuOPRRR::FeqD
};
let lt_op = if ty == F32 {
FpuOPRRR::FltS
} else {
FpuOPRRR::FltD
};
let le_op = if ty == F32 {
FpuOPRRR::FleS
} else {
FpuOPRRR::FleD
};
// >=
if cc_args.has_and_clear(FloatCCArgs::GT | FloatCCArgs::EQ) {
insts.push(Inst::FpuRRR {
frm: None,
alu_op: le_op,
rd: tmp,
rs1: y, // x and y order reversed.
rs2: x,
});
insts.push(Inst::CondBr {
taken: taken,
not_taken: BranchTarget::zero(),
kind: IntegerCompare {
kind: IntCC::NotEqual,
rs1: tmp.to_reg(),
rs2: zero_reg(),
},
});
}
// <=
if cc_args.has_and_clear(FloatCCArgs::LT | FloatCCArgs::EQ) {
insts.push(Inst::FpuRRR {
frm: None,
alu_op: le_op,
rd: tmp,
rs1: x,
rs2: y,
});
insts.push(Inst::CondBr {
taken: taken,
not_taken: BranchTarget::zero(),
kind: IntegerCompare {
kind: IntCC::NotEqual,
rs1: tmp.to_reg(),
rs2: zero_reg(),
},
});
}
// if eq
if cc_args.has_and_clear(FloatCCArgs::EQ) {
insts.push(Inst::FpuRRR {
frm: None,
alu_op: eq_op,
rd: tmp,
rs1: x,
rs2: y,
});
insts.push(Inst::CondBr {
taken: taken,
not_taken: BranchTarget::zero(),
kind: IntegerCompare {
kind: IntCC::NotEqual,
rs1: tmp.to_reg(),
rs2: zero_reg(),
},
});
}
// if ne
if cc_args.has_and_clear(FloatCCArgs::NE) {
insts.push(Inst::FpuRRR {
frm: None,
alu_op: eq_op,
rd: tmp,
rs1: x,
rs2: y,
});
insts.push(Inst::CondBr {
taken: taken,
not_taken: BranchTarget::zero(),
kind: IntegerCompare {
kind: IntCC::Equal,
rs1: tmp.to_reg(),
rs2: zero_reg(),
},
});
}
// if <
if cc_args.has_and_clear(FloatCCArgs::LT) {
insts.push(Inst::FpuRRR {
frm: None,
alu_op: lt_op,
rd: tmp,
rs1: x,
rs2: y,
});
insts.push(Inst::CondBr {
taken: taken,
not_taken: BranchTarget::zero(),
kind: IntegerCompare {
kind: IntCC::NotEqual,
rs1: tmp.to_reg(),
rs2: zero_reg(),
},
});
}
// if gt
if cc_args.has_and_clear(FloatCCArgs::GT) {
insts.push(Inst::FpuRRR {
frm: None,
alu_op: lt_op,
rd: tmp,
rs1: y, // x and y order reversed.
rs2: x,
});
insts.push(Inst::CondBr {
taken,
not_taken: BranchTarget::zero(),
kind: IntegerCompare {
kind: IntCC::NotEqual,
rs1: tmp.to_reg(),
rs2: zero_reg(),
},
});
}
// if unordered
if cc_args.has_and_clear(FloatCCArgs::UN) {
insts.extend(Inst::lower_float_unordered(tmp, ty, x, y, taken, not_taken));
} else {
//make sure we goto the not_taken.
//finally goto not_taken
insts.push(Inst::Jal { dest: not_taken });
}
// make sure we handle all cases.
assert!(cc_args.0 == 0);
insts
}
pub(crate) fn lower_br_icmp( pub(crate) fn lower_br_icmp(
cc: IntCC, cc: IntCC,
a: ValueRegs<Reg>, a: ValueRegs<Reg>,
@ -2186,18 +2029,31 @@ impl MachInstEmit for Inst {
// get abs value. // get abs value.
Inst::emit_fabs(rd, rs, ty).emit(&[], sink, emit_info, state); Inst::emit_fabs(rd, rs, ty).emit(&[], sink, emit_info, state);
Inst::lower_br_fcmp(
FloatCC::GreaterThan, // branch if f_tmp < rd
// abs value > max_value_need_round Inst::FpuRRR {
rd.to_reg(), frm: None,
f_tmp.to_reg(), alu_op: if ty == F32 {
BranchTarget::Label(label_x), FpuOPRRR::FltS
BranchTarget::zero(), } else {
ty, FpuOPRRR::FltD
int_tmp, },
) rd: int_tmp,
.into_iter() rs1: f_tmp.to_reg(),
.for_each(|i| i.emit(&[], sink, emit_info, state)); rs2: rd.to_reg(),
}
.emit(&[], sink, emit_info, state);
Inst::CondBr {
taken: BranchTarget::Label(label_x),
not_taken: BranchTarget::zero(),
kind: IntegerCompare {
kind: IntCC::NotEqual,
rs1: int_tmp.to_reg(),
rs2: zero_reg(),
},
}
.emit(&[], sink, emit_info, state);
//convert to int. //convert to int.
Inst::FpuRR { Inst::FpuRR {

Loading…
Cancel
Save