Merge pull request #2187 from akirilov-arm/ALUOp3
AArch64: Introduce an enum for ternary integer operations
This commit is contained in:
@@ -502,16 +502,8 @@ impl MachInstEmit for Inst {
|
||||
ALUOp::UDiv64 => 0b10011010_110,
|
||||
ALUOp::RotR32 | ALUOp::Lsr32 | ALUOp::Asr32 | ALUOp::Lsl32 => 0b00011010_110,
|
||||
ALUOp::RotR64 | ALUOp::Lsr64 | ALUOp::Asr64 | ALUOp::Lsl64 => 0b10011010_110,
|
||||
|
||||
ALUOp::MAdd32
|
||||
| ALUOp::MAdd64
|
||||
| ALUOp::MSub32
|
||||
| ALUOp::MSub64
|
||||
| ALUOp::SMulH
|
||||
| ALUOp::UMulH => {
|
||||
//// RRRR ops.
|
||||
panic!("Bad ALUOp {:?} in RRR form!", alu_op);
|
||||
}
|
||||
ALUOp::SMulH => 0b10011011_010,
|
||||
ALUOp::UMulH => 0b10011011_110,
|
||||
};
|
||||
let bit15_10 = match alu_op {
|
||||
ALUOp::SDiv64 => 0b000011,
|
||||
@@ -521,6 +513,7 @@ impl MachInstEmit for Inst {
|
||||
ALUOp::Asr32 | ALUOp::Asr64 => 0b001010,
|
||||
ALUOp::Lsl32 | ALUOp::Lsl64 => 0b001000,
|
||||
ALUOp::SubS64XR => 0b011000,
|
||||
ALUOp::SMulH | ALUOp::UMulH => 0b011111,
|
||||
_ => 0b000000,
|
||||
};
|
||||
debug_assert_ne!(writable_stack_reg(), rd);
|
||||
@@ -541,13 +534,10 @@ impl MachInstEmit for Inst {
|
||||
ra,
|
||||
} => {
|
||||
let (top11, bit15) = match alu_op {
|
||||
ALUOp::MAdd32 => (0b0_00_11011_000, 0),
|
||||
ALUOp::MSub32 => (0b0_00_11011_000, 1),
|
||||
ALUOp::MAdd64 => (0b1_00_11011_000, 0),
|
||||
ALUOp::MSub64 => (0b1_00_11011_000, 1),
|
||||
ALUOp::SMulH => (0b1_00_11011_010, 0),
|
||||
ALUOp::UMulH => (0b1_00_11011_110, 0),
|
||||
_ => unimplemented!("{:?}", alu_op),
|
||||
ALUOp3::MAdd32 => (0b0_00_11011_000, 0),
|
||||
ALUOp3::MSub32 => (0b0_00_11011_000, 1),
|
||||
ALUOp3::MAdd64 => (0b1_00_11011_000, 0),
|
||||
ALUOp3::MSub64 => (0b1_00_11011_000, 1),
|
||||
};
|
||||
sink.put4(enc_arith_rrrr(top11, rm, bit15, ra, rn, rd));
|
||||
}
|
||||
@@ -1005,7 +995,7 @@ impl MachInstEmit for Inst {
|
||||
}
|
||||
}
|
||||
}
|
||||
&Inst::Mov { rd, rm } => {
|
||||
&Inst::Mov64 { rd, rm } => {
|
||||
assert!(rd.to_reg().get_class() == rm.get_class());
|
||||
assert!(rm.get_class() == RegClass::I64);
|
||||
|
||||
|
||||
@@ -789,7 +789,7 @@ fn test_aarch64_binemit() {
|
||||
|
||||
insns.push((
|
||||
Inst::AluRRRR {
|
||||
alu_op: ALUOp::MAdd32,
|
||||
alu_op: ALUOp3::MAdd32,
|
||||
rd: writable_xreg(1),
|
||||
rn: xreg(2),
|
||||
rm: xreg(3),
|
||||
@@ -800,7 +800,7 @@ fn test_aarch64_binemit() {
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRRR {
|
||||
alu_op: ALUOp::MAdd64,
|
||||
alu_op: ALUOp3::MAdd64,
|
||||
rd: writable_xreg(1),
|
||||
rn: xreg(2),
|
||||
rm: xreg(3),
|
||||
@@ -811,7 +811,7 @@ fn test_aarch64_binemit() {
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRRR {
|
||||
alu_op: ALUOp::MSub32,
|
||||
alu_op: ALUOp3::MSub32,
|
||||
rd: writable_xreg(1),
|
||||
rn: xreg(2),
|
||||
rm: xreg(3),
|
||||
@@ -822,7 +822,7 @@ fn test_aarch64_binemit() {
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRRR {
|
||||
alu_op: ALUOp::MSub64,
|
||||
alu_op: ALUOp3::MSub64,
|
||||
rd: writable_xreg(1),
|
||||
rn: xreg(2),
|
||||
rm: xreg(3),
|
||||
@@ -832,23 +832,21 @@ fn test_aarch64_binemit() {
|
||||
"msub x1, x2, x3, x4",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRRR {
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::SMulH,
|
||||
rd: writable_xreg(1),
|
||||
rn: xreg(2),
|
||||
rm: xreg(3),
|
||||
ra: zero_reg(),
|
||||
},
|
||||
"417C439B",
|
||||
"smulh x1, x2, x3",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRRR {
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::UMulH,
|
||||
rd: writable_xreg(1),
|
||||
rn: xreg(2),
|
||||
rm: xreg(3),
|
||||
ra: zero_reg(),
|
||||
},
|
||||
"417CC39B",
|
||||
"umulh x1, x2, x3",
|
||||
@@ -1654,7 +1652,7 @@ fn test_aarch64_binemit() {
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::Mov {
|
||||
Inst::Mov64 {
|
||||
rd: writable_xreg(8),
|
||||
rm: xreg(9),
|
||||
},
|
||||
|
||||
@@ -73,14 +73,6 @@ pub enum ALUOp {
|
||||
SubS64,
|
||||
/// Sub, setting flags, using extended registers
|
||||
SubS64XR,
|
||||
/// Multiply-add
|
||||
MAdd32,
|
||||
/// Multiply-add
|
||||
MAdd64,
|
||||
/// Multiply-sub
|
||||
MSub32,
|
||||
/// Multiply-sub
|
||||
MSub64,
|
||||
/// Signed multiply, high-word result
|
||||
SMulH,
|
||||
/// Unsigned multiply, high-word result
|
||||
@@ -97,6 +89,19 @@ pub enum ALUOp {
|
||||
Lsl64,
|
||||
}
|
||||
|
||||
/// An ALU operation with three arguments.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum ALUOp3 {
|
||||
/// Multiply-add
|
||||
MAdd32,
|
||||
/// Multiply-add
|
||||
MAdd64,
|
||||
/// Multiply-sub
|
||||
MSub32,
|
||||
/// Multiply-sub
|
||||
MSub64,
|
||||
}
|
||||
|
||||
/// A floating-point unit (FPU) operation with one arg.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum FPUOp1 {
|
||||
@@ -433,7 +438,7 @@ pub enum Inst {
|
||||
},
|
||||
/// An ALU operation with three register sources and a register destination.
|
||||
AluRRRR {
|
||||
alu_op: ALUOp,
|
||||
alu_op: ALUOp3,
|
||||
rd: Writable<Reg>,
|
||||
rn: Reg,
|
||||
rm: Reg,
|
||||
@@ -571,7 +576,7 @@ pub enum Inst {
|
||||
/// A MOV instruction. These are encoded as ORR's (AluRRR form) but we
|
||||
/// keep them separate at the `Inst` level for better pretty-printing
|
||||
/// and faster `is_move()` logic.
|
||||
Mov {
|
||||
Mov64 {
|
||||
rd: Writable<Reg>,
|
||||
rm: Reg,
|
||||
},
|
||||
@@ -1149,7 +1154,7 @@ impl Inst {
|
||||
pub fn mov(to_reg: Writable<Reg>, from_reg: Reg) -> Inst {
|
||||
assert!(to_reg.to_reg().get_class() == from_reg.get_class());
|
||||
if from_reg.get_class() == RegClass::I64 {
|
||||
Inst::Mov {
|
||||
Inst::Mov64 {
|
||||
rd: to_reg,
|
||||
rm: from_reg,
|
||||
}
|
||||
@@ -1458,7 +1463,7 @@ fn aarch64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
|
||||
collector.add_def(rt2);
|
||||
pairmemarg_regs(mem, collector);
|
||||
}
|
||||
&Inst::Mov { rd, rm } => {
|
||||
&Inst::Mov64 { rd, rm } => {
|
||||
collector.add_def(rd);
|
||||
collector.add_use(rm);
|
||||
}
|
||||
@@ -1991,7 +1996,7 @@ fn aarch64_map_regs<RUM: RegUsageMapper>(inst: &mut Inst, mapper: &RUM) {
|
||||
map_def(mapper, rt2);
|
||||
map_pairmem(mapper, mem);
|
||||
}
|
||||
&mut Inst::Mov {
|
||||
&mut Inst::Mov64 {
|
||||
ref mut rd,
|
||||
ref mut rm,
|
||||
} => {
|
||||
@@ -2456,7 +2461,7 @@ impl MachInst for Inst {
|
||||
|
||||
fn is_move(&self) -> Option<(Writable<Reg>, Reg)> {
|
||||
match self {
|
||||
&Inst::Mov { rd, rm } => Some((rd, rm)),
|
||||
&Inst::Mov64 { rd, rm } => Some((rd, rm)),
|
||||
&Inst::FpuMove64 { rd, rn } => Some((rd, rn)),
|
||||
&Inst::FpuMove128 { rd, rn } => Some((rd, rn)),
|
||||
_ => None,
|
||||
@@ -2628,10 +2633,6 @@ impl Inst {
|
||||
ALUOp::SubS32 => ("subs", OperandSize::Size32),
|
||||
ALUOp::SubS64 => ("subs", OperandSize::Size64),
|
||||
ALUOp::SubS64XR => ("subs", OperandSize::Size64),
|
||||
ALUOp::MAdd32 => ("madd", OperandSize::Size32),
|
||||
ALUOp::MAdd64 => ("madd", OperandSize::Size64),
|
||||
ALUOp::MSub32 => ("msub", OperandSize::Size32),
|
||||
ALUOp::MSub64 => ("msub", OperandSize::Size64),
|
||||
ALUOp::SMulH => ("smulh", OperandSize::Size64),
|
||||
ALUOp::UMulH => ("umulh", OperandSize::Size64),
|
||||
ALUOp::SDiv64 => ("sdiv", OperandSize::Size64),
|
||||
@@ -2670,19 +2671,18 @@ impl Inst {
|
||||
rm,
|
||||
ra,
|
||||
} => {
|
||||
let (op, size) = op_name_size(alu_op);
|
||||
let four_args = alu_op != ALUOp::SMulH && alu_op != ALUOp::UMulH;
|
||||
let (op, size) = match alu_op {
|
||||
ALUOp3::MAdd32 => ("madd", OperandSize::Size32),
|
||||
ALUOp3::MAdd64 => ("madd", OperandSize::Size64),
|
||||
ALUOp3::MSub32 => ("msub", OperandSize::Size32),
|
||||
ALUOp3::MSub64 => ("msub", OperandSize::Size64),
|
||||
};
|
||||
let rd = show_ireg_sized(rd.to_reg(), mb_rru, size);
|
||||
let rn = show_ireg_sized(rn, mb_rru, size);
|
||||
let rm = show_ireg_sized(rm, mb_rru, size);
|
||||
let ra = show_ireg_sized(ra, mb_rru, size);
|
||||
if four_args {
|
||||
format!("{} {}, {}, {}, {}", op, rd, rn, rm, ra)
|
||||
} else {
|
||||
// smulh and umulh have Ra "hard-wired" to the zero register
|
||||
// and the canonical assembly form has only three regs.
|
||||
format!("{} {}, {}, {}", op, rd, rn, rm)
|
||||
}
|
||||
|
||||
format!("{} {}, {}, {}, {}", op, rd, rn, rm, ra)
|
||||
}
|
||||
&Inst::AluRRImm12 {
|
||||
alu_op,
|
||||
@@ -2878,7 +2878,7 @@ impl Inst {
|
||||
let mem = mem.show_rru_sized(mb_rru, /* size = */ 8);
|
||||
format!("ldp {}, {}, {}", rt, rt2, mem)
|
||||
}
|
||||
&Inst::Mov { rd, rm } => {
|
||||
&Inst::Mov64 { rd, rm } => {
|
||||
let rd = rd.to_reg().show_rru(mb_rru);
|
||||
let rm = rm.show_rru(mb_rru);
|
||||
format!("mov {}, {}", rd, rm)
|
||||
|
||||
@@ -212,7 +212,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
let rm = put_input_in_reg(ctx, inputs[1], NarrowValueMode::None);
|
||||
let ty = ty.unwrap();
|
||||
if !ty.is_vector() {
|
||||
let alu_op = choose_32_64(ty, ALUOp::MAdd32, ALUOp::MAdd64);
|
||||
let alu_op = choose_32_64(ty, ALUOp3::MAdd32, ALUOp3::MAdd64);
|
||||
ctx.emit(Inst::AluRRRR {
|
||||
alu_op,
|
||||
rd,
|
||||
@@ -349,19 +349,12 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
I64 => {
|
||||
let rn = put_input_in_reg(ctx, inputs[0], NarrowValueMode::None);
|
||||
let rm = put_input_in_reg(ctx, inputs[1], NarrowValueMode::None);
|
||||
let ra = zero_reg();
|
||||
let alu_op = if is_signed {
|
||||
ALUOp::SMulH
|
||||
} else {
|
||||
ALUOp::UMulH
|
||||
};
|
||||
ctx.emit(Inst::AluRRRR {
|
||||
alu_op,
|
||||
rd,
|
||||
rn,
|
||||
rm,
|
||||
ra,
|
||||
});
|
||||
ctx.emit(Inst::AluRRR { alu_op, rd, rn, rm });
|
||||
}
|
||||
I32 | I16 | I8 => {
|
||||
let narrow_mode = if is_signed {
|
||||
@@ -373,7 +366,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
let rm = put_input_in_reg(ctx, inputs[1], narrow_mode);
|
||||
let ra = zero_reg();
|
||||
ctx.emit(Inst::AluRRRR {
|
||||
alu_op: ALUOp::MAdd64,
|
||||
alu_op: ALUOp3::MAdd64,
|
||||
rd,
|
||||
rn,
|
||||
rm,
|
||||
@@ -462,7 +455,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
});
|
||||
|
||||
ctx.emit(Inst::AluRRRR {
|
||||
alu_op: ALUOp::MSub64,
|
||||
alu_op: ALUOp3::MSub64,
|
||||
rd: rd,
|
||||
rn: rd.to_reg(),
|
||||
rm: rm,
|
||||
|
||||
Reference in New Issue
Block a user