Merge SignExtendAlAh and SignExtendRaxRdx

This commit is contained in:
bjorn3
2020-09-08 13:14:14 +02:00
committed by Benjamin Bouvier
parent 3dcda164dc
commit 9428480230
4 changed files with 43 additions and 42 deletions

View File

@@ -716,20 +716,22 @@ pub(crate) fn emit(
} }
} }
Inst::SignExtendAlAh => { Inst::SignExtendData { size } => match size {
sink.put1(0x66); 1 => {
sink.put1(0x98); sink.put1(0x66);
} sink.put1(0x98);
Inst::SignExtendRaxRdx { size } => {
match size {
2 => sink.put1(0x66),
4 => {}
8 => sink.put1(0x48),
_ => unreachable!(),
} }
sink.put1(0x99); 2 => {
} sink.put1(0x66);
sink.put1(0x99);
}
4 => sink.put1(0x99),
8 => {
sink.put1(0x48);
sink.put1(0x99);
}
_ => unreachable!(),
},
Inst::CheckedDivOrRemSeq { Inst::CheckedDivOrRemSeq {
kind, kind,
@@ -825,10 +827,15 @@ pub(crate) fn emit(
sink.bind_label(do_op); sink.bind_label(do_op);
} }
assert!(
*size > 1,
"CheckedDivOrRemSeq for i8 is not yet implemented"
);
// Fill in the high parts: // Fill in the high parts:
if kind.is_signed() { if kind.is_signed() {
// sign-extend the sign-bit of rax into rdx, for signed opcodes. // 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); inst.emit(sink, flags, state);
} else { } else {
// zero for unsigned opcodes. // zero for unsigned opcodes.

View File

@@ -1356,13 +1356,13 @@ fn test_x64_emit() {
// ======================================================== // ========================================================
// cbw // cbw
insns.push((Inst::sign_extend_al_to_ah(), "6698", "cbw")); insns.push((Inst::sign_extend_data(1), "6698", "cbw"));
// ======================================================== // ========================================================
// cdq family: SignExtendRaxRdx // cdq family: SignExtendRaxRdx
insns.push((Inst::sign_extend_rax_to_rdx(2), "6699", "cwd")); insns.push((Inst::sign_extend_data(2), "6699", "cwd"));
insns.push((Inst::sign_extend_rax_to_rdx(4), "99", "cdq")); insns.push((Inst::sign_extend_data(4), "99", "cdq"));
insns.push((Inst::sign_extend_rax_to_rdx(8), "4899", "cqo")); insns.push((Inst::sign_extend_data(8), "4899", "cqo"));
// ======================================================== // ========================================================
// Imm_R // Imm_R

View File

@@ -100,11 +100,9 @@ pub enum Inst {
loc: SourceLoc, 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) /// 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 size: u8, // 1, 2, 4 or 8
}, },
@@ -577,13 +575,9 @@ impl Inst {
} }
} }
pub(crate) fn sign_extend_al_to_ah() -> Inst { pub(crate) fn sign_extend_data(size: u8) -> Inst {
Inst::SignExtendAlAh debug_assert!(size == 8 || size == 4 || size == 2 || size == 1);
} Inst::SignExtendData { size }
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 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 {
@@ -1267,9 +1261,8 @@ impl ShowWithRRU for Inst {
show_ireg_sized(divisor.to_reg(), mb_rru, *size), show_ireg_sized(divisor.to_reg(), mb_rru, *size),
), ),
Inst::SignExtendAlAh => "cbw".into(), Inst::SignExtendData { size } => match size {
1 => "cbw",
Inst::SignExtendRaxRdx { size } => match size {
2 => "cwd", 2 => "cwd",
4 => "cdq", 4 => "cdq",
8 => "cqo", 8 => "cqo",
@@ -1722,13 +1715,14 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
collector.add_def(*tmp); collector.add_def(*tmp);
} }
} }
Inst::SignExtendAlAh => { Inst::SignExtendData { size } => match size {
collector.add_mod(Writable::from_reg(regs::rax())); 1 => collector.add_mod(Writable::from_reg(regs::rax())),
} 2 | 4 | 8 => {
Inst::SignExtendRaxRdx { .. } => { collector.add_use(regs::rax());
collector.add_use(regs::rax()); collector.add_def(Writable::from_reg(regs::rdx()));
collector.add_def(Writable::from_reg(regs::rdx())); }
} _ => unreachable!(),
},
Inst::UnaryRmR { src, dst, .. } | Inst::XmmUnaryRmR { src, dst, .. } => { Inst::UnaryRmR { src, dst, .. } | Inst::XmmUnaryRmR { src, dst, .. } => {
src.get_regs_as_uses(collector); src.get_regs_as_uses(collector);
collector.add_def(*dst); collector.add_def(*dst);
@@ -2029,7 +2023,7 @@ fn x64_map_regs<RUM: RegUsageMapper>(inst: &mut Inst, mapper: &RUM) {
map_def(mapper, tmp) map_def(mapper, tmp)
} }
} }
Inst::SignExtendAlAh | Inst::SignExtendRaxRdx { .. } => {} Inst::SignExtendData { .. } => {}
Inst::XmmUnaryRmR { Inst::XmmUnaryRmR {
ref mut src, ref mut src,
ref mut dst, ref mut dst,

View File

@@ -2391,7 +2391,7 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
if input_ty == types::I8 { if input_ty == types::I8 {
if kind.is_signed() { if kind.is_signed() {
// sign-extend the sign-bit of al into ah, for signed opcodes. // 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 { } else {
ctx.emit(Inst::movzx_rm_r( ctx.emit(Inst::movzx_rm_r(
ExtMode::BL, ExtMode::BL,
@@ -2403,7 +2403,7 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
} else { } else {
if kind.is_signed() { if kind.is_signed() {
// sign-extend the sign-bit of rax into rdx, for signed opcodes. // 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 { } else {
// zero for unsigned opcodes. // zero for unsigned opcodes.
ctx.emit(Inst::imm_r( ctx.emit(Inst::imm_r(