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:
Ulrich Weigand
2022-01-20 17:23:31 +01:00
parent 9321a9db88
commit be60a19623
10 changed files with 66 additions and 29 deletions

View File

@@ -10,8 +10,9 @@ use super::{
Inst as MInst, JTSequenceInfo, MachLabel, MoveWideConst, NarrowValueMode, Opcode, OperandSize, Inst as MInst, JTSequenceInfo, MachLabel, MoveWideConst, NarrowValueMode, Opcode, OperandSize,
PairAMode, Reg, ScalarSize, ShiftOpAndAmt, UImm5, VectorSize, NZCV, 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::machinst::isle::*;
use crate::settings::Flags;
use crate::{ use crate::{
binemit::CodeOffset, binemit::CodeOffset,
ir::{ ir::{
@@ -36,7 +37,8 @@ type BoxExternalName = Box<ExternalName>;
/// The main entry point for lowering with ISLE. /// The main entry point for lowering with ISLE.
pub(crate) fn lower<C>( pub(crate) fn lower<C>(
lower_ctx: &mut C, lower_ctx: &mut C,
isa_flags: &Flags, flags: &Flags,
isa_flags: &IsaFlags,
outputs: &[InsnOutput], outputs: &[InsnOutput],
inst: Inst, inst: Inst,
) -> Result<(), ()> ) -> Result<(), ()>
@@ -45,6 +47,7 @@ where
{ {
lower_common( lower_common(
lower_ctx, lower_ctx,
flags,
isa_flags, isa_flags,
outputs, outputs,
inst, inst,
@@ -63,7 +66,7 @@ pub struct SinkableAtomicLoad {
atomic_addr: Value, 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 where
C: LowerCtx<I = MInst>, C: LowerCtx<I = MInst>,
{ {

View File

@@ -1,4 +1,4 @@
src/clif.isle f176ef3bba99365 src/clif.isle f176ef3bba99365
src/prelude.isle 22dd5ff133398960 src/prelude.isle 51d2aef2566c1c96
src/isa/aarch64/inst.isle f946561093de4ff5 src/isa/aarch64/inst.isle f946561093de4ff5
src/isa/aarch64/lower.isle 2d2e1e076a0c8a23 src/isa/aarch64/lower.isle 2d2e1e076a0c8a23

View File

@@ -61,6 +61,8 @@ pub trait Context {
fn def_inst(&mut self, arg0: Value) -> Option<Inst>; fn def_inst(&mut self, arg0: Value) -> Option<Inst>;
fn trap_code_division_by_zero(&mut self) -> TrapCode; fn trap_code_division_by_zero(&mut self) -> TrapCode;
fn trap_code_integer_overflow(&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_u64(&mut self, arg0: u64) -> Option<MoveWideConst>;
fn move_wide_const_from_negated_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>; 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; 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)] #[derive(Clone, Debug)]
pub enum SideEffectNoResult { pub enum SideEffectNoResult {
Inst { inst: MInst }, 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)] #[derive(Clone, Debug)]
pub enum ProducesFlags { pub enum ProducesFlags {
ProducesFlags { inst: MInst, result: Reg }, 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)] #[derive(Clone, Debug)]
pub enum ConsumesFlags { pub enum ConsumesFlags {
ConsumesFlags { inst: MInst, result: Reg }, ConsumesFlags { inst: MInst, result: Reg },
@@ -1016,7 +1018,7 @@ pub fn constructor_value_regs_none<C: Context>(
inst: ref pattern1_0, inst: ref pattern1_0,
} = pattern0_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 expr0_0 = C::emit(ctx, &pattern1_0);
let expr1_0 = C::value_regs_invalid(ctx); let expr1_0 = C::value_regs_invalid(ctx);
return Some(expr1_0); return Some(expr1_0);
@@ -1042,7 +1044,7 @@ pub fn constructor_with_flags<C: Context>(
result: pattern3_1, result: pattern3_1,
} = pattern2_0 } = 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 expr0_0 = C::emit(ctx, &pattern1_0);
let expr1_0 = C::emit(ctx, &pattern3_0); let expr1_0 = C::emit(ctx, &pattern3_0);
let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1); 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, result: pattern3_1,
} = pattern2_0 } = 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 expr0_0 = C::emit(ctx, &pattern1_0);
let expr1_0 = C::emit(ctx, &pattern3_0); let expr1_0 = C::emit(ctx, &pattern3_0);
return Some(pattern3_1); return Some(pattern3_1);
@@ -1104,7 +1106,7 @@ pub fn constructor_with_flags_2<C: Context>(
result: pattern5_1, result: pattern5_1,
} = pattern4_0 } = 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 expr0_0 = C::emit(ctx, &pattern1_0);
let expr1_0 = C::emit(ctx, &pattern5_0); let expr1_0 = C::emit(ctx, &pattern5_0);
let expr2_0 = C::emit(ctx, &pattern3_0); let expr2_0 = C::emit(ctx, &pattern3_0);

View File

@@ -38,7 +38,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
None 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(()); return Ok(());
} }

View File

@@ -1190,7 +1190,7 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
None None
}; };
if let Ok(()) = isle::lower(ctx, isa_flags, &outputs, insn) { if let Ok(()) = isle::lower(ctx, flags, isa_flags, &outputs, insn) {
return Ok(()); return Ok(());
} }

View File

@@ -17,9 +17,10 @@ use crate::{
}, },
regs, x64_map_regs, regs, x64_map_regs,
}, },
settings::Flags, settings::Flags as IsaFlags,
}, },
machinst::{isle::*, InsnInput, InsnOutput, LowerCtx, VCodeConstantData}, machinst::{isle::*, InsnInput, InsnOutput, LowerCtx, VCodeConstantData},
settings::Flags,
}; };
use std::convert::TryFrom; use std::convert::TryFrom;
@@ -32,7 +33,8 @@ pub struct SinkableLoad {
/// The main entry point for lowering with ISLE. /// The main entry point for lowering with ISLE.
pub(crate) fn lower<C>( pub(crate) fn lower<C>(
lower_ctx: &mut C, lower_ctx: &mut C,
isa_flags: &Flags, flags: &Flags,
isa_flags: &IsaFlags,
outputs: &[InsnOutput], outputs: &[InsnOutput],
inst: Inst, inst: Inst,
) -> Result<(), ()> ) -> Result<(), ()>
@@ -41,6 +43,7 @@ where
{ {
lower_common( lower_common(
lower_ctx, lower_ctx,
flags,
isa_flags, isa_flags,
outputs, outputs,
inst, 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 where
C: LowerCtx<I = MInst>, C: LowerCtx<I = MInst>,
{ {

View File

@@ -1,4 +1,4 @@
src/clif.isle f176ef3bba99365 src/clif.isle f176ef3bba99365
src/prelude.isle 22dd5ff133398960 src/prelude.isle 51d2aef2566c1c96
src/isa/x64/inst.isle 61004acbb1289816 src/isa/x64/inst.isle 61004acbb1289816
src/isa/x64/lower.isle 82db7f7d47ac7809 src/isa/x64/lower.isle 82db7f7d47ac7809

View File

@@ -61,6 +61,8 @@ pub trait Context {
fn def_inst(&mut self, arg0: Value) -> Option<Inst>; fn def_inst(&mut self, arg0: Value) -> Option<Inst>;
fn trap_code_division_by_zero(&mut self) -> TrapCode; fn trap_code_division_by_zero(&mut self) -> TrapCode;
fn trap_code_integer_overflow(&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 operand_size_of_type_32_64(&mut self, arg0: Type) -> OperandSize;
fn raw_operand_size_of_type(&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; 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; 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)] #[derive(Clone, Debug)]
pub enum SideEffectNoResult { pub enum SideEffectNoResult {
Inst { inst: MInst }, 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)] #[derive(Clone, Debug)]
pub enum ProducesFlags { pub enum ProducesFlags {
ProducesFlags { inst: MInst, result: Reg }, 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)] #[derive(Clone, Debug)]
pub enum ConsumesFlags { pub enum ConsumesFlags {
ConsumesFlags { inst: MInst, result: Reg }, ConsumesFlags { inst: MInst, result: Reg },
@@ -144,7 +146,7 @@ pub fn constructor_value_regs_none<C: Context>(
inst: ref pattern1_0, inst: ref pattern1_0,
} = pattern0_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 expr0_0 = C::emit(ctx, &pattern1_0);
let expr1_0 = C::value_regs_invalid(ctx); let expr1_0 = C::value_regs_invalid(ctx);
return Some(expr1_0); return Some(expr1_0);
@@ -170,7 +172,7 @@ pub fn constructor_with_flags<C: Context>(
result: pattern3_1, result: pattern3_1,
} = pattern2_0 } = 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 expr0_0 = C::emit(ctx, &pattern1_0);
let expr1_0 = C::emit(ctx, &pattern3_0); let expr1_0 = C::emit(ctx, &pattern3_0);
let expr2_0 = C::value_regs(ctx, pattern1_1, pattern3_1); 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, result: pattern3_1,
} = pattern2_0 } = 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 expr0_0 = C::emit(ctx, &pattern1_0);
let expr1_0 = C::emit(ctx, &pattern3_0); let expr1_0 = C::emit(ctx, &pattern3_0);
return Some(pattern3_1); return Some(pattern3_1);
@@ -232,7 +234,7 @@ pub fn constructor_with_flags_2<C: Context>(
result: pattern5_1, result: pattern5_1,
} = pattern4_0 } = 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 expr0_0 = C::emit(ctx, &pattern1_0);
let expr1_0 = C::emit(ctx, &pattern5_0); let expr1_0 = C::emit(ctx, &pattern5_0);
let expr2_0 = C::emit(ctx, &pattern3_0); let expr2_0 = C::emit(ctx, &pattern3_0);

View File

@@ -259,6 +259,18 @@ macro_rules! isle_prelude_methods {
TrapCode::IntegerOverflow 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> { fn nonzero_u64_from_imm64(&mut self, val: Imm64) -> Option<u64> {
match val.bits() { match val.bits() {
0 => None, 0 => None,
@@ -285,12 +297,13 @@ macro_rules! isle_prelude_methods {
/// This structure is used to implement the ISLE-generated `Context` trait and /// This structure is used to implement the ISLE-generated `Context` trait and
/// internally has a temporary reference to a machinst `LowerCtx`. /// 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 where
[C::I; N]: smallvec::Array, [C::I; N]: smallvec::Array,
{ {
pub lower_ctx: &'a mut C, 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]>, 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 /// The `isle_lower` argument here is an ISLE-generated function for `lower` and
/// then this function otherwise handles register mapping and such around the /// then this function otherwise handles register mapping and such around the
/// lowering. /// 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, lower_ctx: &mut C,
isa_flags: &F, flags: &F,
isa_flags: &I,
outputs: &[InsnOutput], outputs: &[InsnOutput],
inst: Inst, 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), map_regs: fn(&mut C::I, &RegRenamer),
) -> Result<(), ()> ) -> Result<(), ()>
where where
@@ -315,6 +329,7 @@ where
// internal heap allocations. // internal heap allocations.
let mut isle_ctx = IsleContext { let mut isle_ctx = IsleContext {
lower_ctx, lower_ctx,
flags,
isa_flags, isa_flags,
emitted_insts: SmallVec::new(), emitted_insts: SmallVec::new(),
}; };

View File

@@ -132,6 +132,9 @@
(extern const $I64 Type) (extern const $I64 Type)
(extern const $I128 Type) (extern const $I128 Type)
(extern const $R32 Type)
(extern const $R64 Type)
(extern const $F32 Type) (extern const $F32 Type)
(extern const $F64 Type) (extern const $F64 Type)
@@ -338,3 +341,12 @@
(decl trap_code_integer_overflow () TrapCode) (decl trap_code_integer_overflow () TrapCode)
(extern constructor trap_code_integer_overflow trap_code_integer_overflow) (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)