From be60a19623b181e3f94b3dd1e80e755a10f03ebd Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Thu, 20 Jan 2022 17:23:31 +0100 Subject: [PATCH] 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. --- .../codegen/src/isa/aarch64/lower/isle.rs | 9 ++++--- .../lower/isle/generated_code.manifest | 2 +- .../isa/aarch64/lower/isle/generated_code.rs | 16 ++++++------ .../codegen/src/isa/aarch64/lower_inst.rs | 2 +- cranelift/codegen/src/isa/x64/lower.rs | 2 +- cranelift/codegen/src/isa/x64/lower/isle.rs | 9 ++++--- .../x64/lower/isle/generated_code.manifest | 2 +- .../src/isa/x64/lower/isle/generated_code.rs | 16 ++++++------ cranelift/codegen/src/machinst/isle.rs | 25 +++++++++++++++---- cranelift/codegen/src/prelude.isle | 12 +++++++++ 10 files changed, 66 insertions(+), 29 deletions(-) diff --git a/cranelift/codegen/src/isa/aarch64/lower/isle.rs b/cranelift/codegen/src/isa/aarch64/lower/isle.rs index 51df016418..b08d3cd173 100644 --- a/cranelift/codegen/src/isa/aarch64/lower/isle.rs +++ b/cranelift/codegen/src/isa/aarch64/lower/isle.rs @@ -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; /// The main entry point for lowering with ISLE. pub(crate) fn lower( 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 generated_code::Context for IsleContext<'_, C, Flags, 6> +impl generated_code::Context for IsleContext<'_, C, Flags, IsaFlags, 6> where C: LowerCtx, { diff --git a/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.manifest b/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.manifest index 09106198bb..2d08e9aa75 100644 --- a/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.manifest +++ b/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.manifest @@ -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 diff --git a/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.rs b/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.rs index 8d0ba055c4..231c90bbc1 100644 --- a/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.rs +++ b/cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.rs @@ -61,6 +61,8 @@ pub trait Context { fn def_inst(&mut self, arg0: Value) -> Option; 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; fn move_wide_const_from_negated_u64(&mut self, arg0: u64) -> Option; fn imm_logic_from_u64(&mut self, arg0: u64, arg1: Type) -> Option; @@ -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( 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( 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( 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( 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); diff --git a/cranelift/codegen/src/isa/aarch64/lower_inst.rs b/cranelift/codegen/src/isa/aarch64/lower_inst.rs index 78cf4f7f24..8fc549ac2e 100644 --- a/cranelift/codegen/src/isa/aarch64/lower_inst.rs +++ b/cranelift/codegen/src/isa/aarch64/lower_inst.rs @@ -38,7 +38,7 @@ pub(crate) fn lower_insn_to_regs>( 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(()); } diff --git a/cranelift/codegen/src/isa/x64/lower.rs b/cranelift/codegen/src/isa/x64/lower.rs index a7765de677..d5503416de 100644 --- a/cranelift/codegen/src/isa/x64/lower.rs +++ b/cranelift/codegen/src/isa/x64/lower.rs @@ -1190,7 +1190,7 @@ fn lower_insn_to_regs>( None }; - if let Ok(()) = isle::lower(ctx, isa_flags, &outputs, insn) { + if let Ok(()) = isle::lower(ctx, flags, isa_flags, &outputs, insn) { return Ok(()); } diff --git a/cranelift/codegen/src/isa/x64/lower/isle.rs b/cranelift/codegen/src/isa/x64/lower/isle.rs index 7c5d1b129b..1f1bcb32d5 100644 --- a/cranelift/codegen/src/isa/x64/lower/isle.rs +++ b/cranelift/codegen/src/isa/x64/lower/isle.rs @@ -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( 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 generated_code::Context for IsleContext<'_, C, Flags, 6> +impl generated_code::Context for IsleContext<'_, C, Flags, IsaFlags, 6> where C: LowerCtx, { diff --git a/cranelift/codegen/src/isa/x64/lower/isle/generated_code.manifest b/cranelift/codegen/src/isa/x64/lower/isle/generated_code.manifest index 5a897a6008..c1a8694135 100644 --- a/cranelift/codegen/src/isa/x64/lower/isle/generated_code.manifest +++ b/cranelift/codegen/src/isa/x64/lower/isle/generated_code.manifest @@ -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 diff --git a/cranelift/codegen/src/isa/x64/lower/isle/generated_code.rs b/cranelift/codegen/src/isa/x64/lower/isle/generated_code.rs index a31e0583c1..9c2ad69740 100644 --- a/cranelift/codegen/src/isa/x64/lower/isle/generated_code.rs +++ b/cranelift/codegen/src/isa/x64/lower/isle/generated_code.rs @@ -61,6 +61,8 @@ pub trait Context { fn def_inst(&mut self, arg0: Value) -> Option; 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( 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( 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( 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( 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); diff --git a/cranelift/codegen/src/machinst/isle.rs b/cranelift/codegen/src/machinst/isle.rs index 808954dea5..d7d1fae60a 100644 --- a/cranelift/codegen/src/machinst/isle.rs +++ b/cranelift/codegen/src/machinst/isle.rs @@ -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 { 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( +pub(crate) fn lower_common( 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, + isle_lower: fn(&mut IsleContext<'_, C, F, I, N>, Inst) -> Option, 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(), }; diff --git a/cranelift/codegen/src/prelude.isle b/cranelift/codegen/src/prelude.isle index 8ce3d787a5..c5a037b657 100644 --- a/cranelift/codegen/src/prelude.isle +++ b/cranelift/codegen/src/prelude.isle @@ -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) +