Browse Source

machinst x64: fix iconst emission

pull/2034/head
Benjamin Bouvier 4 years ago
parent
commit
fe7dd41435
  1. 21
      cranelift/codegen/src/isa/x64/inst/mod.rs
  2. 15
      cranelift/codegen/src/isa/x64/lower.rs

21
cranelift/codegen/src/isa/x64/inst/mod.rs

@ -273,15 +273,13 @@ pub enum Inst {
VirtualSPOffsetAdj { offset: i64 }, VirtualSPOffsetAdj { offset: i64 },
} }
// Handy constructors for Insts. pub(crate) fn low32_will_sign_extend_to_64(x: u64) -> bool {
// For various sizes, will some number of lowest bits sign extend to be the
// same as the whole value?
pub(crate) fn low32willSXto64(x: u64) -> bool {
let xs = x as i64; let xs = x as i64;
xs == ((xs << 32) >> 32) xs == ((xs << 32) >> 32)
} }
// Handy constructors for Insts.
impl Inst { impl Inst {
pub(crate) fn nop(len: u8) -> Self { pub(crate) fn nop(len: u8) -> Self {
debug_assert!(len <= 16); debug_assert!(len <= 16);
@ -337,7 +335,11 @@ impl Inst {
pub(crate) fn imm_r(dst_is_64: bool, simm64: u64, dst: Writable<Reg>) -> Inst { pub(crate) fn imm_r(dst_is_64: bool, simm64: u64, dst: Writable<Reg>) -> Inst {
debug_assert!(dst.to_reg().get_class() == RegClass::I64); debug_assert!(dst.to_reg().get_class() == RegClass::I64);
if !dst_is_64 { if !dst_is_64 {
debug_assert!(low32willSXto64(simm64)); debug_assert!(
low32_will_sign_extend_to_64(simm64),
"{} won't sign-extend to 64 bits!",
simm64
);
} }
Inst::Imm_R { Inst::Imm_R {
dst_is_64, dst_is_64,
@ -1309,10 +1311,11 @@ impl MachInst for Inst {
Inst::jmp_known(BranchTarget::Label(label)) Inst::jmp_known(BranchTarget::Label(label))
} }
fn gen_constant(to_reg: Writable<Reg>, value: u64, _: Type) -> SmallVec<[Self; 4]> { fn gen_constant(to_reg: Writable<Reg>, value: u64, ty: Type) -> SmallVec<[Self; 4]> {
let mut ret = SmallVec::new(); let mut ret = SmallVec::new();
let is64 = value > 0xffff_ffff; debug_assert!(ty.is_int(), "float constants NYI");
ret.push(Inst::imm_r(is64, value, to_reg)); let is_64 = ty == I64 && value > 0x7fffffff;
ret.push(Inst::imm_r(is_64, value, to_reg));
ret ret
} }

15
cranelift/codegen/src/isa/x64/lower.rs

@ -234,9 +234,7 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
match op { match op {
Opcode::Iconst => { Opcode::Iconst => {
if let Some(w64) = iri_to_u64_imm(ctx, insn) { if let Some(w64) = iri_to_u64_imm(ctx, insn) {
// Get exactly the bit pattern in 'w64' into the dest. No let dst_is_64 = w64 > 0x7fffffff;
// monkeying with sign extension etc.
let dst_is_64 = w64 > 0xFFFF_FFFF;
let dst = output_to_reg(ctx, outputs[0]); let dst = output_to_reg(ctx, outputs[0]);
ctx.emit(Inst::imm_r(dst_is_64, w64, dst)); ctx.emit(Inst::imm_r(dst_is_64, w64, dst));
} else { } else {
@ -421,15 +419,8 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
for i in 0..ctx.num_inputs(insn) { for i in 0..ctx.num_inputs(insn) {
let src_reg = input_to_reg(ctx, inputs[i]); let src_reg = input_to_reg(ctx, inputs[i]);
let retval_reg = ctx.retval(i); let retval_reg = ctx.retval(i);
if src_reg.get_class() == RegClass::I64 { let ty = ctx.input_ty(insn, i);
ctx.emit(Inst::mov_r_r(true, src_reg, retval_reg)); ctx.emit(Inst::gen_move(retval_reg, src_reg, ty));
} else if src_reg.get_class() == RegClass::V128 {
ctx.emit(Inst::xmm_mov_rm_r(
SseOpcode::Movsd,
RegMem::reg(src_reg),
retval_reg,
));
}
} }
// N.B.: the Ret itself is generated by the ABI. // N.B.: the Ret itself is generated by the ABI.
} }

Loading…
Cancel
Save