machinst x64: fix iconst emission
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user