x64: port load to ISLE (#3993)

This change moves the majority of the lowerings for CLIF's `load`
instruction over to ISLE. To do so, it also migrates the previous
mechanism for creating an `Amode` (`lower_to_amode`) to several ISLE
rules (see `to_amode`).
This commit is contained in:
Andrew Brown
2022-04-07 18:31:22 -07:00
committed by GitHub
parent 76f7cde673
commit f62199da8c
12 changed files with 1726 additions and 806 deletions

View File

@@ -12,7 +12,7 @@ use crate::{
condcodes::{FloatCC, IntCC},
immediates::*,
types::*,
Inst, InstructionData, Opcode, TrapCode, Value, ValueLabel, ValueList,
Inst, InstructionData, MemFlags, Opcode, TrapCode, Value, ValueLabel, ValueList,
},
isa::{
settings::Flags,
@@ -313,11 +313,30 @@ where
Amode::imm_reg_reg_shift(simm32, base, index, shift)
}
#[inline]
fn amode_imm_reg(&mut self, simm32: u32, base: Gpr) -> Amode {
Amode::imm_reg(simm32, base.to_reg())
}
#[inline]
fn amode_with_flags(&mut self, amode: &Amode, flags: MemFlags) -> Amode {
amode.with_flags(flags)
}
#[inline]
fn amode_to_synthetic_amode(&mut self, amode: &Amode) -> SyntheticAmode {
amode.clone().into()
}
#[inline]
fn const_shift_lt_eq_3(&mut self, shift_amount: Value) -> Option<u8> {
let input = self.lower_ctx.get_value_as_source_or_const(shift_amount);
match input.constant {
Some(shift_amount) if shift_amount <= 3 => Some(shift_amount as u8),
_ => None,
}
}
#[inline]
fn writable_gpr_to_reg(&mut self, r: WritableGpr) -> WritableReg {
r.to_writable_reg()
@@ -519,6 +538,28 @@ where
fn intcc_to_cc(&mut self, intcc: &IntCC) -> CC {
CC::from_intcc(*intcc)
}
#[inline]
fn sum_extend_fits_in_32_bits(
&mut self,
offset: Offset32,
extend_from_ty: Type,
constant_value: Imm64,
) -> Option<u32> {
let offset: i64 = offset.into();
let constant_value: u64 = constant_value.bits() as u64;
// If necessary, zero extend `constant_value` up to 64 bits.
let shift = 64 - extend_from_ty.bits();
let zero_extended_constant_value = (constant_value << shift) >> shift;
// Sum up the two operands.
let sum = offset.wrapping_add(zero_extended_constant_value as i64);
// Check that the sum will fit in 32-bits.
if sum == ((sum << 32) >> 32) {
Some(sum as u32)
} else {
None
}
}
}
// Since x64 doesn't have 8x16 shifts and we must use a 16x8 shift instead, we