ISLE standard prelude: Additional types and helpers
In preparing to move the s390x back-end to ISLE, I noticed a few missing pieces in the common prelude code. This patch: - Defines the reference types $R32 / $R64. - Provides a trap_code_bad_conversion_to_integer helper. - Provides an avoid_div_traps helper. This requires passing the generic flags in addition to the ISA-specifc flags into the ISLE lowering context.
This commit is contained in:
@@ -10,8 +10,9 @@ use super::{
|
||||
Inst as MInst, JTSequenceInfo, MachLabel, MoveWideConst, NarrowValueMode, Opcode, OperandSize,
|
||||
PairAMode, Reg, ScalarSize, ShiftOpAndAmt, UImm5, VectorSize, NZCV,
|
||||
};
|
||||
use crate::isa::aarch64::settings::Flags;
|
||||
use crate::isa::aarch64::settings::Flags as IsaFlags;
|
||||
use crate::machinst::isle::*;
|
||||
use crate::settings::Flags;
|
||||
use crate::{
|
||||
binemit::CodeOffset,
|
||||
ir::{
|
||||
@@ -36,7 +37,8 @@ type BoxExternalName = Box<ExternalName>;
|
||||
/// The main entry point for lowering with ISLE.
|
||||
pub(crate) fn lower<C>(
|
||||
lower_ctx: &mut C,
|
||||
isa_flags: &Flags,
|
||||
flags: &Flags,
|
||||
isa_flags: &IsaFlags,
|
||||
outputs: &[InsnOutput],
|
||||
inst: Inst,
|
||||
) -> Result<(), ()>
|
||||
@@ -45,6 +47,7 @@ where
|
||||
{
|
||||
lower_common(
|
||||
lower_ctx,
|
||||
flags,
|
||||
isa_flags,
|
||||
outputs,
|
||||
inst,
|
||||
@@ -63,7 +66,7 @@ pub struct SinkableAtomicLoad {
|
||||
atomic_addr: Value,
|
||||
}
|
||||
|
||||
impl<C> generated_code::Context for IsleContext<'_, C, Flags, 6>
|
||||
impl<C> generated_code::Context for IsleContext<'_, C, Flags, IsaFlags, 6>
|
||||
where
|
||||
C: LowerCtx<I = MInst>,
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
src/clif.isle f176ef3bba99365
|
||||
src/prelude.isle 22dd5ff133398960
|
||||
src/prelude.isle 51d2aef2566c1c96
|
||||
src/isa/aarch64/inst.isle f946561093de4ff5
|
||||
src/isa/aarch64/lower.isle 2d2e1e076a0c8a23
|
||||
|
||||
@@ -61,6 +61,8 @@ pub trait Context {
|
||||
fn def_inst(&mut self, arg0: Value) -> Option<Inst>;
|
||||
fn trap_code_division_by_zero(&mut self) -> TrapCode;
|
||||
fn trap_code_integer_overflow(&mut self) -> TrapCode;
|
||||
fn trap_code_bad_conversion_to_integer(&mut self) -> TrapCode;
|
||||
fn avoid_div_traps(&mut self, arg0: Type) -> Option<()>;
|
||||
fn move_wide_const_from_u64(&mut self, arg0: u64) -> Option<MoveWideConst>;
|
||||
fn move_wide_const_from_negated_u64(&mut self, arg0: u64) -> Option<MoveWideConst>;
|
||||
fn imm_logic_from_u64(&mut self, arg0: u64, arg1: Type) -> Option<ImmLogic>;
|
||||
@@ -93,19 +95,19 @@ pub trait Context {
|
||||
fn rotr_opposite_amount(&mut self, arg0: Type, arg1: ImmShift) -> ImmShift;
|
||||
}
|
||||
|
||||
/// Internal type SideEffectNoResult: defined at src/prelude.isle line 279.
|
||||
/// Internal type SideEffectNoResult: defined at src/prelude.isle line 282.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum SideEffectNoResult {
|
||||
Inst { inst: MInst },
|
||||
}
|
||||
|
||||
/// Internal type ProducesFlags: defined at src/prelude.isle line 292.
|
||||
/// Internal type ProducesFlags: defined at src/prelude.isle line 295.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ProducesFlags {
|
||||
ProducesFlags { inst: MInst, result: Reg },
|
||||
}
|
||||
|
||||
/// Internal type ConsumesFlags: defined at src/prelude.isle line 295.
|
||||
/// Internal type ConsumesFlags: defined at src/prelude.isle line 298.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ConsumesFlags {
|
||||
ConsumesFlags { inst: MInst, result: Reg },
|
||||
@@ -1016,7 +1018,7 @@ pub fn constructor_value_regs_none<C: Context>(
|
||||
inst: ref pattern1_0,
|
||||
} = pattern0_0
|
||||
{
|
||||
// Rule at src/prelude.isle line 284.
|
||||
// Rule at src/prelude.isle line 287.
|
||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||
let expr1_0 = C::value_regs_invalid(ctx);
|
||||
return Some(expr1_0);
|
||||
@@ -1042,7 +1044,7 @@ pub fn constructor_with_flags<C: Context>(
|
||||
result: pattern3_1,
|
||||
} = pattern2_0
|
||||
{
|
||||
// Rule at src/prelude.isle line 305.
|
||||
// Rule at src/prelude.isle line 308.
|
||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||
let expr1_0 = C::emit(ctx, &pattern3_0);
|
||||
let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1);
|
||||
@@ -1070,7 +1072,7 @@ pub fn constructor_with_flags_1<C: Context>(
|
||||
result: pattern3_1,
|
||||
} = pattern2_0
|
||||
{
|
||||
// Rule at src/prelude.isle line 313.
|
||||
// Rule at src/prelude.isle line 316.
|
||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||
let expr1_0 = C::emit(ctx, &pattern3_0);
|
||||
return Some(pattern3_1);
|
||||
@@ -1104,7 +1106,7 @@ pub fn constructor_with_flags_2<C: Context>(
|
||||
result: pattern5_1,
|
||||
} = pattern4_0
|
||||
{
|
||||
// Rule at src/prelude.isle line 323.
|
||||
// Rule at src/prelude.isle line 326.
|
||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||
let expr1_0 = C::emit(ctx, &pattern5_0);
|
||||
let expr2_0 = C::emit(ctx, &pattern3_0);
|
||||
|
||||
@@ -38,7 +38,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
None
|
||||
};
|
||||
|
||||
if let Ok(()) = super::lower::isle::lower(ctx, isa_flags, &outputs, insn) {
|
||||
if let Ok(()) = super::lower::isle::lower(ctx, flags, isa_flags, &outputs, insn) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
@@ -1190,7 +1190,7 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
None
|
||||
};
|
||||
|
||||
if let Ok(()) = isle::lower(ctx, isa_flags, &outputs, insn) {
|
||||
if let Ok(()) = isle::lower(ctx, flags, isa_flags, &outputs, insn) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,10 @@ use crate::{
|
||||
},
|
||||
regs, x64_map_regs,
|
||||
},
|
||||
settings::Flags,
|
||||
settings::Flags as IsaFlags,
|
||||
},
|
||||
machinst::{isle::*, InsnInput, InsnOutput, LowerCtx, VCodeConstantData},
|
||||
settings::Flags,
|
||||
};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
@@ -32,7 +33,8 @@ pub struct SinkableLoad {
|
||||
/// The main entry point for lowering with ISLE.
|
||||
pub(crate) fn lower<C>(
|
||||
lower_ctx: &mut C,
|
||||
isa_flags: &Flags,
|
||||
flags: &Flags,
|
||||
isa_flags: &IsaFlags,
|
||||
outputs: &[InsnOutput],
|
||||
inst: Inst,
|
||||
) -> Result<(), ()>
|
||||
@@ -41,6 +43,7 @@ where
|
||||
{
|
||||
lower_common(
|
||||
lower_ctx,
|
||||
flags,
|
||||
isa_flags,
|
||||
outputs,
|
||||
inst,
|
||||
@@ -49,7 +52,7 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
impl<C> generated_code::Context for IsleContext<'_, C, Flags, 6>
|
||||
impl<C> generated_code::Context for IsleContext<'_, C, Flags, IsaFlags, 6>
|
||||
where
|
||||
C: LowerCtx<I = MInst>,
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
src/clif.isle f176ef3bba99365
|
||||
src/prelude.isle 22dd5ff133398960
|
||||
src/prelude.isle 51d2aef2566c1c96
|
||||
src/isa/x64/inst.isle 61004acbb1289816
|
||||
src/isa/x64/lower.isle 82db7f7d47ac7809
|
||||
|
||||
@@ -61,6 +61,8 @@ pub trait Context {
|
||||
fn def_inst(&mut self, arg0: Value) -> Option<Inst>;
|
||||
fn trap_code_division_by_zero(&mut self) -> TrapCode;
|
||||
fn trap_code_integer_overflow(&mut self) -> TrapCode;
|
||||
fn trap_code_bad_conversion_to_integer(&mut self) -> TrapCode;
|
||||
fn avoid_div_traps(&mut self, arg0: Type) -> Option<()>;
|
||||
fn operand_size_of_type_32_64(&mut self, arg0: Type) -> OperandSize;
|
||||
fn raw_operand_size_of_type(&mut self, arg0: Type) -> OperandSize;
|
||||
fn put_in_reg_mem_imm(&mut self, arg0: Value) -> RegMemImm;
|
||||
@@ -90,19 +92,19 @@ pub trait Context {
|
||||
fn sse_insertps_lane_imm(&mut self, arg0: u8) -> u8;
|
||||
}
|
||||
|
||||
/// Internal type SideEffectNoResult: defined at src/prelude.isle line 279.
|
||||
/// Internal type SideEffectNoResult: defined at src/prelude.isle line 282.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum SideEffectNoResult {
|
||||
Inst { inst: MInst },
|
||||
}
|
||||
|
||||
/// Internal type ProducesFlags: defined at src/prelude.isle line 292.
|
||||
/// Internal type ProducesFlags: defined at src/prelude.isle line 295.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ProducesFlags {
|
||||
ProducesFlags { inst: MInst, result: Reg },
|
||||
}
|
||||
|
||||
/// Internal type ConsumesFlags: defined at src/prelude.isle line 295.
|
||||
/// Internal type ConsumesFlags: defined at src/prelude.isle line 298.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ConsumesFlags {
|
||||
ConsumesFlags { inst: MInst, result: Reg },
|
||||
@@ -144,7 +146,7 @@ pub fn constructor_value_regs_none<C: Context>(
|
||||
inst: ref pattern1_0,
|
||||
} = pattern0_0
|
||||
{
|
||||
// Rule at src/prelude.isle line 284.
|
||||
// Rule at src/prelude.isle line 287.
|
||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||
let expr1_0 = C::value_regs_invalid(ctx);
|
||||
return Some(expr1_0);
|
||||
@@ -170,7 +172,7 @@ pub fn constructor_with_flags<C: Context>(
|
||||
result: pattern3_1,
|
||||
} = pattern2_0
|
||||
{
|
||||
// Rule at src/prelude.isle line 305.
|
||||
// Rule at src/prelude.isle line 308.
|
||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||
let expr1_0 = C::emit(ctx, &pattern3_0);
|
||||
let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1);
|
||||
@@ -198,7 +200,7 @@ pub fn constructor_with_flags_1<C: Context>(
|
||||
result: pattern3_1,
|
||||
} = pattern2_0
|
||||
{
|
||||
// Rule at src/prelude.isle line 313.
|
||||
// Rule at src/prelude.isle line 316.
|
||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||
let expr1_0 = C::emit(ctx, &pattern3_0);
|
||||
return Some(pattern3_1);
|
||||
@@ -232,7 +234,7 @@ pub fn constructor_with_flags_2<C: Context>(
|
||||
result: pattern5_1,
|
||||
} = pattern4_0
|
||||
{
|
||||
// Rule at src/prelude.isle line 323.
|
||||
// Rule at src/prelude.isle line 326.
|
||||
let expr0_0 = C::emit(ctx, &pattern1_0);
|
||||
let expr1_0 = C::emit(ctx, &pattern5_0);
|
||||
let expr2_0 = C::emit(ctx, &pattern3_0);
|
||||
|
||||
@@ -259,6 +259,18 @@ macro_rules! isle_prelude_methods {
|
||||
TrapCode::IntegerOverflow
|
||||
}
|
||||
|
||||
fn trap_code_bad_conversion_to_integer(&mut self) -> TrapCode {
|
||||
TrapCode::BadConversionToInteger
|
||||
}
|
||||
|
||||
fn avoid_div_traps(&mut self, _: Type) -> Option<()> {
|
||||
if self.flags.avoid_div_traps() {
|
||||
Some(())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn nonzero_u64_from_imm64(&mut self, val: Imm64) -> Option<u64> {
|
||||
match val.bits() {
|
||||
0 => None,
|
||||
@@ -285,12 +297,13 @@ macro_rules! isle_prelude_methods {
|
||||
|
||||
/// This structure is used to implement the ISLE-generated `Context` trait and
|
||||
/// internally has a temporary reference to a machinst `LowerCtx`.
|
||||
pub(crate) struct IsleContext<'a, C: LowerCtx, F, const N: usize>
|
||||
pub(crate) struct IsleContext<'a, C: LowerCtx, F, I, const N: usize>
|
||||
where
|
||||
[C::I; N]: smallvec::Array,
|
||||
{
|
||||
pub lower_ctx: &'a mut C,
|
||||
pub isa_flags: &'a F,
|
||||
pub flags: &'a F,
|
||||
pub isa_flags: &'a I,
|
||||
pub emitted_insts: SmallVec<[C::I; N]>,
|
||||
}
|
||||
|
||||
@@ -299,12 +312,13 @@ where
|
||||
/// The `isle_lower` argument here is an ISLE-generated function for `lower` and
|
||||
/// then this function otherwise handles register mapping and such around the
|
||||
/// lowering.
|
||||
pub(crate) fn lower_common<C, F, const N: usize>(
|
||||
pub(crate) fn lower_common<C, F, I, const N: usize>(
|
||||
lower_ctx: &mut C,
|
||||
isa_flags: &F,
|
||||
flags: &F,
|
||||
isa_flags: &I,
|
||||
outputs: &[InsnOutput],
|
||||
inst: Inst,
|
||||
isle_lower: fn(&mut IsleContext<'_, C, F, N>, Inst) -> Option<ValueRegs>,
|
||||
isle_lower: fn(&mut IsleContext<'_, C, F, I, N>, Inst) -> Option<ValueRegs>,
|
||||
map_regs: fn(&mut C::I, &RegRenamer),
|
||||
) -> Result<(), ()>
|
||||
where
|
||||
@@ -315,6 +329,7 @@ where
|
||||
// internal heap allocations.
|
||||
let mut isle_ctx = IsleContext {
|
||||
lower_ctx,
|
||||
flags,
|
||||
isa_flags,
|
||||
emitted_insts: SmallVec::new(),
|
||||
};
|
||||
|
||||
@@ -132,6 +132,9 @@
|
||||
(extern const $I64 Type)
|
||||
(extern const $I128 Type)
|
||||
|
||||
(extern const $R32 Type)
|
||||
(extern const $R64 Type)
|
||||
|
||||
(extern const $F32 Type)
|
||||
(extern const $F64 Type)
|
||||
|
||||
@@ -338,3 +341,12 @@
|
||||
|
||||
(decl trap_code_integer_overflow () TrapCode)
|
||||
(extern constructor trap_code_integer_overflow trap_code_integer_overflow)
|
||||
|
||||
(decl trap_code_bad_conversion_to_integer () TrapCode)
|
||||
(extern constructor trap_code_bad_conversion_to_integer trap_code_bad_conversion_to_integer)
|
||||
|
||||
;;;; Helpers for accessing compilation flags ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(decl avoid_div_traps () Type)
|
||||
(extern extractor avoid_div_traps avoid_div_traps)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user