diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs index 3b37581489..3e8b441b73 100644 --- a/cranelift/codegen/src/isa/x64/inst/emit.rs +++ b/cranelift/codegen/src/isa/x64/inst/emit.rs @@ -716,20 +716,22 @@ pub(crate) fn emit( } } - Inst::SignExtendAlAh => { - sink.put1(0x66); - sink.put1(0x98); - } - - Inst::SignExtendRaxRdx { size } => { - match size { - 2 => sink.put1(0x66), - 4 => {} - 8 => sink.put1(0x48), - _ => unreachable!(), + Inst::SignExtendData { size } => match size { + 1 => { + sink.put1(0x66); + sink.put1(0x98); } - sink.put1(0x99); - } + 2 => { + sink.put1(0x66); + sink.put1(0x99); + } + 4 => sink.put1(0x99), + 8 => { + sink.put1(0x48); + sink.put1(0x99); + } + _ => unreachable!(), + }, Inst::CheckedDivOrRemSeq { kind, @@ -825,10 +827,15 @@ pub(crate) fn emit( sink.bind_label(do_op); } + assert!( + *size > 1, + "CheckedDivOrRemSeq for i8 is not yet implemented" + ); + // Fill in the high parts: if kind.is_signed() { // sign-extend the sign-bit of rax into rdx, for signed opcodes. - let inst = Inst::sign_extend_rax_to_rdx(*size); + let inst = Inst::sign_extend_data(*size); inst.emit(sink, flags, state); } else { // zero for unsigned opcodes. diff --git a/cranelift/codegen/src/isa/x64/inst/emit_tests.rs b/cranelift/codegen/src/isa/x64/inst/emit_tests.rs index 8a65d3c729..9f7ea65b4b 100644 --- a/cranelift/codegen/src/isa/x64/inst/emit_tests.rs +++ b/cranelift/codegen/src/isa/x64/inst/emit_tests.rs @@ -1356,13 +1356,13 @@ fn test_x64_emit() { // ======================================================== // cbw - insns.push((Inst::sign_extend_al_to_ah(), "6698", "cbw")); + insns.push((Inst::sign_extend_data(1), "6698", "cbw")); // ======================================================== // cdq family: SignExtendRaxRdx - insns.push((Inst::sign_extend_rax_to_rdx(2), "6699", "cwd")); - insns.push((Inst::sign_extend_rax_to_rdx(4), "99", "cdq")); - insns.push((Inst::sign_extend_rax_to_rdx(8), "4899", "cqo")); + insns.push((Inst::sign_extend_data(2), "6699", "cwd")); + insns.push((Inst::sign_extend_data(4), "99", "cdq")); + insns.push((Inst::sign_extend_data(8), "4899", "cqo")); // ======================================================== // Imm_R diff --git a/cranelift/codegen/src/isa/x64/inst/mod.rs b/cranelift/codegen/src/isa/x64/inst/mod.rs index c069015da2..7c3a83e98f 100644 --- a/cranelift/codegen/src/isa/x64/inst/mod.rs +++ b/cranelift/codegen/src/isa/x64/inst/mod.rs @@ -100,11 +100,9 @@ pub enum Inst { loc: SourceLoc, }, - /// Do a sign-extend based on the sign of the value in al into ah: (cbw) - SignExtendAlAh, - /// Do a sign-extend based on the sign of the value in rax into rdx: (cwd cdq cqo) - SignExtendRaxRdx { + /// or al into ah: (cbw) + SignExtendData { size: u8, // 1, 2, 4 or 8 }, @@ -577,13 +575,9 @@ impl Inst { } } - pub(crate) fn sign_extend_al_to_ah() -> Inst { - Inst::SignExtendAlAh - } - - pub(crate) fn sign_extend_rax_to_rdx(size: u8) -> Inst { - debug_assert!(size == 8 || size == 4 || size == 2); - Inst::SignExtendRaxRdx { size } + pub(crate) fn sign_extend_data(size: u8) -> Inst { + debug_assert!(size == 8 || size == 4 || size == 2 || size == 1); + Inst::SignExtendData { size } } pub(crate) fn imm_r(dst_is_64: bool, simm64: u64, dst: Writable) -> Inst { @@ -1267,9 +1261,8 @@ impl ShowWithRRU for Inst { show_ireg_sized(divisor.to_reg(), mb_rru, *size), ), - Inst::SignExtendAlAh => "cbw".into(), - - Inst::SignExtendRaxRdx { size } => match size { + Inst::SignExtendData { size } => match size { + 1 => "cbw", 2 => "cwd", 4 => "cdq", 8 => "cqo", @@ -1722,13 +1715,14 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) { collector.add_def(*tmp); } } - Inst::SignExtendAlAh => { - collector.add_mod(Writable::from_reg(regs::rax())); - } - Inst::SignExtendRaxRdx { .. } => { - collector.add_use(regs::rax()); - collector.add_def(Writable::from_reg(regs::rdx())); - } + Inst::SignExtendData { size } => match size { + 1 => collector.add_mod(Writable::from_reg(regs::rax())), + 2 | 4 | 8 => { + collector.add_use(regs::rax()); + collector.add_def(Writable::from_reg(regs::rdx())); + } + _ => unreachable!(), + }, Inst::UnaryRmR { src, dst, .. } | Inst::XmmUnaryRmR { src, dst, .. } => { src.get_regs_as_uses(collector); collector.add_def(*dst); @@ -2029,7 +2023,7 @@ fn x64_map_regs(inst: &mut Inst, mapper: &RUM) { map_def(mapper, tmp) } } - Inst::SignExtendAlAh | Inst::SignExtendRaxRdx { .. } => {} + Inst::SignExtendData { .. } => {} Inst::XmmUnaryRmR { ref mut src, ref mut dst, diff --git a/cranelift/codegen/src/isa/x64/lower.rs b/cranelift/codegen/src/isa/x64/lower.rs index 16f2e1f45b..3e455a9688 100644 --- a/cranelift/codegen/src/isa/x64/lower.rs +++ b/cranelift/codegen/src/isa/x64/lower.rs @@ -2391,7 +2391,7 @@ fn lower_insn_to_regs>( if input_ty == types::I8 { if kind.is_signed() { // sign-extend the sign-bit of al into ah, for signed opcodes. - ctx.emit(Inst::sign_extend_al_to_ah()); + ctx.emit(Inst::sign_extend_data(1)); } else { ctx.emit(Inst::movzx_rm_r( ExtMode::BL, @@ -2403,7 +2403,7 @@ fn lower_insn_to_regs>( } else { if kind.is_signed() { // sign-extend the sign-bit of rax into rdx, for signed opcodes. - ctx.emit(Inst::sign_extend_rax_to_rdx(size)); + ctx.emit(Inst::sign_extend_data(size)); } else { // zero for unsigned opcodes. ctx.emit(Inst::imm_r(