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,
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>,
{

View File

@@ -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

View File

@@ -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);

View File

@@ -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(());
}

View File

@@ -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(());
}

View File

@@ -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>,
{

View File

@@ -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

View File

@@ -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);

View File

@@ -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(),
};

View File

@@ -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)