x64 and aarch64: carry MemFlags on loads/stores; don't emit trap info unless an op can trap.

This end result was previously enacted by carrying a `SourceLoc` on
every load/store, which was somewhat cumbersome, and only indirectly
encoded metadata about a memory reference (can it trap) by its presence
or absence. We have a type for this -- `MemFlags` -- that tells us
everything we might want to know about a load or store, and we should
plumb it through to code emission instead.

This PR attaches a `MemFlags` to an `Amode` on x64, and puts it on load
and store `Inst` variants on aarch64. These two choices seem to factor
things out in the nicest way: there are relatively few load/store insts
on aarch64 but many addressing modes, while the opposite is true on x64.
This commit is contained in:
Chris Fallin
2020-11-17 09:17:12 -08:00
parent e7df081696
commit 073c727a74
11 changed files with 340 additions and 89 deletions

View File

@@ -3,6 +3,7 @@
use crate::ir;
use crate::ir::types;
use crate::ir::types::*;
use crate::ir::MemFlags;
use crate::isa;
use crate::isa::aarch64::{inst::EmitState, inst::*};
use crate::machinst::*;
@@ -312,11 +313,11 @@ impl ABIMachineSpec for AArch64MachineDeps {
}
fn gen_load_stack(mem: StackAMode, into_reg: Writable<Reg>, ty: Type) -> Inst {
Inst::gen_load(into_reg, mem.into(), ty)
Inst::gen_load(into_reg, mem.into(), ty, MemFlags::trusted())
}
fn gen_store_stack(mem: StackAMode, from_reg: Reg, ty: Type) -> Inst {
Inst::gen_store(mem.into(), from_reg, ty)
Inst::gen_store(mem.into(), from_reg, ty, MemFlags::trusted())
}
fn gen_move(to_reg: Writable<Reg>, from_reg: Reg, ty: Type) -> Inst {
@@ -402,12 +403,12 @@ impl ABIMachineSpec for AArch64MachineDeps {
fn gen_load_base_offset(into_reg: Writable<Reg>, base: Reg, offset: i32, ty: Type) -> Inst {
let mem = AMode::RegOffset(base, offset as i64, ty);
Inst::gen_load(into_reg, mem, ty)
Inst::gen_load(into_reg, mem, ty, MemFlags::trusted())
}
fn gen_store_base_offset(base: Reg, offset: i32, from_reg: Reg, ty: Type) -> Inst {
let mem = AMode::RegOffset(base, offset as i64, ty);
Inst::gen_store(mem, from_reg, ty)
Inst::gen_store(mem, from_reg, ty, MemFlags::trusted())
}
fn gen_sp_reg_adjust(amount: i32) -> SmallVec<[Inst; 2]> {
@@ -464,6 +465,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
writable_stack_reg(),
SImm7Scaled::maybe_from_i64(-16, types::I64).unwrap(),
),
flags: MemFlags::trusted(),
});
// mov fp (x29), sp. This uses the ADDI rd, rs, 0 form of `MOV` because
// the usual encoding (`ORR`) does not work with SP.
@@ -500,6 +502,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
writable_stack_reg(),
SImm7Scaled::maybe_from_i64(16, types::I64).unwrap(),
),
flags: MemFlags::trusted(),
});
insts
@@ -542,6 +545,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
stack_reg(),
SImm7Scaled::maybe_from_i64((i * 16) as i64, types::I64).unwrap(),
),
flags: MemFlags::trusted(),
});
}
@@ -553,6 +557,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
stack_reg(),
SImm9::maybe_from_i64((vec_offset + (i * 16)) as i64).unwrap(),
),
flags: MemFlags::trusted(),
});
}
@@ -591,6 +596,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
stack_reg(),
SImm7Scaled::maybe_from_i64((i * 16) as i64, types::I64).unwrap(),
),
flags: MemFlags::trusted(),
});
}
@@ -601,6 +607,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
stack_reg(),
SImm9::maybe_from_i64(((i * 16) + int_save_bytes) as i64).unwrap(),
),
flags: MemFlags::trusted(),
});
}
@@ -621,6 +628,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
writable_xreg(BALDRDASH_TLS_REG),
AMode::UnsignedOffset(fp_reg(), UImm12Scaled::maybe_from_i64(off, I64).unwrap()),
I64,
MemFlags::trusted(),
));
}