AArch64 SIMD: pattern-match load+splat into LD1R instruction.
This commit is contained in:
@@ -209,6 +209,19 @@ impl AMode {
|
||||
pub fn label(label: MemLabel) -> AMode {
|
||||
AMode::Label(label)
|
||||
}
|
||||
|
||||
/// Does the address resolve to just a register value, with no offset or
|
||||
/// other computation?
|
||||
pub fn is_reg(&self) -> Option<Reg> {
|
||||
match self {
|
||||
&AMode::UnsignedOffset(r, uimm12) if uimm12.value() == 0 => Some(r),
|
||||
&AMode::Unscaled(r, imm9) if imm9.value() == 0 => Some(r),
|
||||
&AMode::RegOffset(r, off, _) if off == 0 => Some(r),
|
||||
&AMode::FPOffset(off, _) if off == 0 => Some(fp_reg()),
|
||||
&AMode::SPOffset(off, _) if off == 0 => Some(stack_reg()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A memory argument to a load/store-pair.
|
||||
|
||||
@@ -1463,6 +1463,17 @@ impl Inst {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate a LoadAddr instruction (load address of an amode into
|
||||
/// register). Elides when possible (when amode is just a register). Returns
|
||||
/// destination register: either `rd` or a register directly from the amode.
|
||||
pub fn gen_load_addr(rd: Writable<Reg>, mem: AMode) -> (Reg, Option<Inst>) {
|
||||
if let Some(r) = mem.is_reg() {
|
||||
(r, None)
|
||||
} else {
|
||||
(rd.to_reg(), Some(Inst::LoadAddr { rd, mem }))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
Reference in New Issue
Block a user