diff --git a/cranelift/codegen/src/isa/aarch64/inst/mod.rs b/cranelift/codegen/src/isa/aarch64/inst/mod.rs index 6775f98b2d..90fce9c5fa 100644 --- a/cranelift/codegen/src/isa/aarch64/inst/mod.rs +++ b/cranelift/codegen/src/isa/aarch64/inst/mod.rs @@ -13,6 +13,7 @@ use regalloc::{RealReg, RealRegUniverse, Reg, RegClass, SpillSlot, VirtualReg, W use regalloc::{RegUsageCollector, Set}; use alloc::vec::Vec; +use core::convert::TryFrom; use smallvec::{smallvec, SmallVec}; use std::string::{String, ToString}; @@ -2552,12 +2553,42 @@ impl ShowWithRRU for Inst { let rd = rd.show_rru(mb_rru); format!("ldr {}, 8 ; b 12 ; data {:?} + {}", rd, name, offset) } - &Inst::LoadAddr { rd, ref mem } => { - let rd = rd.show_rru(mb_rru); - let (mem_str, mem) = mem_finalize_for_show(mem, mb_rru); - let mem = mem.show_rru(mb_rru); - format!("{}load_addr {}, {}", mem_str, rd, mem) - } + &Inst::LoadAddr { rd, ref mem } => match *mem { + MemArg::FPOffset(fp_off) => { + let alu_op = if fp_off < 0 { + ALUOp::Sub64 + } else { + ALUOp::Add64 + }; + if let Some(imm12) = Imm12::maybe_from_u64(u64::try_from(fp_off.abs()).unwrap()) + { + let inst = Inst::AluRRImm12 { + alu_op, + rd, + imm12, + rn: fp_reg(), + }; + inst.show_rru(mb_rru) + } else { + let mut res = String::new(); + let const_insts = + Inst::load_constant(rd, u64::try_from(fp_off.abs()).unwrap()); + for inst in const_insts { + res.push_str(&inst.show_rru(mb_rru)); + res.push_str("; "); + } + let inst = Inst::AluRRR { + alu_op, + rd, + rn: fp_reg(), + rm: rd.to_reg(), + }; + res.push_str(&inst.show_rru(mb_rru)); + res + } + } + _ => unimplemented!("{:?}", mem), + }, } } } diff --git a/cranelift/filetests/filetests/vcode/aarch64/stack.clif b/cranelift/filetests/filetests/vcode/aarch64/stack.clif index 0b503c3aa5..99d60d97ad 100644 --- a/cranelift/filetests/filetests/vcode/aarch64/stack.clif +++ b/cranelift/filetests/filetests/vcode/aarch64/stack.clif @@ -12,7 +12,7 @@ block0: ; check: stp fp, lr, [sp, #-16]! ; nextln: mov fp, sp ; nextln: sub sp, sp, #16 -; nextln: load_addr x0, [fp, #-8] +; nextln: sub x0, fp, #8 ; nextln: mov sp, fp ; nextln: ldp fp, lr, [sp], #16 ; nextln: ret @@ -31,7 +31,7 @@ block0: ; nextln: mov fp, sp ; nextln: ldr x15, 8 ; b 12 ; data 100016 ; nextln: sub sp, sp, x15, UXTX -; nextln: movn x15, #34471 ; movk x15, #65534, LSL #16 ; add x15, x15, fp ; load_addr x0, [x15] +; nextln: movz x0, #34472; movk x0, #1, LSL #16; sub x0, fp, x0 ; nextln: mov sp, fp ; nextln: ldp fp, lr, [sp], #16 ; nextln: ret @@ -50,7 +50,7 @@ block0: ; check: stp fp, lr, [sp, #-16]! ; nextln: mov fp, sp ; nextln: sub sp, sp, #16 -; nextln: load_addr x0, [fp, #-8] +; nextln: sub x0, fp, #8 ; nextln: ldur x0, [x0] ; nextln: mov sp, fp ; nextln: ldp fp, lr, [sp], #16 @@ -70,7 +70,7 @@ block0: ; nextln: mov fp, sp ; nextln: ldr x15, 8 ; b 12 ; data 100016 ; nextln: sub sp, sp, x15, UXTX -; nextln: movn x15, #34471 ; movk x15, #65534, LSL #16 ; add x15, x15, fp ; load_addr x0, [x15] +; nextln: movz x0, #34472; movk x0, #1, LSL #16; sub x0, fp, x0 ; nextln: ldur x0, [x0] ; nextln: mov sp, fp ; nextln: ldp fp, lr, [sp], #16 @@ -88,7 +88,7 @@ block0(v0: i64): ; check: stp fp, lr, [sp, #-16]! ; nextln: mov fp, sp ; nextln: sub sp, sp, #16 -; nextln: load_addr x1, [fp, #-8] +; nextln: sub x1, fp, #8 ; nextln: stur x0, [x1] ; nextln: mov sp, fp ; nextln: ldp fp, lr, [sp], #16 @@ -108,7 +108,7 @@ block0(v0: i64): ; nextln: mov fp, sp ; nextln: ldr x15, 8 ; b 12 ; data 100016 ; nextln: sub sp, sp, x15, UXTX -; nextln: movn x15, #34471 ; movk x15, #65534, LSL #16 ; add x15, x15, fp ; load_addr x1, [x15] +; nextln: movz x1, #34472; movk x1, #1, LSL #16; sub x1, fp, x1 ; nextln: stur x0, [x1] ; nextln: mov sp, fp ; nextln: ldp fp, lr, [sp], #16 diff --git a/cranelift/src/disasm.rs b/cranelift/src/disasm.rs index 0b60439f4d..3977be69f3 100644 --- a/cranelift/src/disasm.rs +++ b/cranelift/src/disasm.rs @@ -150,10 +150,16 @@ cfg_if! { .build() } } - Architecture::Aarch64 {..} => Capstone::new() - .arm64() - .mode(arch::arm64::ArchMode::Arm) - .build(), + Architecture::Aarch64 {..} => { + let mut cs = Capstone::new() + .arm64() + .mode(arch::arm64::ArchMode::Arm) + .build() + .map_err(|err| err.to_string())?; + // Inline constants should be skipped + cs.set_skipdata(true).map_err(|err| err.to_string())?; + Ok(cs) + } _ => return Err(String::from("Unknown ISA")), };