MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / lower_to_amode

Function lower_to_amode

cranelift/codegen/src/isa/x64/lower.rs:233–315  ·  view source on GitHub ↗

Lowers an instruction to one of the x86 addressing modes. Note: the 32-bit offset in Cranelift has to be sign-extended, which maps x86's behavior.

(ctx: &mut Lower<Inst>, spec: InsnInput, offset: i32)

Source from the content-addressed store, hash-verified

231///
232/// Note: the 32-bit offset in Cranelift has to be sign-extended, which maps x86's behavior.
233fn lower_to_amode(ctx: &mut Lower<Inst>, spec: InsnInput, offset: i32) -> Amode {
234 let flags = ctx
235 .memflags(spec.insn)
236 .expect("Instruction with amode should have memflags");
237
238 // We now either have an add that we must materialize, or some other input; as well as the
239 // final offset.
240 if let Some(add) = matches_input(ctx, spec, Opcode::Iadd) {
241 let output_ty = ctx.output_ty(add, 0);
242 debug_assert_eq!(
243 output_ty,
244 types::I64,
245 "Address width of 64 expected, got {output_ty}"
246 );
247 let add_inputs = &[
248 InsnInput {
249 insn: add,
250 input: 0,
251 },
252 InsnInput {
253 insn: add,
254 input: 1,
255 },
256 ];
257
258 // TODO heap_addr legalization generates a uext64 *after* the shift, so these optimizations
259 // aren't happening in the wasm case. We could do better, given some range analysis.
260 let (base, index, shift) = if let Some((shift_input, shift_amt)) =
261 matches_small_constant_shift(ctx, add_inputs[0])
262 {
263 (
264 put_input_in_reg(ctx, add_inputs[1]),
265 put_input_in_reg(ctx, shift_input),
266 shift_amt,
267 )
268 } else if let Some((shift_input, shift_amt)) =
269 matches_small_constant_shift(ctx, add_inputs[1])
270 {
271 (
272 put_input_in_reg(ctx, add_inputs[0]),
273 put_input_in_reg(ctx, shift_input),
274 shift_amt,
275 )
276 } else {
277 for input in 0..=1 {
278 // Try to pierce through uextend.
279 let (inst, inst_input) = if let Some(uextend) =
280 matches_input(ctx, InsnInput { insn: add, input }, Opcode::Uextend)
281 {
282 (uextend, 0)
283 } else {
284 (add, input)
285 };
286
287 // If it's a constant, add it directly!
288 if let Some(cst) = ctx.get_input_as_source_or_const(inst, inst_input).constant {
289 let final_offset = (offset as i64).wrapping_add(cst as i64);
290 if let Ok(final_offset) = i32::try_from(final_offset) {

Callers 1

sink_loadMethod · 0.85

Calls 8

matches_inputFunction · 0.85
put_input_in_regFunction · 0.85
output_tyMethod · 0.80
expectMethod · 0.45
memflagsMethod · 0.45
with_flagsMethod · 0.45

Tested by

no test coverage detected