isle
cisen opened this issue · 0 comments
cisen commented
https://github.com/cisen/sourcecode-isle
总结
// decl 函数名 参数类型列表 返回结果列表
(decl produces_flags_append (ProducesFlags MInst) ProducesFlags)
// 转换为一个提供一个这样的函数:x是变量,如果输入x为-1,则得到返回结果-2
(rule (X -1) -2)
翻译对照
0
(type i64 (primitive i64))
(decl X (i64) i64)
// 转换为一个提供一个这样的函数:x是变量,如果输入x为-1,则得到返回结果-2
(rule (X -1) -2)
(rule (X -2) -3)
(rule (X 0x7fff_ffff_ffff_ffff) 0x8000_0000_0000_0000)
(rule (X 0xffff_ffff_ffff_fff0) 1)
(type i128 (primitive i128))
(decl Y (i128) i128)
(rule (Y 0x1000_0000_0000_0000_1234_5678_9abc_def0) -1)
(rule (Y 0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff) 3)
(rule (Y -0x1000_0000_0000_0000_1234_5678_9abc_def0) 1)
(rule (Y -0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff) -3)
翻译结果
// GENERATED BY ISLE. DO NOT EDIT!
//
// Generated automatically from the instruction-selection DSL code in:
// - cranelift/isle/isle/isle_examples/run/iconst.isle
#![allow(dead_code, unreachable_code, unreachable_patterns)]
#![allow(unused_imports, unused_variables, non_snake_case, unused_mut)]
#![allow(irrefutable_let_patterns, unused_assignments, non_camel_case_types)]
use super::*; // Pulls in all external types.
use std::marker::PhantomData;
/// Context during lowering: an implementation of this trait
/// must be provided with all external constructors and extractors.
/// A mutable borrow is passed along through all lowering logic.
pub trait Context {
}
pub trait ContextIter {
type Context;
type Output;
fn next(&mut self, ctx: &mut Self::Context) -> Option<Self::Output>;
}
pub struct ContextIterWrapper<Item, I: Iterator < Item = Item>, C: Context> {
iter: I,
_ctx: PhantomData<C>,
}
impl<Item, I: Iterator<Item = Item>, C: Context> From<I> for ContextIterWrapper<Item, I, C> {
fn from(iter: I) -> Self {
Self { iter, _ctx: PhantomData }
}
}
impl<Item, I: Iterator<Item = Item>, C: Context> ContextIter for ContextIterWrapper<Item, I, C> {
type Context = C;
type Output = Item;
fn next(&mut self, _ctx: &mut Self::Context) -> Option<Self::Output> {
self.iter.next()
}
}
// Generated as internal constructor for term X.
pub fn constructor_X<C: Context>(ctx: &mut C, arg0: i64) -> Option<i64> {
let pattern0_0 = arg0;
if pattern0_0 == -2i128 as i64 {
// Rule at cranelift/isle/isle/isle_examples/run/iconst.isle line 5.
let expr0_0: i64 = -3i128 as i64;
return Some(expr0_0);
}
if pattern0_0 == -1i128 as i64 {
// Rule at cranelift/isle/isle/isle_examples/run/iconst.isle line 4.
let expr0_0: i64 = -2i128 as i64;
return Some(expr0_0);
}
if pattern0_0 == 9223372036854775807i128 as i64 {
// Rule at cranelift/isle/isle/isle_examples/run/iconst.isle line 6.
let expr0_0: i64 = 9223372036854775808i128 as i64;
return Some(expr0_0);
}
if pattern0_0 == 18446744073709551600i128 as i64 {
// Rule at cranelift/isle/isle/isle_examples/run/iconst.isle line 7.
let expr0_0: i64 = 1i128 as i64;
return Some(expr0_0);
}
return None;
}
// Generated as internal constructor for term Y.
pub fn constructor_Y<C: Context>(ctx: &mut C, arg0: i128) -> Option<i128> {
let pattern0_0 = arg0;
if pattern0_0 == -21267647932558653967772681431949303536i128 {
// Rule at cranelift/isle/isle/isle_examples/run/iconst.isle line 16.
let expr0_0: i128 = 1i128;
return Some(expr0_0);
}
// 为什么这里是1?因为0 - fffffff = 1
if pattern0_0 == -1i128 {
// Rule at cranelift/isle/isle/isle_examples/run/iconst.isle line 14.
let expr0_0: i128 = 3i128;
return Some(expr0_0);
}
if pattern0_0 == 1i128 {
// Rule at cranelift/isle/isle/isle_examples/run/iconst.isle line 17.
let expr0_0: i128 = -3i128;
return Some(expr0_0);
}
if pattern0_0 == 21267647932558653967772681431949303536i128 {
// Rule at cranelift/isle/isle/isle_examples/run/iconst.isle line 13.
let expr0_0: i128 = -1i128;
return Some(expr0_0);
}
return None;
}
提供给用户调用
mod iconst;
struct Context;
impl iconst::Context for Context {}
fn main() {
let mut ctx = Context;
assert_eq!(iconst::constructor_X(&mut ctx, -1), Some(-2));
assert_eq!(iconst::constructor_X(&mut ctx, -2), Some(-3));
assert_eq!(iconst::constructor_X(&mut ctx, 0x7fff_ffff_ffff_ffff), Some(0x8000_0000_0000_0000u64 as i64));
assert_eq!(iconst::constructor_X(&mut ctx, 0xffff_ffff_ffff_fff0_u64 as i64), Some(1));
assert_eq!(iconst::constructor_Y(&mut ctx, 0x1000_0000_0000_0000_1234_5678_9abc_def0), Some(-1));
assert_eq!(iconst::constructor_Y(&mut ctx, 0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffffu128 as i128), Some(3));
assert_eq!(iconst::constructor_Y(&mut ctx, -0x1000_0000_0000_0000_1234_5678_9abc_def0), Some(1));
assert_eq!(iconst::constructor_Y(&mut ctx, -(0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffffu128 as i128)), Some(-3));
}
1
(type SideEffectNoResult (enum
(Inst (inst MInst))
(Inst2 (inst1 MInst)
(inst2 MInst))
(Inst3 (inst1 MInst)
(inst2 MInst)
(inst3 MInst))))
/// Internal type SideEffectNoResult: defined at src\prelude.isle line 639.
#[derive(Clone, Debug)]
pub enum SideEffectNoResult {
Inst {
inst: MInst,
},
Inst2 {
inst1: MInst,
inst2: MInst,
},
Inst3 {
inst1: MInst,
inst2: MInst,
inst3: MInst,
},
}
2
;; Construct a single-element `InstOutput` from a single register.
(decl output_reg (Reg) InstOutput)
(rule (output_reg reg) (output (value_reg reg)))
// Generated as internal constructor for term output_reg.
pub fn constructor_output_reg<C: Context>(ctx: &mut C, arg0: Reg) -> Option<InstOutput> {
let pattern0_0 = arg0;
// Rule at src\prelude.isle line 121.
let expr0_0 = C::value_reg(ctx, pattern0_0);
let expr1_0 = C::output(ctx, expr0_0);
return Some(expr1_0);
}
3 if else
;; Chain another producer to a `ProducesFlags`.
(decl produces_flags_append (ProducesFlags MInst) ProducesFlags)
(rule (produces_flags_append (ProducesFlags.ProducesFlagsSideEffect inst1) inst2)
(ProducesFlags.ProducesFlagsTwiceSideEffect inst1 inst2))
// Generated as internal constructor for term produces_flags_append.
pub fn constructor_produces_flags_append<C: Context>(
ctx: &mut C,
arg0: &ProducesFlags,
arg1: &MInst,
) -> Option<ProducesFlags> {
let pattern0_0 = arg0;
if let &ProducesFlags::ProducesFlagsSideEffect {
inst: ref pattern1_0,
} = pattern0_0
{
let pattern2_0 = arg1;
// Rule at src\prelude.isle line 693.
let expr0_0 = ProducesFlags::ProducesFlagsTwiceSideEffect {
inst1: pattern1_0.clone(),
inst2: pattern2_0.clone(),
};
return Some(expr0_0);
}
return None;
}
4 match
;; Modify a ProducesFlags to use it only for its side-effect, ignoring
;; its result.
(decl produces_flags_ignore (ProducesFlags) ProducesFlags)
(rule (produces_flags_ignore (ProducesFlags.ProducesFlagsReturnsReg inst _))
(ProducesFlags.ProducesFlagsSideEffect inst))
(rule (produces_flags_ignore (ProducesFlags.ProducesFlagsReturnsResultWithConsumer inst _))
(ProducesFlags.ProducesFlagsSideEffect inst))
// Generated as internal constructor for term produces_flags_ignore.
pub fn constructor_produces_flags_ignore<C: Context>(
ctx: &mut C,
arg0: &ProducesFlags,
) -> Option<ProducesFlags> {
let pattern0_0 = arg0;
match pattern0_0 {
&ProducesFlags::ProducesFlagsReturnsReg {
inst: ref pattern1_0,
result: pattern1_1,
} => {
// Rule at src\prelude.isle line 723.
let expr0_0 = ProducesFlags::ProducesFlagsSideEffect {
inst: pattern1_0.clone(),
};
return Some(expr0_0);
}
&ProducesFlags::ProducesFlagsReturnsResultWithConsumer {
inst: ref pattern1_0,
result: pattern1_1,
} => {
// Rule at src\prelude.isle line 725.
let expr0_0 = ProducesFlags::ProducesFlagsSideEffect {
inst: pattern1_0.clone(),
};
return Some(expr0_0);
}
_ => {}
}
return None;
}
5 嵌套
(convert u8 u64 u8_as_u64)
(decl lower_clz (Type Reg) Reg)
(rule
(lower_clz ty rs)
(if-let $false (has_b))
(gen_cltz $true rs ty))
(rule 2
(lower_clz $I64 r)
(if-let $true (has_b))
(alu_rr_funct12 (AluOPRRI.Clz) r))
(rule 2
(lower_clz $I32 r)
(if-let $true (has_b))
(alu_rr_funct12 (AluOPRRI.Clzw) r))
;;; for I8 and I16
(rule 1
(lower_clz ty r)
(if-let $true (has_b))
(let
( ;; narrow int make all upper bits are zeros.
(tmp Reg (ext_int_if_need $false r ty ))
;;
(count Reg (alu_rr_funct12 (AluOPRRI.Clz) tmp))
;;make result
(result Reg (alu_rr_imm12 (AluOPRRI.Addi) count (imm12_const_add (ty_bits ty) -64))))
result))
// Generated as internal constructor for term lower_clz.
pub fn constructor_lower_clz<C: Context>(ctx: &mut C, arg0: Type, arg1: Reg) -> Option<Reg> {
let pattern0_0 = arg0;
if pattern0_0 == I32 {
let pattern2_0 = arg1;
let mut closure3 = || {
let expr0_0 = C::has_b(ctx)?;
return Some(expr0_0);
};
if let Some(pattern3_0) = closure3() {
if pattern3_0 == true {
// Rule at src\isa\riscv64\inst.isle line 963.
let expr0_0 = AluOPRRI::Clzw;
let expr1_0 = constructor_alu_rr_funct12(ctx, &expr0_0, pattern2_0)?;
return Some(expr1_0);
}
}
}
if pattern0_0 == I64 {
let pattern2_0 = arg1;
let mut closure3 = || {
let expr0_0 = C::has_b(ctx)?;
return Some(expr0_0);
};
if let Some(pattern3_0) = closure3() {
if pattern3_0 == true {
// Rule at src\isa\riscv64\inst.isle line 959.
let expr0_0 = AluOPRRI::Clz;
let expr1_0 = constructor_alu_rr_funct12(ctx, &expr0_0, pattern2_0)?;
return Some(expr1_0);
}
}
}
let pattern0_0 = arg0;
let pattern1_0 = arg1;
let mut closure2 = || {
let expr0_0 = C::has_b(ctx)?;
return Some(expr0_0);
};
if let Some(pattern2_0) = closure2() {
if pattern2_0 == true {
// Rule at src\isa\riscv64\inst.isle line 969.
let expr0_0: bool = false;
let expr1_0 = C::value_reg(ctx, pattern1_0);
let expr2_0 = constructor_ext_int_if_need(ctx, expr0_0, expr1_0, pattern0_0)?;
let expr3_0 = constructor_convert_valueregs_reg(ctx, expr2_0)?;
let expr4_0 = AluOPRRI::Clz;
let expr5_0 = constructor_alu_rr_funct12(ctx, &expr4_0, expr3_0)?;
let expr6_0 = AluOPRRI::Addi;
let expr7_0 = C::ty_bits(ctx, pattern0_0)?;
let expr8_0 = C::u8_as_i32(ctx, expr7_0);
let expr9_0: i32 = -64i128 as i32;
let expr10_0 = C::imm12_const_add(ctx, expr8_0, expr9_0);
let expr11_0 = constructor_alu_rr_imm12(ctx, &expr6_0, expr5_0, expr10_0)?;
return Some(expr11_0);
}
}
let pattern0_0 = arg0;
let pattern1_0 = arg1;
let mut closure2 = || {
let expr0_0 = C::has_b(ctx)?;
return Some(expr0_0);
};
if let Some(pattern2_0) = closure2() {
if pattern2_0 == false {
// Rule at src\isa\riscv64\inst.isle line 956.
let expr0_0: bool = true;
let expr1_0 = constructor_gen_cltz(ctx, expr0_0, pattern1_0, pattern0_0)?;
return Some(expr1_0);
}
}
return None;
}