[AArch64] Refactor Mov instructions (#4033)
Merge Mov32 and Mov64 into a single instruction parameterized by a new OperandSize field. Also combine the Mov[K,N,Z] into a single instruction with a new opcode to select between the operations. Copyright (c) 2022, Arm Limited.
This commit is contained in:
@@ -156,33 +156,18 @@
|
||||
(mem PairAMode)
|
||||
(flags MemFlags))
|
||||
|
||||
;; 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.
|
||||
(Mov64
|
||||
;; A MOV instruction. These are encoded as ORR's (AluRRR form).
|
||||
;; The 32-bit version zeroes the top 32 bits of the
|
||||
;; destination, which is effectively an alias for an unsigned
|
||||
;; 32-to-64-bit extension.
|
||||
(Mov
|
||||
(size OperandSize)
|
||||
(rd WritableReg)
|
||||
(rm Reg))
|
||||
|
||||
;; A 32-bit MOV. Zeroes the top 32 bits of the destination. This is
|
||||
;; effectively an alias for an unsigned 32-to-64-bit extension.
|
||||
(Mov32
|
||||
(rd WritableReg)
|
||||
(rm Reg))
|
||||
|
||||
;; A MOVZ with a 16-bit immediate.
|
||||
(MovZ
|
||||
(rd WritableReg)
|
||||
(imm MoveWideConst)
|
||||
(size OperandSize))
|
||||
|
||||
;; A MOVN with a 16-bit immediate.
|
||||
(MovN
|
||||
(rd WritableReg)
|
||||
(imm MoveWideConst)
|
||||
(size OperandSize))
|
||||
|
||||
;; A MOVK with a 16-bit immediate.
|
||||
(MovK
|
||||
;; A MOV[Z,N,K] with a 16-bit immediate.
|
||||
(MovWide
|
||||
(op MoveWideOp)
|
||||
(rd WritableReg)
|
||||
(imm MoveWideConst)
|
||||
(size OperandSize))
|
||||
@@ -841,6 +826,13 @@
|
||||
(MSub)
|
||||
))
|
||||
|
||||
(type MoveWideOp
|
||||
(enum
|
||||
(MovZ)
|
||||
(MovN)
|
||||
(MovK)
|
||||
))
|
||||
|
||||
(type UImm5 (primitive UImm5))
|
||||
(type Imm12 (primitive Imm12))
|
||||
(type ImmLogic (primitive ImmLogic))
|
||||
@@ -1361,14 +1353,14 @@
|
||||
(decl movz (MoveWideConst OperandSize) Reg)
|
||||
(rule (movz imm size)
|
||||
(let ((dst WritableReg (temp_writable_reg $I64))
|
||||
(_ Unit (emit (MInst.MovZ dst imm size))))
|
||||
(_ Unit (emit (MInst.MovWide (MoveWideOp.MovZ) dst imm size))))
|
||||
dst))
|
||||
|
||||
;; Helper for emitting `MInst.MovN` instructions.
|
||||
(decl movn (MoveWideConst OperandSize) Reg)
|
||||
(rule (movn imm size)
|
||||
(let ((dst WritableReg (temp_writable_reg $I64))
|
||||
(_ Unit (emit (MInst.MovN dst imm size))))
|
||||
(_ Unit (emit (MInst.MovWide (MoveWideOp.MovN) dst imm size))))
|
||||
dst))
|
||||
|
||||
;; Helper for emitting `MInst.AluRRImmLogic` instructions.
|
||||
|
||||
@@ -185,25 +185,16 @@ fn enc_conditional_br(
|
||||
}
|
||||
}
|
||||
|
||||
const MOVE_WIDE_FIXED: u32 = 0x12800000;
|
||||
|
||||
#[repr(u32)]
|
||||
enum MoveWideOpcode {
|
||||
MOVN = 0b00,
|
||||
MOVZ = 0b10,
|
||||
MOVK = 0b11,
|
||||
}
|
||||
|
||||
fn enc_move_wide(
|
||||
op: MoveWideOpcode,
|
||||
rd: Writable<Reg>,
|
||||
imm: MoveWideConst,
|
||||
size: OperandSize,
|
||||
) -> u32 {
|
||||
fn enc_move_wide(op: MoveWideOp, rd: Writable<Reg>, imm: MoveWideConst, size: OperandSize) -> u32 {
|
||||
assert!(imm.shift <= 0b11);
|
||||
MOVE_WIDE_FIXED
|
||||
let op = match op {
|
||||
MoveWideOp::MovN => 0b00,
|
||||
MoveWideOp::MovZ => 0b10,
|
||||
MoveWideOp::MovK => 0b11,
|
||||
};
|
||||
0x12800000
|
||||
| size.sf_bit() << 31
|
||||
| (op as u32) << 29
|
||||
| op << 29
|
||||
| u32::from(imm.shift) << 21
|
||||
| u32::from(imm.bits) << 5
|
||||
| machreg_to_gpr(rd.to_reg())
|
||||
@@ -1315,51 +1306,45 @@ impl MachInstEmit for Inst {
|
||||
}
|
||||
}
|
||||
}
|
||||
&Inst::Mov64 { rd, rm } => {
|
||||
&Inst::Mov { size, rd, rm } => {
|
||||
let rd = allocs.next_writable(rd);
|
||||
let rm = allocs.next(rm);
|
||||
assert!(rd.to_reg().class() == rm.class());
|
||||
assert!(rm.class() == RegClass::Int);
|
||||
|
||||
// MOV to SP is interpreted as MOV to XZR instead. And our codegen
|
||||
// should never MOV to XZR.
|
||||
assert!(rd.to_reg() != stack_reg());
|
||||
match size {
|
||||
OperandSize::Size64 => {
|
||||
// MOV to SP is interpreted as MOV to XZR instead. And our codegen
|
||||
// should never MOV to XZR.
|
||||
assert!(rd.to_reg() != stack_reg());
|
||||
|
||||
if rm == stack_reg() {
|
||||
// We can't use ORR here, so use an `add rd, sp, #0` instead.
|
||||
let imm12 = Imm12::maybe_from_u64(0).unwrap();
|
||||
sink.put4(enc_arith_rr_imm12(
|
||||
0b100_10001,
|
||||
imm12.shift_bits(),
|
||||
imm12.imm_bits(),
|
||||
rm,
|
||||
rd,
|
||||
));
|
||||
} else {
|
||||
// Encoded as ORR rd, rm, zero.
|
||||
sink.put4(enc_arith_rrr(0b10101010_000, 0b000_000, rd, zero_reg(), rm));
|
||||
if rm == stack_reg() {
|
||||
// We can't use ORR here, so use an `add rd, sp, #0` instead.
|
||||
let imm12 = Imm12::maybe_from_u64(0).unwrap();
|
||||
sink.put4(enc_arith_rr_imm12(
|
||||
0b100_10001,
|
||||
imm12.shift_bits(),
|
||||
imm12.imm_bits(),
|
||||
rm,
|
||||
rd,
|
||||
));
|
||||
} else {
|
||||
// Encoded as ORR rd, rm, zero.
|
||||
sink.put4(enc_arith_rrr(0b10101010_000, 0b000_000, rd, zero_reg(), rm));
|
||||
}
|
||||
}
|
||||
OperandSize::Size32 => {
|
||||
// MOV to SP is interpreted as MOV to XZR instead. And our codegen
|
||||
// should never MOV to XZR.
|
||||
assert!(machreg_to_gpr(rd.to_reg()) != 31);
|
||||
// Encoded as ORR rd, rm, zero.
|
||||
sink.put4(enc_arith_rrr(0b00101010_000, 0b000_000, rd, zero_reg(), rm));
|
||||
}
|
||||
}
|
||||
}
|
||||
&Inst::Mov32 { rd, rm } => {
|
||||
&Inst::MovWide { op, rd, imm, size } => {
|
||||
let rd = allocs.next_writable(rd);
|
||||
let rm = allocs.next(rm);
|
||||
// MOV to SP is interpreted as MOV to XZR instead. And our codegen
|
||||
// should never MOV to XZR.
|
||||
assert!(machreg_to_gpr(rd.to_reg()) != 31);
|
||||
// Encoded as ORR rd, rm, zero.
|
||||
sink.put4(enc_arith_rrr(0b00101010_000, 0b000_000, rd, zero_reg(), rm));
|
||||
}
|
||||
&Inst::MovZ { rd, imm, size } => {
|
||||
let rd = allocs.next_writable(rd);
|
||||
sink.put4(enc_move_wide(MoveWideOpcode::MOVZ, rd, imm, size))
|
||||
}
|
||||
&Inst::MovN { rd, imm, size } => {
|
||||
let rd = allocs.next_writable(rd);
|
||||
sink.put4(enc_move_wide(MoveWideOpcode::MOVN, rd, imm, size))
|
||||
}
|
||||
&Inst::MovK { rd, imm, size } => {
|
||||
let rd = allocs.next_writable(rd);
|
||||
sink.put4(enc_move_wide(MoveWideOpcode::MOVK, rd, imm, size))
|
||||
sink.put4(enc_move_wide(op, rd, imm, size));
|
||||
}
|
||||
&Inst::CSel { rd, rn, rm, cond } => {
|
||||
let rd = allocs.next_writable(rd);
|
||||
@@ -2700,7 +2685,11 @@ impl MachInstEmit for Inst {
|
||||
} => {
|
||||
let rd = allocs.next_writable(rd);
|
||||
let rn = allocs.next(rn);
|
||||
let mov = Inst::Mov32 { rd, rm: rn };
|
||||
let mov = Inst::Mov {
|
||||
size: OperandSize::Size32,
|
||||
rd,
|
||||
rm: rn,
|
||||
};
|
||||
mov.emit(&[], sink, emit_info, state);
|
||||
}
|
||||
&Inst::Extend {
|
||||
@@ -2980,7 +2969,11 @@ impl MachInstEmit for Inst {
|
||||
add.emit(&[], sink, emit_info, state);
|
||||
} else if offset == 0 {
|
||||
if reg != rd.to_reg() {
|
||||
let mov = Inst::Mov64 { rd, rm: reg };
|
||||
let mov = Inst::Mov {
|
||||
size: OperandSize::Size64,
|
||||
rd,
|
||||
rm: reg,
|
||||
};
|
||||
|
||||
mov.emit(&[], sink, emit_info, state);
|
||||
}
|
||||
|
||||
@@ -1920,7 +1920,8 @@ fn test_aarch64_binemit() {
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::Mov64 {
|
||||
Inst::Mov {
|
||||
size: OperandSize::Size64,
|
||||
rd: writable_xreg(8),
|
||||
rm: xreg(9),
|
||||
},
|
||||
@@ -1928,7 +1929,8 @@ fn test_aarch64_binemit() {
|
||||
"mov x8, x9",
|
||||
));
|
||||
insns.push((
|
||||
Inst::Mov32 {
|
||||
Inst::Mov {
|
||||
size: OperandSize::Size32,
|
||||
rd: writable_xreg(8),
|
||||
rm: xreg(9),
|
||||
},
|
||||
@@ -1937,7 +1939,8 @@ fn test_aarch64_binemit() {
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::MovZ {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovZ,
|
||||
rd: writable_xreg(8),
|
||||
imm: MoveWideConst::maybe_from_u64(0x0000_0000_0000_ffff).unwrap(),
|
||||
size: OperandSize::Size64,
|
||||
@@ -1946,7 +1949,8 @@ fn test_aarch64_binemit() {
|
||||
"movz x8, #65535",
|
||||
));
|
||||
insns.push((
|
||||
Inst::MovZ {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovZ,
|
||||
rd: writable_xreg(8),
|
||||
imm: MoveWideConst::maybe_from_u64(0x0000_0000_ffff_0000).unwrap(),
|
||||
size: OperandSize::Size64,
|
||||
@@ -1955,7 +1959,8 @@ fn test_aarch64_binemit() {
|
||||
"movz x8, #65535, LSL #16",
|
||||
));
|
||||
insns.push((
|
||||
Inst::MovZ {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovZ,
|
||||
rd: writable_xreg(8),
|
||||
imm: MoveWideConst::maybe_from_u64(0x0000_ffff_0000_0000).unwrap(),
|
||||
size: OperandSize::Size64,
|
||||
@@ -1964,7 +1969,8 @@ fn test_aarch64_binemit() {
|
||||
"movz x8, #65535, LSL #32",
|
||||
));
|
||||
insns.push((
|
||||
Inst::MovZ {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovZ,
|
||||
rd: writable_xreg(8),
|
||||
imm: MoveWideConst::maybe_from_u64(0xffff_0000_0000_0000).unwrap(),
|
||||
size: OperandSize::Size64,
|
||||
@@ -1973,7 +1979,8 @@ fn test_aarch64_binemit() {
|
||||
"movz x8, #65535, LSL #48",
|
||||
));
|
||||
insns.push((
|
||||
Inst::MovZ {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovZ,
|
||||
rd: writable_xreg(8),
|
||||
imm: MoveWideConst::maybe_from_u64(0x0000_0000_ffff_0000).unwrap(),
|
||||
size: OperandSize::Size32,
|
||||
@@ -1983,7 +1990,8 @@ fn test_aarch64_binemit() {
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::MovN {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovN,
|
||||
rd: writable_xreg(8),
|
||||
imm: MoveWideConst::maybe_from_u64(0x0000_0000_0000_ffff).unwrap(),
|
||||
size: OperandSize::Size64,
|
||||
@@ -1992,7 +2000,8 @@ fn test_aarch64_binemit() {
|
||||
"movn x8, #65535",
|
||||
));
|
||||
insns.push((
|
||||
Inst::MovN {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovN,
|
||||
rd: writable_xreg(8),
|
||||
imm: MoveWideConst::maybe_from_u64(0x0000_0000_ffff_0000).unwrap(),
|
||||
size: OperandSize::Size64,
|
||||
@@ -2001,7 +2010,8 @@ fn test_aarch64_binemit() {
|
||||
"movn x8, #65535, LSL #16",
|
||||
));
|
||||
insns.push((
|
||||
Inst::MovN {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovN,
|
||||
rd: writable_xreg(8),
|
||||
imm: MoveWideConst::maybe_from_u64(0x0000_ffff_0000_0000).unwrap(),
|
||||
size: OperandSize::Size64,
|
||||
@@ -2010,7 +2020,8 @@ fn test_aarch64_binemit() {
|
||||
"movn x8, #65535, LSL #32",
|
||||
));
|
||||
insns.push((
|
||||
Inst::MovN {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovN,
|
||||
rd: writable_xreg(8),
|
||||
imm: MoveWideConst::maybe_from_u64(0xffff_0000_0000_0000).unwrap(),
|
||||
size: OperandSize::Size64,
|
||||
@@ -2019,7 +2030,8 @@ fn test_aarch64_binemit() {
|
||||
"movn x8, #65535, LSL #48",
|
||||
));
|
||||
insns.push((
|
||||
Inst::MovN {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovN,
|
||||
rd: writable_xreg(8),
|
||||
imm: MoveWideConst::maybe_from_u64(0x0000_0000_0000_ffff).unwrap(),
|
||||
size: OperandSize::Size32,
|
||||
@@ -2029,7 +2041,8 @@ fn test_aarch64_binemit() {
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::MovK {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovK,
|
||||
rd: writable_xreg(12),
|
||||
imm: MoveWideConst::maybe_from_u64(0x0000_0000_0000_0000).unwrap(),
|
||||
size: OperandSize::Size64,
|
||||
@@ -2038,7 +2051,8 @@ fn test_aarch64_binemit() {
|
||||
"movk x12, #0",
|
||||
));
|
||||
insns.push((
|
||||
Inst::MovK {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovK,
|
||||
rd: writable_xreg(19),
|
||||
imm: MoveWideConst::maybe_with_shift(0x0000, 16).unwrap(),
|
||||
size: OperandSize::Size64,
|
||||
@@ -2047,7 +2061,8 @@ fn test_aarch64_binemit() {
|
||||
"movk x19, #0, LSL #16",
|
||||
));
|
||||
insns.push((
|
||||
Inst::MovK {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovK,
|
||||
rd: writable_xreg(3),
|
||||
imm: MoveWideConst::maybe_from_u64(0x0000_0000_0000_ffff).unwrap(),
|
||||
size: OperandSize::Size64,
|
||||
@@ -2056,7 +2071,8 @@ fn test_aarch64_binemit() {
|
||||
"movk x3, #65535",
|
||||
));
|
||||
insns.push((
|
||||
Inst::MovK {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovK,
|
||||
rd: writable_xreg(8),
|
||||
imm: MoveWideConst::maybe_from_u64(0x0000_0000_ffff_0000).unwrap(),
|
||||
size: OperandSize::Size64,
|
||||
@@ -2065,7 +2081,8 @@ fn test_aarch64_binemit() {
|
||||
"movk x8, #65535, LSL #16",
|
||||
));
|
||||
insns.push((
|
||||
Inst::MovK {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovK,
|
||||
rd: writable_xreg(8),
|
||||
imm: MoveWideConst::maybe_from_u64(0x0000_ffff_0000_0000).unwrap(),
|
||||
size: OperandSize::Size64,
|
||||
@@ -2074,7 +2091,8 @@ fn test_aarch64_binemit() {
|
||||
"movk x8, #65535, LSL #32",
|
||||
));
|
||||
insns.push((
|
||||
Inst::MovK {
|
||||
Inst::MovWide {
|
||||
op: MoveWideOp::MovK,
|
||||
rd: writable_xreg(8),
|
||||
imm: MoveWideConst::maybe_from_u64(0xffff_0000_0000_0000).unwrap(),
|
||||
size: OperandSize::Size64,
|
||||
|
||||
@@ -40,8 +40,8 @@ mod emit_tests;
|
||||
|
||||
pub use crate::isa::aarch64::lower::isle::generated_code::{
|
||||
ALUOp, ALUOp3, AtomicRMWOp, BitOp, FPUOp1, FPUOp2, FPUOp3, FpuRoundMode, FpuToIntOp,
|
||||
IntToFpuOp, MInst as Inst, VecALUOp, VecExtendOp, VecLanesOp, VecMisc2, VecPairOp, VecRRLongOp,
|
||||
VecRRNarrowOp, VecRRPairLongOp, VecRRRLongOp, VecShiftImmOp,
|
||||
IntToFpuOp, MInst as Inst, MoveWideOp, VecALUOp, VecExtendOp, VecLanesOp, VecMisc2, VecPairOp,
|
||||
VecRRLongOp, VecRRNarrowOp, VecRRPairLongOp, VecRRRLongOp, VecShiftImmOp,
|
||||
};
|
||||
|
||||
/// A floating-point unit (FPU) operation with two args, a register and an immediate.
|
||||
@@ -130,14 +130,16 @@ impl Inst {
|
||||
|
||||
if let Some(imm) = MoveWideConst::maybe_from_u64(value) {
|
||||
// 16-bit immediate (shifted by 0, 16, 32 or 48 bits) in MOVZ
|
||||
smallvec![Inst::MovZ {
|
||||
smallvec![Inst::MovWide {
|
||||
op: MoveWideOp::MovZ,
|
||||
rd,
|
||||
imm,
|
||||
size: OperandSize::Size64
|
||||
}]
|
||||
} else if let Some(imm) = MoveWideConst::maybe_from_u64(!value) {
|
||||
// 16-bit immediate (shifted by 0, 16, 32 or 48 bits) in MOVN
|
||||
smallvec![Inst::MovN {
|
||||
smallvec![Inst::MovWide {
|
||||
op: MoveWideOp::MovN,
|
||||
rd,
|
||||
imm,
|
||||
size: OperandSize::Size64
|
||||
@@ -178,15 +180,30 @@ impl Inst {
|
||||
let imm =
|
||||
MoveWideConst::maybe_with_shift(((!imm16) & 0xffff) as u16, i * 16)
|
||||
.unwrap();
|
||||
insts.push(Inst::MovN { rd, imm, size });
|
||||
insts.push(Inst::MovWide {
|
||||
op: MoveWideOp::MovN,
|
||||
rd,
|
||||
imm,
|
||||
size,
|
||||
});
|
||||
} else {
|
||||
let imm =
|
||||
MoveWideConst::maybe_with_shift(imm16 as u16, i * 16).unwrap();
|
||||
insts.push(Inst::MovZ { rd, imm, size });
|
||||
insts.push(Inst::MovWide {
|
||||
op: MoveWideOp::MovZ,
|
||||
rd,
|
||||
imm,
|
||||
size,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
let imm = MoveWideConst::maybe_with_shift(imm16 as u16, i * 16).unwrap();
|
||||
insts.push(Inst::MovK { rd, imm, size });
|
||||
insts.push(Inst::MovWide {
|
||||
op: MoveWideOp::MovK,
|
||||
rd,
|
||||
imm,
|
||||
size,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -641,20 +658,14 @@ fn aarch64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut Operan
|
||||
collector.reg_def(rt2);
|
||||
pairmemarg_operands(mem, collector);
|
||||
}
|
||||
&Inst::Mov64 { rd, rm } => {
|
||||
&Inst::Mov { rd, rm, .. } => {
|
||||
collector.reg_def(rd);
|
||||
collector.reg_use(rm);
|
||||
}
|
||||
&Inst::Mov32 { rd, rm } => {
|
||||
collector.reg_def(rd);
|
||||
collector.reg_use(rm);
|
||||
}
|
||||
&Inst::MovZ { rd, .. } | &Inst::MovN { rd, .. } => {
|
||||
collector.reg_def(rd);
|
||||
}
|
||||
&Inst::MovK { rd, .. } => {
|
||||
collector.reg_mod(rd);
|
||||
}
|
||||
&Inst::MovWide { op, rd, .. } => match op {
|
||||
MoveWideOp::MovK => collector.reg_mod(rd),
|
||||
_ => collector.reg_def(rd),
|
||||
},
|
||||
&Inst::CSel { rd, rn, rm, .. } => {
|
||||
collector.reg_def(rd);
|
||||
collector.reg_use(rn);
|
||||
@@ -1043,7 +1054,11 @@ impl MachInst for Inst {
|
||||
|
||||
fn is_move(&self) -> Option<(Writable<Reg>, Reg)> {
|
||||
match self {
|
||||
&Inst::Mov64 { rd, rm } => Some((rd, rm)),
|
||||
&Inst::Mov {
|
||||
size: OperandSize::Size64,
|
||||
rd,
|
||||
rm,
|
||||
} => Some((rd, rm)),
|
||||
&Inst::FpuMove64 { rd, rn } => Some((rd, rn)),
|
||||
&Inst::FpuMove128 { rd, rn } => Some((rd, rn)),
|
||||
_ => None,
|
||||
@@ -1097,7 +1112,8 @@ impl MachInst for Inst {
|
||||
assert!(bits <= 128);
|
||||
assert!(to_reg.to_reg().class() == from_reg.class());
|
||||
match from_reg.class() {
|
||||
RegClass::Int => Inst::Mov64 {
|
||||
RegClass::Int => Inst::Mov {
|
||||
size: OperandSize::Size64,
|
||||
rd: to_reg,
|
||||
rm: from_reg,
|
||||
},
|
||||
@@ -1467,30 +1483,25 @@ impl Inst {
|
||||
let mem = mem.pretty_print_default();
|
||||
format!("ldp {}, {}, {}", rt, rt2, mem)
|
||||
}
|
||||
&Inst::Mov64 { rd, rm } => {
|
||||
let rd = pretty_print_ireg(rd.to_reg(), OperandSize::Size64, allocs);
|
||||
let rm = pretty_print_ireg(rm, OperandSize::Size64, allocs);
|
||||
&Inst::Mov { size, rd, rm } => {
|
||||
let rd = pretty_print_ireg(rd.to_reg(), size, allocs);
|
||||
let rm = pretty_print_ireg(rm, size, allocs);
|
||||
format!("mov {}, {}", rd, rm)
|
||||
}
|
||||
&Inst::Mov32 { rd, rm } => {
|
||||
let rd = pretty_print_ireg(rd.to_reg(), OperandSize::Size32, allocs);
|
||||
let rm = pretty_print_ireg(rm, OperandSize::Size32, allocs);
|
||||
format!("mov {}, {}", rd, rm)
|
||||
}
|
||||
&Inst::MovZ { rd, ref imm, size } => {
|
||||
&Inst::MovWide {
|
||||
op,
|
||||
rd,
|
||||
ref imm,
|
||||
size,
|
||||
} => {
|
||||
let op_str = match op {
|
||||
MoveWideOp::MovZ => "movz",
|
||||
MoveWideOp::MovN => "movn",
|
||||
MoveWideOp::MovK => "movk",
|
||||
};
|
||||
let rd = pretty_print_ireg(rd.to_reg(), size, allocs);
|
||||
let imm = imm.pretty_print(0, allocs);
|
||||
format!("movz {}, {}", rd, imm)
|
||||
}
|
||||
&Inst::MovN { rd, ref imm, size } => {
|
||||
let rd = pretty_print_ireg(rd.to_reg(), size, allocs);
|
||||
let imm = imm.pretty_print(0, allocs);
|
||||
format!("movn {}, {}", rd, imm)
|
||||
}
|
||||
&Inst::MovK { rd, ref imm, size } => {
|
||||
let rd = pretty_print_ireg(rd.to_reg(), size, allocs);
|
||||
let imm = imm.pretty_print(0, allocs);
|
||||
format!("movk {}, {}", rd, imm)
|
||||
format!("{} {}, {}", op_str, rd, imm)
|
||||
}
|
||||
&Inst::CSel { rd, rn, rm, cond } => {
|
||||
let rd = pretty_print_ireg(rd.to_reg(), OperandSize::Size64, allocs);
|
||||
|
||||
@@ -7,8 +7,9 @@ pub mod generated_code;
|
||||
use super::{
|
||||
writable_zero_reg, zero_reg, AMode, ASIMDFPModImm, ASIMDMovModImm, AtomicRmwOp, BranchTarget,
|
||||
CallIndInfo, CallInfo, Cond, CondBrKind, ExtendOp, FPUOpRI, FloatCC, Imm12, ImmLogic, ImmShift,
|
||||
Inst as MInst, IntCC, JTSequenceInfo, MachLabel, MoveWideConst, NarrowValueMode, Opcode,
|
||||
OperandSize, PairAMode, Reg, ScalarSize, ShiftOpAndAmt, UImm5, VecMisc2, VectorSize, NZCV,
|
||||
Inst as MInst, IntCC, JTSequenceInfo, MachLabel, MoveWideConst, MoveWideOp, NarrowValueMode,
|
||||
Opcode, OperandSize, PairAMode, Reg, ScalarSize, ShiftOpAndAmt, UImm5, VecMisc2, VectorSize,
|
||||
NZCV,
|
||||
};
|
||||
use crate::isa::aarch64::settings::Flags as IsaFlags;
|
||||
use crate::machinst::isle::*;
|
||||
@@ -145,14 +146,29 @@ where
|
||||
let imm =
|
||||
MoveWideConst::maybe_with_shift(((!imm16) & 0xffff) as u16, i * 16)
|
||||
.unwrap();
|
||||
self.emit(&MInst::MovN { rd, imm, size });
|
||||
self.emit(&MInst::MovWide {
|
||||
op: MoveWideOp::MovN,
|
||||
rd,
|
||||
imm,
|
||||
size,
|
||||
});
|
||||
} else {
|
||||
let imm = MoveWideConst::maybe_with_shift(imm16 as u16, i * 16).unwrap();
|
||||
self.emit(&MInst::MovZ { rd, imm, size });
|
||||
self.emit(&MInst::MovWide {
|
||||
op: MoveWideOp::MovZ,
|
||||
rd,
|
||||
imm,
|
||||
size,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
let imm = MoveWideConst::maybe_with_shift(imm16 as u16, i * 16).unwrap();
|
||||
self.emit(&MInst::MovK { rd, imm, size });
|
||||
self.emit(&MInst::MovWide {
|
||||
op: MoveWideOp::MovK,
|
||||
rd,
|
||||
imm,
|
||||
size,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
src/clif.isle 443b34b797fc8ace
|
||||
src/prelude.isle afd037c4d91c875c
|
||||
src/isa/aarch64/inst.isle 950bb0092242218e
|
||||
src/isa/aarch64/inst.isle f7f03d5ea5411344
|
||||
src/isa/aarch64/lower.isle 71c7e603b0e4bdef
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user