diff --git a/cranelift/codegen/src/isa/pulley_shared/inst.isle b/cranelift/codegen/src/isa/pulley_shared/inst.isle index a27d421abd7a..0da137f4aaed 100644 --- a/cranelift/codegen/src/isa/pulley_shared/inst.isle +++ b/cranelift/codegen/src/isa/pulley_shared/inst.isle @@ -109,6 +109,17 @@ (IfXult32 (src1 XReg) (src2 XReg)) (IfXulteq32 (src1 XReg) (src2 XReg)) + (IfXeq32I32 (src1 XReg) (src2 i32)) + (IfXneq32I32 (src1 XReg) (src2 i32)) + (IfXslt32I32 (src1 XReg) (src2 i32)) + (IfXslteq32I32 (src1 XReg) (src2 i32)) + (IfXult32I32 (src1 XReg) (src2 u32)) + (IfXulteq32I32 (src1 XReg) (src2 u32)) + (IfXsgt32I32 (src1 XReg) (src2 i32)) + (IfXsgteq32I32 (src1 XReg) (src2 i32)) + (IfXugt32I32 (src1 XReg) (src2 u32)) + (IfXugteq32I32 (src1 XReg) (src2 u32)) + ;; Conditionals for comparing two 64-bit registers. (IfXeq64 (src1 XReg) (src2 XReg)) (IfXneq64 (src1 XReg) (src2 XReg)) @@ -116,6 +127,17 @@ (IfXslteq64 (src1 XReg) (src2 XReg)) (IfXult64 (src1 XReg) (src2 XReg)) (IfXulteq64 (src1 XReg) (src2 XReg)) + + (IfXeq64I32 (src1 XReg) (src2 i32)) + (IfXneq64I32 (src1 XReg) (src2 i32)) + (IfXslt64I32 (src1 XReg) (src2 i32)) + (IfXslteq64I32 (src1 XReg) (src2 i32)) + (IfXult64I32 (src1 XReg) (src2 u32)) + (IfXulteq64I32 (src1 XReg) (src2 u32)) + (IfXsgt64I32 (src1 XReg) (src2 i32)) + (IfXsgteq64I32 (src1 XReg) (src2 i32)) + (IfXugt64I32 (src1 XReg) (src2 u32)) + (IfXugteq64I32 (src1 XReg) (src2 u32)) ) ) diff --git a/cranelift/codegen/src/isa/pulley_shared/inst/args.rs b/cranelift/codegen/src/isa/pulley_shared/inst/args.rs index d28ae9c9d1dc..cb7496336341 100644 --- a/cranelift/codegen/src/isa/pulley_shared/inst/args.rs +++ b/cranelift/codegen/src/isa/pulley_shared/inst/args.rs @@ -255,6 +255,34 @@ impl Cond { collector.reg_use(src1); collector.reg_use(src2); } + + Cond::IfXeq32I32 { src1, src2 } + | Cond::IfXneq32I32 { src1, src2 } + | Cond::IfXslt32I32 { src1, src2 } + | Cond::IfXslteq32I32 { src1, src2 } + | Cond::IfXsgt32I32 { src1, src2 } + | Cond::IfXsgteq32I32 { src1, src2 } + | Cond::IfXeq64I32 { src1, src2 } + | Cond::IfXneq64I32 { src1, src2 } + | Cond::IfXslt64I32 { src1, src2 } + | Cond::IfXslteq64I32 { src1, src2 } + | Cond::IfXsgt64I32 { src1, src2 } + | Cond::IfXsgteq64I32 { src1, src2 } => { + collector.reg_use(src1); + let _: &mut i32 = src2; + } + + Cond::IfXult32I32 { src1, src2 } + | Cond::IfXulteq32I32 { src1, src2 } + | Cond::IfXugt32I32 { src1, src2 } + | Cond::IfXugteq32I32 { src1, src2 } + | Cond::IfXult64I32 { src1, src2 } + | Cond::IfXulteq64I32 { src1, src2 } + | Cond::IfXugt64I32 { src1, src2 } + | Cond::IfXugteq64I32 { src1, src2 } => { + collector.reg_use(src1); + let _: &mut u32 = src2; + } } } @@ -263,7 +291,7 @@ impl Cond { /// Note that the offset encoded to jump by is filled in as 0 and it's /// assumed `MachBuffer` will come back and clean it up. pub fn encode(&self, sink: &mut impl Extend) { - match self { + match *self { Cond::If32 { reg } => encode::br_if32(sink, reg, 0), Cond::IfNot32 { reg } => encode::br_if_not32(sink, reg, 0), Cond::IfXeq32 { src1, src2 } => encode::br_if_xeq32(sink, src1, src2, 0), @@ -278,6 +306,88 @@ impl Cond { Cond::IfXslteq64 { src1, src2 } => encode::br_if_xslteq64(sink, src1, src2, 0), Cond::IfXult64 { src1, src2 } => encode::br_if_xult64(sink, src1, src2, 0), Cond::IfXulteq64 { src1, src2 } => encode::br_if_xulteq64(sink, src1, src2, 0), + + Cond::IfXeq32I32 { src1, src2 } => match i8::try_from(src2) { + Ok(src2) => encode::br_if_xeq32_i8(sink, src1, src2, 0), + Err(_) => encode::br_if_xeq32_i32(sink, src1, src2, 0), + }, + Cond::IfXneq32I32 { src1, src2 } => match i8::try_from(src2) { + Ok(src2) => encode::br_if_xneq32_i8(sink, src1, src2, 0), + Err(_) => encode::br_if_xneq32_i32(sink, src1, src2, 0), + }, + Cond::IfXslt32I32 { src1, src2 } => match i8::try_from(src2) { + Ok(src2) => encode::br_if_xslt32_i8(sink, src1, src2, 0), + Err(_) => encode::br_if_xslt32_i32(sink, src1, src2, 0), + }, + Cond::IfXslteq32I32 { src1, src2 } => match i8::try_from(src2) { + Ok(src2) => encode::br_if_xslteq32_i8(sink, src1, src2, 0), + Err(_) => encode::br_if_xslteq32_i32(sink, src1, src2, 0), + }, + Cond::IfXsgt32I32 { src1, src2 } => match i8::try_from(src2) { + Ok(src2) => encode::br_if_xsgt32_i8(sink, src1, src2, 0), + Err(_) => encode::br_if_xsgt32_i32(sink, src1, src2, 0), + }, + Cond::IfXsgteq32I32 { src1, src2 } => match i8::try_from(src2) { + Ok(src2) => encode::br_if_xsgteq32_i8(sink, src1, src2, 0), + Err(_) => encode::br_if_xsgteq32_i32(sink, src1, src2, 0), + }, + Cond::IfXult32I32 { src1, src2 } => match u8::try_from(src2) { + Ok(src2) => encode::br_if_xult32_u8(sink, src1, src2, 0), + Err(_) => encode::br_if_xult32_u32(sink, src1, src2, 0), + }, + Cond::IfXulteq32I32 { src1, src2 } => match u8::try_from(src2) { + Ok(src2) => encode::br_if_xulteq32_u8(sink, src1, src2, 0), + Err(_) => encode::br_if_xulteq32_u32(sink, src1, src2, 0), + }, + Cond::IfXugt32I32 { src1, src2 } => match u8::try_from(src2) { + Ok(src2) => encode::br_if_xugt32_u8(sink, src1, src2, 0), + Err(_) => encode::br_if_xugt32_u32(sink, src1, src2, 0), + }, + Cond::IfXugteq32I32 { src1, src2 } => match u8::try_from(src2) { + Ok(src2) => encode::br_if_xugteq32_u8(sink, src1, src2, 0), + Err(_) => encode::br_if_xugteq32_u32(sink, src1, src2, 0), + }, + + Cond::IfXeq64I32 { src1, src2 } => match i8::try_from(src2) { + Ok(src2) => encode::br_if_xeq64_i8(sink, src1, src2, 0), + Err(_) => encode::br_if_xeq64_i32(sink, src1, src2, 0), + }, + Cond::IfXneq64I32 { src1, src2 } => match i8::try_from(src2) { + Ok(src2) => encode::br_if_xneq64_i8(sink, src1, src2, 0), + Err(_) => encode::br_if_xneq64_i32(sink, src1, src2, 0), + }, + Cond::IfXslt64I32 { src1, src2 } => match i8::try_from(src2) { + Ok(src2) => encode::br_if_xslt64_i8(sink, src1, src2, 0), + Err(_) => encode::br_if_xslt64_i32(sink, src1, src2, 0), + }, + Cond::IfXslteq64I32 { src1, src2 } => match i8::try_from(src2) { + Ok(src2) => encode::br_if_xslteq64_i8(sink, src1, src2, 0), + Err(_) => encode::br_if_xslteq64_i32(sink, src1, src2, 0), + }, + Cond::IfXsgt64I32 { src1, src2 } => match i8::try_from(src2) { + Ok(src2) => encode::br_if_xsgt64_i8(sink, src1, src2, 0), + Err(_) => encode::br_if_xsgt64_i32(sink, src1, src2, 0), + }, + Cond::IfXsgteq64I32 { src1, src2 } => match i8::try_from(src2) { + Ok(src2) => encode::br_if_xsgteq64_i8(sink, src1, src2, 0), + Err(_) => encode::br_if_xsgteq64_i32(sink, src1, src2, 0), + }, + Cond::IfXult64I32 { src1, src2 } => match u8::try_from(src2) { + Ok(src2) => encode::br_if_xult64_u8(sink, src1, src2, 0), + Err(_) => encode::br_if_xult64_u32(sink, src1, src2, 0), + }, + Cond::IfXulteq64I32 { src1, src2 } => match u8::try_from(src2) { + Ok(src2) => encode::br_if_xulteq64_u8(sink, src1, src2, 0), + Err(_) => encode::br_if_xulteq64_u32(sink, src1, src2, 0), + }, + Cond::IfXugt64I32 { src1, src2 } => match u8::try_from(src2) { + Ok(src2) => encode::br_if_xugt64_u8(sink, src1, src2, 0), + Err(_) => encode::br_if_xugt64_u32(sink, src1, src2, 0), + }, + Cond::IfXugteq64I32 { src1, src2 } => match u8::try_from(src2) { + Ok(src2) => encode::br_if_xugteq64_u8(sink, src1, src2, 0), + Err(_) => encode::br_if_xugteq64_u32(sink, src1, src2, 0), + }, } } @@ -325,6 +435,28 @@ impl Cond { src1: src2, src2: src1, }, + + Cond::IfXeq32I32 { src1, src2 } => Cond::IfXneq32I32 { src1, src2 }, + Cond::IfXneq32I32 { src1, src2 } => Cond::IfXeq32I32 { src1, src2 }, + Cond::IfXslt32I32 { src1, src2 } => Cond::IfXsgteq32I32 { src1, src2 }, + Cond::IfXslteq32I32 { src1, src2 } => Cond::IfXsgt32I32 { src1, src2 }, + Cond::IfXult32I32 { src1, src2 } => Cond::IfXugteq32I32 { src1, src2 }, + Cond::IfXulteq32I32 { src1, src2 } => Cond::IfXugt32I32 { src1, src2 }, + Cond::IfXsgt32I32 { src1, src2 } => Cond::IfXslteq32I32 { src1, src2 }, + Cond::IfXsgteq32I32 { src1, src2 } => Cond::IfXslt32I32 { src1, src2 }, + Cond::IfXugt32I32 { src1, src2 } => Cond::IfXulteq32I32 { src1, src2 }, + Cond::IfXugteq32I32 { src1, src2 } => Cond::IfXult32I32 { src1, src2 }, + + Cond::IfXeq64I32 { src1, src2 } => Cond::IfXneq64I32 { src1, src2 }, + Cond::IfXneq64I32 { src1, src2 } => Cond::IfXeq64I32 { src1, src2 }, + Cond::IfXslt64I32 { src1, src2 } => Cond::IfXsgteq64I32 { src1, src2 }, + Cond::IfXslteq64I32 { src1, src2 } => Cond::IfXsgt64I32 { src1, src2 }, + Cond::IfXult64I32 { src1, src2 } => Cond::IfXugteq64I32 { src1, src2 }, + Cond::IfXulteq64I32 { src1, src2 } => Cond::IfXugt64I32 { src1, src2 }, + Cond::IfXsgt64I32 { src1, src2 } => Cond::IfXslteq64I32 { src1, src2 }, + Cond::IfXsgteq64I32 { src1, src2 } => Cond::IfXslt64I32 { src1, src2 }, + Cond::IfXugt64I32 { src1, src2 } => Cond::IfXulteq64I32 { src1, src2 }, + Cond::IfXugteq64I32 { src1, src2 } => Cond::IfXult64I32 { src1, src2 }, } } } @@ -370,6 +502,66 @@ impl fmt::Display for Cond { Cond::IfXulteq64 { src1, src2 } => { write!(f, "if_xulteq64 {}, {}", reg_name(**src1), reg_name(**src2)) } + Cond::IfXeq32I32 { src1, src2 } => { + write!(f, "if_xeq32_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXneq32I32 { src1, src2 } => { + write!(f, "if_xneq32_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXslt32I32 { src1, src2 } => { + write!(f, "if_xslt32_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXslteq32I32 { src1, src2 } => { + write!(f, "if_xslteq32_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXsgt32I32 { src1, src2 } => { + write!(f, "if_xsgt32_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXsgteq32I32 { src1, src2 } => { + write!(f, "if_xsgteq32_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXult32I32 { src1, src2 } => { + write!(f, "if_xult32_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXulteq32I32 { src1, src2 } => { + write!(f, "if_xulteq32_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXugt32I32 { src1, src2 } => { + write!(f, "if_xugt32_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXugteq32I32 { src1, src2 } => { + write!(f, "if_xugteq32_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXeq64I32 { src1, src2 } => { + write!(f, "if_xeq64_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXneq64I32 { src1, src2 } => { + write!(f, "if_xneq64_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXslt64I32 { src1, src2 } => { + write!(f, "if_xslt64_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXslteq64I32 { src1, src2 } => { + write!(f, "if_xslteq64_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXsgt64I32 { src1, src2 } => { + write!(f, "if_xsgt64_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXsgteq64I32 { src1, src2 } => { + write!(f, "if_xsgteq64_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXult64I32 { src1, src2 } => { + write!(f, "if_xult64_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXulteq64I32 { src1, src2 } => { + write!(f, "if_xulteq64_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXugt64I32 { src1, src2 } => { + write!(f, "if_xugt64_i32 {}, {src2}", reg_name(**src1)) + } + Cond::IfXugteq64I32 { src1, src2 } => { + write!(f, "if_xugteq64_i32 {}, {src2}", reg_name(**src1)) + } } } } diff --git a/cranelift/codegen/src/isa/pulley_shared/lower.isle b/cranelift/codegen/src/isa/pulley_shared/lower.isle index 5b14f38fc01b..03bacddc78ed 100644 --- a/cranelift/codegen/src/isa/pulley_shared/lower.isle +++ b/cranelift/codegen/src/isa/pulley_shared/lower.isle @@ -35,6 +35,27 @@ (rule (lower_cond_icmp32 (IntCC.UnsignedGreaterThan) a b) (Cond.IfXult32 b a)) (rule (lower_cond_icmp32 (IntCC.UnsignedGreaterThanOrEqual) a b) (Cond.IfXulteq32 b a)) +(rule 1 (lower_cond_icmp32 (IntCC.Equal) a (i32_from_iconst b)) + (Cond.IfXeq32I32 a b)) +(rule 1 (lower_cond_icmp32 (IntCC.NotEqual) a (i32_from_iconst b)) + (Cond.IfXneq32I32 a b)) +(rule 1 (lower_cond_icmp32 (IntCC.SignedLessThan) a (i32_from_iconst b)) + (Cond.IfXslt32I32 a b)) +(rule 1 (lower_cond_icmp32 (IntCC.SignedLessThanOrEqual) a (i32_from_iconst b)) + (Cond.IfXslteq32I32 a b)) +(rule 1 (lower_cond_icmp32 (IntCC.SignedGreaterThan) a (i32_from_iconst b)) + (Cond.IfXsgt32I32 a b)) +(rule 1 (lower_cond_icmp32 (IntCC.SignedGreaterThanOrEqual) a (i32_from_iconst b)) + (Cond.IfXsgteq32I32 a b)) +(rule 1 (lower_cond_icmp32 (IntCC.UnsignedLessThan) a (u32_from_iconst b)) + (Cond.IfXult32I32 a b)) +(rule 1 (lower_cond_icmp32 (IntCC.UnsignedLessThanOrEqual) a (u32_from_iconst b)) + (Cond.IfXulteq32I32 a b)) +(rule 1 (lower_cond_icmp32 (IntCC.UnsignedGreaterThan) a (u32_from_iconst b)) + (Cond.IfXugt32I32 a b)) +(rule 1 (lower_cond_icmp32 (IntCC.UnsignedGreaterThanOrEqual) a (u32_from_iconst b)) + (Cond.IfXugteq32I32 a b)) + (decl lower_cond_icmp64 (IntCC Value Value) Cond) (rule (lower_cond_icmp64 (IntCC.Equal) a b) (Cond.IfXeq64 a b)) (rule (lower_cond_icmp64 (IntCC.NotEqual) a b) (Cond.IfXneq64 a b)) @@ -48,6 +69,27 @@ (rule (lower_cond_icmp64 (IntCC.UnsignedGreaterThan) a b) (Cond.IfXult64 b a)) (rule (lower_cond_icmp64 (IntCC.UnsignedGreaterThanOrEqual) a b) (Cond.IfXulteq64 b a)) +(rule 1 (lower_cond_icmp64 (IntCC.Equal) a (i32_from_iconst b)) + (Cond.IfXeq64I32 a b)) +(rule 1 (lower_cond_icmp64 (IntCC.NotEqual) a (i32_from_iconst b)) + (Cond.IfXneq64I32 a b)) +(rule 1 (lower_cond_icmp64 (IntCC.SignedLessThan) a (i32_from_iconst b)) + (Cond.IfXslt64I32 a b)) +(rule 1 (lower_cond_icmp64 (IntCC.SignedLessThanOrEqual) a (i32_from_iconst b)) + (Cond.IfXslteq64I32 a b)) +(rule 1 (lower_cond_icmp64 (IntCC.SignedGreaterThan) a (i32_from_iconst b)) + (Cond.IfXsgt64I32 a b)) +(rule 1 (lower_cond_icmp64 (IntCC.SignedGreaterThanOrEqual) a (i32_from_iconst b)) + (Cond.IfXsgteq64I32 a b)) +(rule 1 (lower_cond_icmp64 (IntCC.UnsignedLessThan) a (u32_from_iconst b)) + (Cond.IfXult64I32 a b)) +(rule 1 (lower_cond_icmp64 (IntCC.UnsignedLessThanOrEqual) a (u32_from_iconst b)) + (Cond.IfXulteq64I32 a b)) +(rule 1 (lower_cond_icmp64 (IntCC.UnsignedGreaterThan) a (u32_from_iconst b)) + (Cond.IfXugt64I32 a b)) +(rule 1 (lower_cond_icmp64 (IntCC.UnsignedGreaterThanOrEqual) a (u32_from_iconst b)) + (Cond.IfXugteq64I32 a b)) + ;; The main control-flow-lowering term: takes a control-flow instruction and ;; target(s) and emits the necessary instructions. (decl partial lower_branch (Inst MachLabelSlice) Unit) @@ -880,6 +922,52 @@ (rule (emit_cond (Cond.IfXult64 src1 src2)) (pulley_xult64 src1 src2)) (rule (emit_cond (Cond.IfXulteq64 src1 src2)) (pulley_xulteq64 src1 src2)) +(rule (emit_cond (Cond.IfXeq32I32 src1 src2)) + (pulley_xeq32 src1 (imm $I32 (i64_as_u64 (i32_as_i64 src2))))) +(rule (emit_cond (Cond.IfXneq32I32 src1 src2)) + (pulley_xneq32 src1 (imm $I32 (i64_as_u64 (i32_as_i64 src2))))) +(rule (emit_cond (Cond.IfXslt32I32 src1 src2)) + (pulley_xslt32 src1 (imm $I32 (i64_as_u64 (i32_as_i64 src2))))) +(rule (emit_cond (Cond.IfXslteq32I32 src1 src2)) + (pulley_xslteq32 src1 (imm $I32 (i64_as_u64 (i32_as_i64 src2))))) +(rule (emit_cond (Cond.IfXult32I32 src1 src2)) + (pulley_xult32 src1 (imm $I32 (u32_as_u64 src2)))) +(rule (emit_cond (Cond.IfXulteq32I32 src1 src2)) + (pulley_xulteq32 src1 (imm $I32 (u32_as_u64 src2)))) + +;; Note the operand swaps here +(rule (emit_cond (Cond.IfXsgt32I32 src1 src2)) + (pulley_xslteq32 (imm $I32 (i64_as_u64 (i32_as_i64 src2))) src1)) +(rule (emit_cond (Cond.IfXsgteq32I32 src1 src2)) + (pulley_xslt32 (imm $I32 (i64_as_u64 (i32_as_i64 src2))) src1)) +(rule (emit_cond (Cond.IfXugt32I32 src1 src2)) + (pulley_xulteq32 (imm $I32 (u32_as_u64 src2)) src1)) +(rule (emit_cond (Cond.IfXugteq32I32 src1 src2)) + (pulley_xult32 (imm $I32 (u32_as_u64 src2)) src1)) + +(rule (emit_cond (Cond.IfXeq64I32 src1 src2)) + (pulley_xeq64 src1 (imm $I64 (i64_as_u64 (i32_as_i64 src2))))) +(rule (emit_cond (Cond.IfXneq64I32 src1 src2)) + (pulley_xneq64 src1 (imm $I64 (i64_as_u64 (i32_as_i64 src2))))) +(rule (emit_cond (Cond.IfXslt64I32 src1 src2)) + (pulley_xslt64 src1 (imm $I64 (i64_as_u64 (i32_as_i64 src2))))) +(rule (emit_cond (Cond.IfXslteq64I32 src1 src2)) + (pulley_xslteq64 src1 (imm $I64 (i64_as_u64 (i32_as_i64 src2))))) +(rule (emit_cond (Cond.IfXult64I32 src1 src2)) + (pulley_xult64 src1 (imm $I64 (u32_as_u64 src2)))) +(rule (emit_cond (Cond.IfXulteq64I32 src1 src2)) + (pulley_xulteq64 src1 (imm $I64 (u32_as_u64 src2)))) + +;; Note the operand swaps here +(rule (emit_cond (Cond.IfXsgt64I32 src1 src2)) + (pulley_xslteq64 (imm $I64 (i64_as_u64 (i32_as_i64 src2))) src1)) +(rule (emit_cond (Cond.IfXsgteq64I32 src1 src2)) + (pulley_xslt64 (imm $I64 (i64_as_u64 (i32_as_i64 src2))) src1)) +(rule (emit_cond (Cond.IfXugt64I32 src1 src2)) + (pulley_xulteq64 (imm $I64 (u32_as_u64 src2)) src1)) +(rule (emit_cond (Cond.IfXugteq64I32 src1 src2)) + (pulley_xult64 (imm $I64 (u32_as_u64 src2)) src1)) + ;;;; Rules for `bitcast` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (rule (lower (has_type $F32 (bitcast _flags val @ (value_type $I32)))) diff --git a/cranelift/filetests/filetests/isa/pulley32/brif.clif b/cranelift/filetests/filetests/isa/pulley32/brif.clif index b7c86f7513c1..f342c34b08ea 100644 --- a/cranelift/filetests/filetests/isa/pulley32/brif.clif +++ b/cranelift/filetests/filetests/isa/pulley32/brif.clif @@ -267,3 +267,126 @@ block2: ; xconst8 x0, 1 ; ret +function %brif_icmp_i32_imm(i32) -> i8 { +block0(v0: i32): + v2 = icmp_imm slt v0, 10 + brif v2, block1, block2 + +block1: + v3 = iconst.i8 1 + return v3 + +block2: + v4 = iconst.i8 0 + return v4 +} + +; VCode: +; block0: +; br_if_xslt32_i32 x0, 10, label2; jump label1 +; block1: +; xconst8 x0, 0 +; ret +; block2: +; xconst8 x0, 1 +; ret +; +; Disassembled: +; br_if_xslt32_i8 x0, 10, 0xb // target = 0xb +; xconst8 x0, 0 +; ret +; xconst8 x0, 1 +; ret + +function %brif_icmp_i32_imm_big(i32) -> i8 { +block0(v0: i32): + v2 = icmp_imm slt v0, 88888 + brif v2, block1, block2 + +block1: + v3 = iconst.i8 1 + return v3 + +block2: + v4 = iconst.i8 0 + return v4 +} + +; VCode: +; block0: +; br_if_xslt32_i32 x0, 88888, label2; jump label1 +; block1: +; xconst8 x0, 0 +; ret +; block2: +; xconst8 x0, 1 +; ret +; +; Disassembled: +; br_if_xslt32_i32 x0, 88888, 0xe // target = 0xe +; xconst8 x0, 0 +; ret +; xconst8 x0, 1 +; ret + +function %brif_icmp_i64_imm(i64) -> i8 { +block0(v0: i64): + v2 = icmp_imm slt v0, 10 + brif v2, block1, block2 + +block1: + v3 = iconst.i8 1 + return v3 + +block2: + v4 = iconst.i8 0 + return v4 +} + +; VCode: +; block0: +; br_if_xslt64_i32 x0, 10, label2; jump label1 +; block1: +; xconst8 x0, 0 +; ret +; block2: +; xconst8 x0, 1 +; ret +; +; Disassembled: +; br_if_xslt64_i8 x0, 10, 0xb // target = 0xb +; xconst8 x0, 0 +; ret +; xconst8 x0, 1 +; ret + +function %brif_icmp_i64_imm_big(i64) -> i8 { +block0(v0: i64): + v2 = icmp_imm slt v0, 88888 + brif v2, block1, block2 + +block1: + v3 = iconst.i8 1 + return v3 + +block2: + v4 = iconst.i8 0 + return v4 +} + +; VCode: +; block0: +; br_if_xslt64_i32 x0, 88888, label2; jump label1 +; block1: +; xconst8 x0, 0 +; ret +; block2: +; xconst8 x0, 1 +; ret +; +; Disassembled: +; br_if_xslt64_i32 x0, 88888, 0xe // target = 0xe +; xconst8 x0, 0 +; ret +; xconst8 x0, 1 +; ret diff --git a/cranelift/filetests/filetests/isa/pulley32/trap.clif b/cranelift/filetests/filetests/isa/pulley32/trap.clif index f11b1f2de43e..7bd7ba27fbae 100644 --- a/cranelift/filetests/filetests/isa/pulley32/trap.clif +++ b/cranelift/filetests/filetests/isa/pulley32/trap.clif @@ -23,13 +23,11 @@ block0(v0: i64): ; VCode: ; block0: -; xconst8 x2, 42 -; trap_if_xeq64 x0, x2 // code = TrapCode(1) +; trap_if_xeq64_i32 x0, 42 // code = TrapCode(1) ; ret ; ; Disassembled: -; xconst8 x2, 42 -; br_if_xeq64 x0, x2, 0x8 // target = 0xb +; br_if_xeq64_i8 x0, 42, 0x8 // target = 0x8 ; ret ; trap @@ -43,13 +41,11 @@ block0(v0: i64): ; VCode: ; block0: -; xconst8 x2, 42 -; trap_if_xneq64 x0, x2 // code = TrapCode(1) +; trap_if_xneq64_i32 x0, 42 // code = TrapCode(1) ; ret ; ; Disassembled: -; xconst8 x2, 42 -; br_if_xneq64 x0, x2, 0x8 // target = 0xb +; br_if_xneq64_i8 x0, 42, 0x8 // target = 0x8 ; ret ; trap @@ -63,13 +59,11 @@ block0(v0: i64): ; VCode: ; block0: -; xconst8 x2, 42 -; trap_if_xeq64 x0, x2 // code = TrapCode(1) +; trap_if_xeq64_i32 x0, 42 // code = TrapCode(1) ; ret ; ; Disassembled: -; xconst8 x2, 42 -; br_if_xeq64 x0, x2, 0x8 // target = 0xb +; br_if_xeq64_i8 x0, 42, 0x8 // target = 0x8 ; ret ; trap @@ -83,13 +77,11 @@ block0(v0: i64): ; VCode: ; block0: -; xconst8 x2, 42 -; trap_if_xneq64 x0, x2 // code = TrapCode(1) +; trap_if_xneq64_i32 x0, 42 // code = TrapCode(1) ; ret ; ; Disassembled: -; xconst8 x2, 42 -; br_if_xneq64 x0, x2, 0x8 // target = 0xb +; br_if_xneq64_i8 x0, 42, 0x8 // target = 0x8 ; ret ; trap diff --git a/cranelift/filetests/filetests/isa/pulley64/trap.clif b/cranelift/filetests/filetests/isa/pulley64/trap.clif index e343de871480..d38ac59dd9f1 100644 --- a/cranelift/filetests/filetests/isa/pulley64/trap.clif +++ b/cranelift/filetests/filetests/isa/pulley64/trap.clif @@ -23,13 +23,11 @@ block0(v0: i64): ; VCode: ; block0: -; xconst8 x2, 42 -; trap_if_xeq64 x0, x2 // code = TrapCode(1) +; trap_if_xeq64_i32 x0, 42 // code = TrapCode(1) ; ret ; ; Disassembled: -; xconst8 x2, 42 -; br_if_xeq64 x0, x2, 0x8 // target = 0xb +; br_if_xeq64_i8 x0, 42, 0x8 // target = 0x8 ; ret ; trap @@ -43,13 +41,11 @@ block0(v0: i64): ; VCode: ; block0: -; xconst8 x2, 42 -; trap_if_xneq64 x0, x2 // code = TrapCode(1) +; trap_if_xneq64_i32 x0, 42 // code = TrapCode(1) ; ret ; ; Disassembled: -; xconst8 x2, 42 -; br_if_xneq64 x0, x2, 0x8 // target = 0xb +; br_if_xneq64_i8 x0, 42, 0x8 // target = 0x8 ; ret ; trap @@ -63,13 +59,11 @@ block0(v0: i64): ; VCode: ; block0: -; xconst8 x2, 42 -; trap_if_xeq64 x0, x2 // code = TrapCode(1) +; trap_if_xeq64_i32 x0, 42 // code = TrapCode(1) ; ret ; ; Disassembled: -; xconst8 x2, 42 -; br_if_xeq64 x0, x2, 0x8 // target = 0xb +; br_if_xeq64_i8 x0, 42, 0x8 // target = 0x8 ; ret ; trap @@ -83,13 +77,11 @@ block0(v0: i64): ; VCode: ; block0: -; xconst8 x2, 42 -; trap_if_xneq64 x0, x2 // code = TrapCode(1) +; trap_if_xneq64_i32 x0, 42 // code = TrapCode(1) ; ret ; ; Disassembled: -; xconst8 x2, 42 -; br_if_xneq64 x0, x2, 0x8 // target = 0xb +; br_if_xneq64_i8 x0, 42, 0x8 // target = 0x8 ; ret ; trap diff --git a/pulley/src/interp.rs b/pulley/src/interp.rs index b87ad44a3eac..fe32ea75d6ac 100644 --- a/pulley/src/interp.rs +++ b/pulley/src/interp.rs @@ -1024,6 +1024,22 @@ fn simple_push_pop() { } } +macro_rules! br_if_imm { + ($( + fn $snake:ident(&mut self, a: XReg, b: $imm:ident, offset: PcRelOffset) + = $camel:ident / $op:tt / $get:ident; + )*) => {$( + fn $snake(&mut self, a: XReg, b: $imm, offset: PcRelOffset) -> ControlFlow { + let a = self.state[a].$get(); + if a $op b.into() { + self.pc_rel_jump::(offset) + } else { + ControlFlow::Continue(()) + } + } + )*}; +} + impl OpVisitor for Interpreter<'_> { type BytecodeStream = UnsafeBytecodeStream; type Return = ControlFlow; @@ -1211,6 +1227,94 @@ impl OpVisitor for Interpreter<'_> { } } + br_if_imm! { + fn br_if_xeq32_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset) + = BrIfXeq32I8 / == / get_i32; + fn br_if_xeq32_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset) + = BrIfXeq32I32 / == / get_i32; + fn br_if_xneq32_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset) + = BrIfXneq32I8 / != / get_i32; + fn br_if_xneq32_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset) + = BrIfXneq32I32 / != / get_i32; + + fn br_if_xslt32_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset) + = BrIfXslt32I8 / < / get_i32; + fn br_if_xslt32_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset) + = BrIfXslt32I32 / < / get_i32; + fn br_if_xsgt32_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset) + = BrIfXsgt32I8 / > / get_i32; + fn br_if_xsgt32_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset) + = BrIfXsgt32I32 / > / get_i32; + fn br_if_xslteq32_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset) + = BrIfXslteq32I8 / <= / get_i32; + fn br_if_xslteq32_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset) + = BrIfXslteq32I32 / <= / get_i32; + fn br_if_xsgteq32_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset) + = BrIfXsgteq32I8 / >= / get_i32; + fn br_if_xsgteq32_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset) + = BrIfXsgteq32I32 / >= / get_i32; + + fn br_if_xult32_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset) + = BrIfXult32U8 / < / get_u32; + fn br_if_xult32_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset) + = BrIfXult32U32 / < / get_u32; + fn br_if_xugt32_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset) + = BrIfXugt32U8 / > / get_u32; + fn br_if_xugt32_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset) + = BrIfXugt32U32 / > / get_u32; + fn br_if_xulteq32_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset) + = BrIfXulteq32U8 / <= / get_u32; + fn br_if_xulteq32_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset) + = BrIfXulteq32U32 / <= / get_u32; + fn br_if_xugteq32_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset) + = BrIfXugteq32U8 / >= / get_u32; + fn br_if_xugteq32_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset) + = BrIfXugteq32U32 / >= / get_u32; + + fn br_if_xeq64_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset) + = BrIfXeq64I8 / == / get_i64; + fn br_if_xeq64_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset) + = BrIfXeq64I32 / == / get_i64; + fn br_if_xneq64_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset) + = BrIfXneq64I8 / != / get_i64; + fn br_if_xneq64_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset) + = BrIfXneq64I32 / != / get_i64; + + fn br_if_xslt64_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset) + = BrIfXslt64I8 / < / get_i64; + fn br_if_xslt64_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset) + = BrIfXslt64I32 / < / get_i64; + fn br_if_xsgt64_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset) + = BrIfXsgt64I8 / > / get_i64; + fn br_if_xsgt64_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset) + = BrIfXsgt64I32 / > / get_i64; + fn br_if_xslteq64_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset) + = BrIfXslteq64I8 / <= / get_i64; + fn br_if_xslteq64_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset) + = BrIfXslteq64I32 / <= / get_i64; + fn br_if_xsgteq64_i8(&mut self, a: XReg, b: i8, offset: PcRelOffset) + = BrIfXsgteq64I8 / >= / get_i64; + fn br_if_xsgteq64_i32(&mut self, a: XReg, b: i32, offset: PcRelOffset) + = BrIfXsgteq64I32 / >= / get_i64; + + fn br_if_xult64_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset) + = BrIfXult64U8 / < / get_u64; + fn br_if_xult64_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset) + = BrIfXult64U32 / < / get_u64; + fn br_if_xugt64_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset) + = BrIfXugt64U8 / > / get_u64; + fn br_if_xugt64_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset) + = BrIfXugt64U32 / > / get_u64; + fn br_if_xulteq64_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset) + = BrIfXulteq64U8 / <= / get_u64; + fn br_if_xulteq64_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset) + = BrIfXulteq64U32 / <= / get_u64; + fn br_if_xugteq64_u8(&mut self, a: XReg, b: u8, offset: PcRelOffset) + = BrIfXugteq64U8 / >= / get_u64; + fn br_if_xugteq64_u32(&mut self, a: XReg, b: u32, offset: PcRelOffset) + = BrIfXugteq64U32 / >= / get_u64; + } + fn xmov(&mut self, dst: XReg, src: XReg) -> ControlFlow { let val = self.state[src]; self.state[dst] = val; diff --git a/pulley/src/lib.rs b/pulley/src/lib.rs index 37fb02c78ddf..f87388f2f59c 100644 --- a/pulley/src/lib.rs +++ b/pulley/src/lib.rs @@ -138,6 +138,88 @@ macro_rules! for_each_op { /// Branch if unsigned `a <= b`. br_if_xulteq64 = BrIfXulteq64 { a: XReg, b: XReg, offset: PcRelOffset }; + /// Branch if `a == b`. + br_if_xeq32_i8 = BrIfXeq32I8 { a: XReg, b: i8, offset: PcRelOffset }; + /// Branch if `a == b`. + br_if_xeq32_i32 = BrIfXeq32I32 { a: XReg, b: i32, offset: PcRelOffset }; + /// Branch if `a != `b. + br_if_xneq32_i8 = BrIfXneq32I8 { a: XReg, b: i8, offset: PcRelOffset }; + /// Branch if `a != `b. + br_if_xneq32_i32 = BrIfXneq32I32 { a: XReg, b: i32, offset: PcRelOffset }; + /// Branch if signed `a < b`. + br_if_xslt32_i8 = BrIfXslt32I8 { a: XReg, b: i8, offset: PcRelOffset }; + /// Branch if signed `a < b`. + br_if_xslt32_i32 = BrIfXslt32I32 { a: XReg, b: i32, offset: PcRelOffset }; + /// Branch if signed `a > b`. + br_if_xsgt32_i8 = BrIfXsgt32I8 { a: XReg, b: i8, offset: PcRelOffset }; + /// Branch if signed `a > b`. + br_if_xsgt32_i32 = BrIfXsgt32I32 { a: XReg, b: i32, offset: PcRelOffset }; + /// Branch if signed `a <= b`. + br_if_xslteq32_i8 = BrIfXslteq32I8 { a: XReg, b: i8, offset: PcRelOffset }; + /// Branch if signed `a <= b`. + br_if_xslteq32_i32 = BrIfXslteq32I32 { a: XReg, b: i32, offset: PcRelOffset }; + /// Branch if signed `a >= b`. + br_if_xsgteq32_i8 = BrIfXsgteq32I8 { a: XReg, b: i8, offset: PcRelOffset }; + /// Branch if signed `a >= b`. + br_if_xsgteq32_i32 = BrIfXsgteq32I32 { a: XReg, b: i32, offset: PcRelOffset }; + /// Branch if unsigned `a < b`. + br_if_xult32_u8 = BrIfXult32U8 { a: XReg, b: u8, offset: PcRelOffset }; + /// Branch if unsigned `a < b`. + br_if_xult32_u32 = BrIfXult32U32 { a: XReg, b: u32, offset: PcRelOffset }; + /// Branch if unsigned `a <= b`. + br_if_xulteq32_u8 = BrIfXulteq32U8 { a: XReg, b: u8, offset: PcRelOffset }; + /// Branch if unsigned `a <= b`. + br_if_xulteq32_u32 = BrIfXulteq32U32 { a: XReg, b: u32, offset: PcRelOffset }; + /// Branch if unsigned `a > b`. + br_if_xugt32_u8 = BrIfXugt32U8 { a: XReg, b: u8, offset: PcRelOffset }; + /// Branch if unsigned `a > b`. + br_if_xugt32_u32 = BrIfXugt32U32 { a: XReg, b: u32, offset: PcRelOffset }; + /// Branch if unsigned `a >= b`. + br_if_xugteq32_u8 = BrIfXugteq32U8 { a: XReg, b: u8, offset: PcRelOffset }; + /// Branch if unsigned `a >= b`. + br_if_xugteq32_u32 = BrIfXugteq32U32 { a: XReg, b: u32, offset: PcRelOffset }; + + /// Branch if `a == b`. + br_if_xeq64_i8 = BrIfXeq64I8 { a: XReg, b: i8, offset: PcRelOffset }; + /// Branch if `a == b`. + br_if_xeq64_i32 = BrIfXeq64I32 { a: XReg, b: i32, offset: PcRelOffset }; + /// Branch if `a != `b. + br_if_xneq64_i8 = BrIfXneq64I8 { a: XReg, b: i8, offset: PcRelOffset }; + /// Branch if `a != `b. + br_if_xneq64_i32 = BrIfXneq64I32 { a: XReg, b: i32, offset: PcRelOffset }; + /// Branch if signed `a < b`. + br_if_xslt64_i8 = BrIfXslt64I8 { a: XReg, b: i8, offset: PcRelOffset }; + /// Branch if signed `a < b`. + br_if_xslt64_i32 = BrIfXslt64I32 { a: XReg, b: i32, offset: PcRelOffset }; + /// Branch if signed `a > b`. + br_if_xsgt64_i8 = BrIfXsgt64I8 { a: XReg, b: i8, offset: PcRelOffset }; + /// Branch if signed `a > b`. + br_if_xsgt64_i32 = BrIfXsgt64I32 { a: XReg, b: i32, offset: PcRelOffset }; + /// Branch if signed `a <= b`. + br_if_xslteq64_i8 = BrIfXslteq64I8 { a: XReg, b: i8, offset: PcRelOffset }; + /// Branch if signed `a <= b`. + br_if_xslteq64_i32 = BrIfXslteq64I32 { a: XReg, b: i32, offset: PcRelOffset }; + /// Branch if signed `a >= b`. + br_if_xsgteq64_i8 = BrIfXsgteq64I8 { a: XReg, b: i8, offset: PcRelOffset }; + /// Branch if signed `a >= b`. + br_if_xsgteq64_i32 = BrIfXsgteq64I32 { a: XReg, b: i32, offset: PcRelOffset }; + /// Branch if unsigned `a < b`. + br_if_xult64_u8 = BrIfXult64U8 { a: XReg, b: u8, offset: PcRelOffset }; + /// Branch if unsigned `a < b`. + br_if_xult64_u32 = BrIfXult64U32 { a: XReg, b: u32, offset: PcRelOffset }; + /// Branch if unsigned `a <= b`. + br_if_xulteq64_u8 = BrIfXulteq64U8 { a: XReg, b: u8, offset: PcRelOffset }; + /// Branch if unsigned `a <= b`. + br_if_xulteq64_u32 = BrIfXulteq64U32 { a: XReg, b: u32, offset: PcRelOffset }; + /// Branch if unsigned `a > b`. + br_if_xugt64_u8 = BrIfXugt64U8 { a: XReg, b: u8, offset: PcRelOffset }; + /// Branch if unsigned `a > b`. + br_if_xugt64_u32 = BrIfXugt64U32 { a: XReg, b: u32, offset: PcRelOffset }; + /// Branch if unsigned `a >= b`. + br_if_xugteq64_u8 = BrIfXugteq64U8 { a: XReg, b: u8, offset: PcRelOffset }; + /// Branch if unsigned `a >= b`. + br_if_xugteq64_u32 = BrIfXugteq64U32 { a: XReg, b: u32, offset: PcRelOffset }; + /// Branch to the label indicated by `low32(idx)`. /// /// After this instruction are `amt` instances of `PcRelOffset` diff --git a/tests/disas/pulley/epoch-simple.wat b/tests/disas/pulley/epoch-simple.wat index 763aaad534aa..0c2adb5fede5 100644 --- a/tests/disas/pulley/epoch-simple.wat +++ b/tests/disas/pulley/epoch-simple.wat @@ -14,5 +14,5 @@ ;; br_if_xulteq64 x6, x7, 0x9 // target = 0x1a ;; 18: pop_frame ;; ret -;; 1a: call 0xa4 // target = 0xbe +;; 1a: call 0xa1 // target = 0xbb ;; 1f: jump 0xfffffffffffffff9 // target = 0x18 diff --git a/tests/disas/pulley/memory-inbounds.wat b/tests/disas/pulley/memory-inbounds.wat index f4a7d6fbffa2..3b5f021d2014 100644 --- a/tests/disas/pulley/memory-inbounds.wat +++ b/tests/disas/pulley/memory-inbounds.wat @@ -48,15 +48,14 @@ ;; ;; wasm[0]::function[4]::offset_just_bad: ;; push_frame -;; xload64le_offset8 x6, x0, 104 -;; xsub64_u8 x6, x6, 4 -;; xconst32 x7, 65533 -;; br_if_xult64 x6, x7, 0x14 // target = 0x23 -;; 16: xload64le_offset8 x7, x0, 96 -;; xload32le_offset32 x0, x7, 65533 +;; xload64le_offset8 x5, x0, 104 +;; xsub64_u8 x5, x5, 4 +;; br_if_xult64_u32 x5, 65533, 0x17 // target = 0x20 +;; 13: xload64le_offset8 x6, x0, 96 +;; xload32le_offset32 x0, x6, 65533 ;; pop_frame ;; ret -;; 23: trap +;; 20: trap ;; ;; wasm[0]::function[5]::offset_just_ok_v2: ;; push_frame @@ -67,27 +66,25 @@ ;; ;; wasm[0]::function[6]::offset_just_bad_v2: ;; push_frame -;; xload64le_offset8 x6, x0, 104 -;; xsub64_u32 x6, x6, 65536 -;; xconst8 x7, 0 -;; br_if_xeq64 x6, x7, 0x14 // target = 0x23 -;; 16: xload64le_offset8 x7, x0, 96 -;; xload32le_offset32 x0, x7, 65533 +;; xload64le_offset8 x5, x0, 104 +;; xsub64_u32 x5, x5, 65536 +;; br_if_xeq64_i8 x5, 0, 0x14 // target = 0x20 +;; 13: xload64le_offset8 x6, x0, 96 +;; xload32le_offset32 x0, x6, 65533 ;; pop_frame ;; ret -;; 23: trap +;; 20: trap ;; ;; wasm[0]::function[7]::maybe_inbounds: ;; push_frame -;; xload64le_offset8 x6, x0, 104 -;; xsub64_u8 x6, x6, 4 -;; xconst32 x7, 131068 -;; br_if_xult64 x6, x7, 0x14 // target = 0x23 -;; 16: xload64le_offset8 x7, x0, 96 -;; xload32le_offset32 x0, x7, 131068 +;; xload64le_offset8 x5, x0, 104 +;; xsub64_u8 x5, x5, 4 +;; br_if_xult64_u32 x5, 131068, 0x17 // target = 0x20 +;; 13: xload64le_offset8 x6, x0, 96 +;; xload32le_offset32 x0, x6, 131068 ;; pop_frame ;; ret -;; 23: trap +;; 20: trap ;; ;; wasm[0]::function[8]::maybe_inbounds_v2: ;; push_frame @@ -104,15 +101,14 @@ ;; ;; wasm[0]::function[9]::never_inbounds: ;; push_frame -;; xload64le_offset8 x6, x0, 104 -;; xsub64_u8 x6, x6, 4 -;; xconst32 x7, 131069 -;; br_if_xult64 x6, x7, 0x14 // target = 0x23 -;; 16: xload64le_offset8 x7, x0, 96 -;; xload32le_offset32 x0, x7, 131069 +;; xload64le_offset8 x5, x0, 104 +;; xsub64_u8 x5, x5, 4 +;; br_if_xult64_u32 x5, 131069, 0x17 // target = 0x20 +;; 13: xload64le_offset8 x6, x0, 96 +;; xload32le_offset32 x0, x6, 131069 ;; pop_frame ;; ret -;; 23: trap +;; 20: trap ;; ;; wasm[0]::function[10]::never_inbounds_v2: ;; push_frame