Skip to content

Commit 4178766

Browse files
authored
pulley: Add branch-with-compare-against-immediate (bytecodealliance#9863)
This commit adds a large number of new `br_if_x*` instructions which compare with an immediate instead of comparing two registers. This is pretty common in wasm/compiled code where, for example, loop upper bounds are often constants. This helps compress code slightly while fusing more instructions together. The main cost of this is that the number of opcodes added here is quite large. Like with previous immediate-taking opcodes both 8 and 32-bit variants of immediates are added for all comparisons. Additionally unlike the previous set of branch-and-compare instructions it's required to add instructions for `>` and `>=` because the operands cannot be swapped to invert the condition, further increasing the number of opcodes added. This is a mild size reduction on `spidermonkey.cwasm` from 29M to 28M but it's mostly expected to be a performance win for interpreted loops.
1 parent 1e4c470 commit 4178766

File tree

10 files changed

+653
-62
lines changed

10 files changed

+653
-62
lines changed

cranelift/codegen/src/isa/pulley_shared/inst.isle

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,35 @@
109109
(IfXult32 (src1 XReg) (src2 XReg))
110110
(IfXulteq32 (src1 XReg) (src2 XReg))
111111

112+
(IfXeq32I32 (src1 XReg) (src2 i32))
113+
(IfXneq32I32 (src1 XReg) (src2 i32))
114+
(IfXslt32I32 (src1 XReg) (src2 i32))
115+
(IfXslteq32I32 (src1 XReg) (src2 i32))
116+
(IfXult32I32 (src1 XReg) (src2 u32))
117+
(IfXulteq32I32 (src1 XReg) (src2 u32))
118+
(IfXsgt32I32 (src1 XReg) (src2 i32))
119+
(IfXsgteq32I32 (src1 XReg) (src2 i32))
120+
(IfXugt32I32 (src1 XReg) (src2 u32))
121+
(IfXugteq32I32 (src1 XReg) (src2 u32))
122+
112123
;; Conditionals for comparing two 64-bit registers.
113124
(IfXeq64 (src1 XReg) (src2 XReg))
114125
(IfXneq64 (src1 XReg) (src2 XReg))
115126
(IfXslt64 (src1 XReg) (src2 XReg))
116127
(IfXslteq64 (src1 XReg) (src2 XReg))
117128
(IfXult64 (src1 XReg) (src2 XReg))
118129
(IfXulteq64 (src1 XReg) (src2 XReg))
130+
131+
(IfXeq64I32 (src1 XReg) (src2 i32))
132+
(IfXneq64I32 (src1 XReg) (src2 i32))
133+
(IfXslt64I32 (src1 XReg) (src2 i32))
134+
(IfXslteq64I32 (src1 XReg) (src2 i32))
135+
(IfXult64I32 (src1 XReg) (src2 u32))
136+
(IfXulteq64I32 (src1 XReg) (src2 u32))
137+
(IfXsgt64I32 (src1 XReg) (src2 i32))
138+
(IfXsgteq64I32 (src1 XReg) (src2 i32))
139+
(IfXugt64I32 (src1 XReg) (src2 u32))
140+
(IfXugteq64I32 (src1 XReg) (src2 u32))
119141
)
120142
)
121143

cranelift/codegen/src/isa/pulley_shared/inst/args.rs

Lines changed: 193 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,34 @@ impl Cond {
255255
collector.reg_use(src1);
256256
collector.reg_use(src2);
257257
}
258+
259+
Cond::IfXeq32I32 { src1, src2 }
260+
| Cond::IfXneq32I32 { src1, src2 }
261+
| Cond::IfXslt32I32 { src1, src2 }
262+
| Cond::IfXslteq32I32 { src1, src2 }
263+
| Cond::IfXsgt32I32 { src1, src2 }
264+
| Cond::IfXsgteq32I32 { src1, src2 }
265+
| Cond::IfXeq64I32 { src1, src2 }
266+
| Cond::IfXneq64I32 { src1, src2 }
267+
| Cond::IfXslt64I32 { src1, src2 }
268+
| Cond::IfXslteq64I32 { src1, src2 }
269+
| Cond::IfXsgt64I32 { src1, src2 }
270+
| Cond::IfXsgteq64I32 { src1, src2 } => {
271+
collector.reg_use(src1);
272+
let _: &mut i32 = src2;
273+
}
274+
275+
Cond::IfXult32I32 { src1, src2 }
276+
| Cond::IfXulteq32I32 { src1, src2 }
277+
| Cond::IfXugt32I32 { src1, src2 }
278+
| Cond::IfXugteq32I32 { src1, src2 }
279+
| Cond::IfXult64I32 { src1, src2 }
280+
| Cond::IfXulteq64I32 { src1, src2 }
281+
| Cond::IfXugt64I32 { src1, src2 }
282+
| Cond::IfXugteq64I32 { src1, src2 } => {
283+
collector.reg_use(src1);
284+
let _: &mut u32 = src2;
285+
}
258286
}
259287
}
260288

@@ -263,7 +291,7 @@ impl Cond {
263291
/// Note that the offset encoded to jump by is filled in as 0 and it's
264292
/// assumed `MachBuffer` will come back and clean it up.
265293
pub fn encode(&self, sink: &mut impl Extend<u8>) {
266-
match self {
294+
match *self {
267295
Cond::If32 { reg } => encode::br_if32(sink, reg, 0),
268296
Cond::IfNot32 { reg } => encode::br_if_not32(sink, reg, 0),
269297
Cond::IfXeq32 { src1, src2 } => encode::br_if_xeq32(sink, src1, src2, 0),
@@ -278,6 +306,88 @@ impl Cond {
278306
Cond::IfXslteq64 { src1, src2 } => encode::br_if_xslteq64(sink, src1, src2, 0),
279307
Cond::IfXult64 { src1, src2 } => encode::br_if_xult64(sink, src1, src2, 0),
280308
Cond::IfXulteq64 { src1, src2 } => encode::br_if_xulteq64(sink, src1, src2, 0),
309+
310+
Cond::IfXeq32I32 { src1, src2 } => match i8::try_from(src2) {
311+
Ok(src2) => encode::br_if_xeq32_i8(sink, src1, src2, 0),
312+
Err(_) => encode::br_if_xeq32_i32(sink, src1, src2, 0),
313+
},
314+
Cond::IfXneq32I32 { src1, src2 } => match i8::try_from(src2) {
315+
Ok(src2) => encode::br_if_xneq32_i8(sink, src1, src2, 0),
316+
Err(_) => encode::br_if_xneq32_i32(sink, src1, src2, 0),
317+
},
318+
Cond::IfXslt32I32 { src1, src2 } => match i8::try_from(src2) {
319+
Ok(src2) => encode::br_if_xslt32_i8(sink, src1, src2, 0),
320+
Err(_) => encode::br_if_xslt32_i32(sink, src1, src2, 0),
321+
},
322+
Cond::IfXslteq32I32 { src1, src2 } => match i8::try_from(src2) {
323+
Ok(src2) => encode::br_if_xslteq32_i8(sink, src1, src2, 0),
324+
Err(_) => encode::br_if_xslteq32_i32(sink, src1, src2, 0),
325+
},
326+
Cond::IfXsgt32I32 { src1, src2 } => match i8::try_from(src2) {
327+
Ok(src2) => encode::br_if_xsgt32_i8(sink, src1, src2, 0),
328+
Err(_) => encode::br_if_xsgt32_i32(sink, src1, src2, 0),
329+
},
330+
Cond::IfXsgteq32I32 { src1, src2 } => match i8::try_from(src2) {
331+
Ok(src2) => encode::br_if_xsgteq32_i8(sink, src1, src2, 0),
332+
Err(_) => encode::br_if_xsgteq32_i32(sink, src1, src2, 0),
333+
},
334+
Cond::IfXult32I32 { src1, src2 } => match u8::try_from(src2) {
335+
Ok(src2) => encode::br_if_xult32_u8(sink, src1, src2, 0),
336+
Err(_) => encode::br_if_xult32_u32(sink, src1, src2, 0),
337+
},
338+
Cond::IfXulteq32I32 { src1, src2 } => match u8::try_from(src2) {
339+
Ok(src2) => encode::br_if_xulteq32_u8(sink, src1, src2, 0),
340+
Err(_) => encode::br_if_xulteq32_u32(sink, src1, src2, 0),
341+
},
342+
Cond::IfXugt32I32 { src1, src2 } => match u8::try_from(src2) {
343+
Ok(src2) => encode::br_if_xugt32_u8(sink, src1, src2, 0),
344+
Err(_) => encode::br_if_xugt32_u32(sink, src1, src2, 0),
345+
},
346+
Cond::IfXugteq32I32 { src1, src2 } => match u8::try_from(src2) {
347+
Ok(src2) => encode::br_if_xugteq32_u8(sink, src1, src2, 0),
348+
Err(_) => encode::br_if_xugteq32_u32(sink, src1, src2, 0),
349+
},
350+
351+
Cond::IfXeq64I32 { src1, src2 } => match i8::try_from(src2) {
352+
Ok(src2) => encode::br_if_xeq64_i8(sink, src1, src2, 0),
353+
Err(_) => encode::br_if_xeq64_i32(sink, src1, src2, 0),
354+
},
355+
Cond::IfXneq64I32 { src1, src2 } => match i8::try_from(src2) {
356+
Ok(src2) => encode::br_if_xneq64_i8(sink, src1, src2, 0),
357+
Err(_) => encode::br_if_xneq64_i32(sink, src1, src2, 0),
358+
},
359+
Cond::IfXslt64I32 { src1, src2 } => match i8::try_from(src2) {
360+
Ok(src2) => encode::br_if_xslt64_i8(sink, src1, src2, 0),
361+
Err(_) => encode::br_if_xslt64_i32(sink, src1, src2, 0),
362+
},
363+
Cond::IfXslteq64I32 { src1, src2 } => match i8::try_from(src2) {
364+
Ok(src2) => encode::br_if_xslteq64_i8(sink, src1, src2, 0),
365+
Err(_) => encode::br_if_xslteq64_i32(sink, src1, src2, 0),
366+
},
367+
Cond::IfXsgt64I32 { src1, src2 } => match i8::try_from(src2) {
368+
Ok(src2) => encode::br_if_xsgt64_i8(sink, src1, src2, 0),
369+
Err(_) => encode::br_if_xsgt64_i32(sink, src1, src2, 0),
370+
},
371+
Cond::IfXsgteq64I32 { src1, src2 } => match i8::try_from(src2) {
372+
Ok(src2) => encode::br_if_xsgteq64_i8(sink, src1, src2, 0),
373+
Err(_) => encode::br_if_xsgteq64_i32(sink, src1, src2, 0),
374+
},
375+
Cond::IfXult64I32 { src1, src2 } => match u8::try_from(src2) {
376+
Ok(src2) => encode::br_if_xult64_u8(sink, src1, src2, 0),
377+
Err(_) => encode::br_if_xult64_u32(sink, src1, src2, 0),
378+
},
379+
Cond::IfXulteq64I32 { src1, src2 } => match u8::try_from(src2) {
380+
Ok(src2) => encode::br_if_xulteq64_u8(sink, src1, src2, 0),
381+
Err(_) => encode::br_if_xulteq64_u32(sink, src1, src2, 0),
382+
},
383+
Cond::IfXugt64I32 { src1, src2 } => match u8::try_from(src2) {
384+
Ok(src2) => encode::br_if_xugt64_u8(sink, src1, src2, 0),
385+
Err(_) => encode::br_if_xugt64_u32(sink, src1, src2, 0),
386+
},
387+
Cond::IfXugteq64I32 { src1, src2 } => match u8::try_from(src2) {
388+
Ok(src2) => encode::br_if_xugteq64_u8(sink, src1, src2, 0),
389+
Err(_) => encode::br_if_xugteq64_u32(sink, src1, src2, 0),
390+
},
281391
}
282392
}
283393

@@ -325,6 +435,28 @@ impl Cond {
325435
src1: src2,
326436
src2: src1,
327437
},
438+
439+
Cond::IfXeq32I32 { src1, src2 } => Cond::IfXneq32I32 { src1, src2 },
440+
Cond::IfXneq32I32 { src1, src2 } => Cond::IfXeq32I32 { src1, src2 },
441+
Cond::IfXslt32I32 { src1, src2 } => Cond::IfXsgteq32I32 { src1, src2 },
442+
Cond::IfXslteq32I32 { src1, src2 } => Cond::IfXsgt32I32 { src1, src2 },
443+
Cond::IfXult32I32 { src1, src2 } => Cond::IfXugteq32I32 { src1, src2 },
444+
Cond::IfXulteq32I32 { src1, src2 } => Cond::IfXugt32I32 { src1, src2 },
445+
Cond::IfXsgt32I32 { src1, src2 } => Cond::IfXslteq32I32 { src1, src2 },
446+
Cond::IfXsgteq32I32 { src1, src2 } => Cond::IfXslt32I32 { src1, src2 },
447+
Cond::IfXugt32I32 { src1, src2 } => Cond::IfXulteq32I32 { src1, src2 },
448+
Cond::IfXugteq32I32 { src1, src2 } => Cond::IfXult32I32 { src1, src2 },
449+
450+
Cond::IfXeq64I32 { src1, src2 } => Cond::IfXneq64I32 { src1, src2 },
451+
Cond::IfXneq64I32 { src1, src2 } => Cond::IfXeq64I32 { src1, src2 },
452+
Cond::IfXslt64I32 { src1, src2 } => Cond::IfXsgteq64I32 { src1, src2 },
453+
Cond::IfXslteq64I32 { src1, src2 } => Cond::IfXsgt64I32 { src1, src2 },
454+
Cond::IfXult64I32 { src1, src2 } => Cond::IfXugteq64I32 { src1, src2 },
455+
Cond::IfXulteq64I32 { src1, src2 } => Cond::IfXugt64I32 { src1, src2 },
456+
Cond::IfXsgt64I32 { src1, src2 } => Cond::IfXslteq64I32 { src1, src2 },
457+
Cond::IfXsgteq64I32 { src1, src2 } => Cond::IfXslt64I32 { src1, src2 },
458+
Cond::IfXugt64I32 { src1, src2 } => Cond::IfXulteq64I32 { src1, src2 },
459+
Cond::IfXugteq64I32 { src1, src2 } => Cond::IfXult64I32 { src1, src2 },
328460
}
329461
}
330462
}
@@ -370,6 +502,66 @@ impl fmt::Display for Cond {
370502
Cond::IfXulteq64 { src1, src2 } => {
371503
write!(f, "if_xulteq64 {}, {}", reg_name(**src1), reg_name(**src2))
372504
}
505+
Cond::IfXeq32I32 { src1, src2 } => {
506+
write!(f, "if_xeq32_i32 {}, {src2}", reg_name(**src1))
507+
}
508+
Cond::IfXneq32I32 { src1, src2 } => {
509+
write!(f, "if_xneq32_i32 {}, {src2}", reg_name(**src1))
510+
}
511+
Cond::IfXslt32I32 { src1, src2 } => {
512+
write!(f, "if_xslt32_i32 {}, {src2}", reg_name(**src1))
513+
}
514+
Cond::IfXslteq32I32 { src1, src2 } => {
515+
write!(f, "if_xslteq32_i32 {}, {src2}", reg_name(**src1))
516+
}
517+
Cond::IfXsgt32I32 { src1, src2 } => {
518+
write!(f, "if_xsgt32_i32 {}, {src2}", reg_name(**src1))
519+
}
520+
Cond::IfXsgteq32I32 { src1, src2 } => {
521+
write!(f, "if_xsgteq32_i32 {}, {src2}", reg_name(**src1))
522+
}
523+
Cond::IfXult32I32 { src1, src2 } => {
524+
write!(f, "if_xult32_i32 {}, {src2}", reg_name(**src1))
525+
}
526+
Cond::IfXulteq32I32 { src1, src2 } => {
527+
write!(f, "if_xulteq32_i32 {}, {src2}", reg_name(**src1))
528+
}
529+
Cond::IfXugt32I32 { src1, src2 } => {
530+
write!(f, "if_xugt32_i32 {}, {src2}", reg_name(**src1))
531+
}
532+
Cond::IfXugteq32I32 { src1, src2 } => {
533+
write!(f, "if_xugteq32_i32 {}, {src2}", reg_name(**src1))
534+
}
535+
Cond::IfXeq64I32 { src1, src2 } => {
536+
write!(f, "if_xeq64_i32 {}, {src2}", reg_name(**src1))
537+
}
538+
Cond::IfXneq64I32 { src1, src2 } => {
539+
write!(f, "if_xneq64_i32 {}, {src2}", reg_name(**src1))
540+
}
541+
Cond::IfXslt64I32 { src1, src2 } => {
542+
write!(f, "if_xslt64_i32 {}, {src2}", reg_name(**src1))
543+
}
544+
Cond::IfXslteq64I32 { src1, src2 } => {
545+
write!(f, "if_xslteq64_i32 {}, {src2}", reg_name(**src1))
546+
}
547+
Cond::IfXsgt64I32 { src1, src2 } => {
548+
write!(f, "if_xsgt64_i32 {}, {src2}", reg_name(**src1))
549+
}
550+
Cond::IfXsgteq64I32 { src1, src2 } => {
551+
write!(f, "if_xsgteq64_i32 {}, {src2}", reg_name(**src1))
552+
}
553+
Cond::IfXult64I32 { src1, src2 } => {
554+
write!(f, "if_xult64_i32 {}, {src2}", reg_name(**src1))
555+
}
556+
Cond::IfXulteq64I32 { src1, src2 } => {
557+
write!(f, "if_xulteq64_i32 {}, {src2}", reg_name(**src1))
558+
}
559+
Cond::IfXugt64I32 { src1, src2 } => {
560+
write!(f, "if_xugt64_i32 {}, {src2}", reg_name(**src1))
561+
}
562+
Cond::IfXugteq64I32 { src1, src2 } => {
563+
write!(f, "if_xugteq64_i32 {}, {src2}", reg_name(**src1))
564+
}
373565
}
374566
}
375567
}

cranelift/codegen/src/isa/pulley_shared/lower.isle

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,27 @@
3535
(rule (lower_cond_icmp32 (IntCC.UnsignedGreaterThan) a b) (Cond.IfXult32 b a))
3636
(rule (lower_cond_icmp32 (IntCC.UnsignedGreaterThanOrEqual) a b) (Cond.IfXulteq32 b a))
3737

38+
(rule 1 (lower_cond_icmp32 (IntCC.Equal) a (i32_from_iconst b))
39+
(Cond.IfXeq32I32 a b))
40+
(rule 1 (lower_cond_icmp32 (IntCC.NotEqual) a (i32_from_iconst b))
41+
(Cond.IfXneq32I32 a b))
42+
(rule 1 (lower_cond_icmp32 (IntCC.SignedLessThan) a (i32_from_iconst b))
43+
(Cond.IfXslt32I32 a b))
44+
(rule 1 (lower_cond_icmp32 (IntCC.SignedLessThanOrEqual) a (i32_from_iconst b))
45+
(Cond.IfXslteq32I32 a b))
46+
(rule 1 (lower_cond_icmp32 (IntCC.SignedGreaterThan) a (i32_from_iconst b))
47+
(Cond.IfXsgt32I32 a b))
48+
(rule 1 (lower_cond_icmp32 (IntCC.SignedGreaterThanOrEqual) a (i32_from_iconst b))
49+
(Cond.IfXsgteq32I32 a b))
50+
(rule 1 (lower_cond_icmp32 (IntCC.UnsignedLessThan) a (u32_from_iconst b))
51+
(Cond.IfXult32I32 a b))
52+
(rule 1 (lower_cond_icmp32 (IntCC.UnsignedLessThanOrEqual) a (u32_from_iconst b))
53+
(Cond.IfXulteq32I32 a b))
54+
(rule 1 (lower_cond_icmp32 (IntCC.UnsignedGreaterThan) a (u32_from_iconst b))
55+
(Cond.IfXugt32I32 a b))
56+
(rule 1 (lower_cond_icmp32 (IntCC.UnsignedGreaterThanOrEqual) a (u32_from_iconst b))
57+
(Cond.IfXugteq32I32 a b))
58+
3859
(decl lower_cond_icmp64 (IntCC Value Value) Cond)
3960
(rule (lower_cond_icmp64 (IntCC.Equal) a b) (Cond.IfXeq64 a b))
4061
(rule (lower_cond_icmp64 (IntCC.NotEqual) a b) (Cond.IfXneq64 a b))
@@ -48,6 +69,27 @@
4869
(rule (lower_cond_icmp64 (IntCC.UnsignedGreaterThan) a b) (Cond.IfXult64 b a))
4970
(rule (lower_cond_icmp64 (IntCC.UnsignedGreaterThanOrEqual) a b) (Cond.IfXulteq64 b a))
5071

72+
(rule 1 (lower_cond_icmp64 (IntCC.Equal) a (i32_from_iconst b))
73+
(Cond.IfXeq64I32 a b))
74+
(rule 1 (lower_cond_icmp64 (IntCC.NotEqual) a (i32_from_iconst b))
75+
(Cond.IfXneq64I32 a b))
76+
(rule 1 (lower_cond_icmp64 (IntCC.SignedLessThan) a (i32_from_iconst b))
77+
(Cond.IfXslt64I32 a b))
78+
(rule 1 (lower_cond_icmp64 (IntCC.SignedLessThanOrEqual) a (i32_from_iconst b))
79+
(Cond.IfXslteq64I32 a b))
80+
(rule 1 (lower_cond_icmp64 (IntCC.SignedGreaterThan) a (i32_from_iconst b))
81+
(Cond.IfXsgt64I32 a b))
82+
(rule 1 (lower_cond_icmp64 (IntCC.SignedGreaterThanOrEqual) a (i32_from_iconst b))
83+
(Cond.IfXsgteq64I32 a b))
84+
(rule 1 (lower_cond_icmp64 (IntCC.UnsignedLessThan) a (u32_from_iconst b))
85+
(Cond.IfXult64I32 a b))
86+
(rule 1 (lower_cond_icmp64 (IntCC.UnsignedLessThanOrEqual) a (u32_from_iconst b))
87+
(Cond.IfXulteq64I32 a b))
88+
(rule 1 (lower_cond_icmp64 (IntCC.UnsignedGreaterThan) a (u32_from_iconst b))
89+
(Cond.IfXugt64I32 a b))
90+
(rule 1 (lower_cond_icmp64 (IntCC.UnsignedGreaterThanOrEqual) a (u32_from_iconst b))
91+
(Cond.IfXugteq64I32 a b))
92+
5193
;; The main control-flow-lowering term: takes a control-flow instruction and
5294
;; target(s) and emits the necessary instructions.
5395
(decl partial lower_branch (Inst MachLabelSlice) Unit)
@@ -880,6 +922,52 @@
880922
(rule (emit_cond (Cond.IfXult64 src1 src2)) (pulley_xult64 src1 src2))
881923
(rule (emit_cond (Cond.IfXulteq64 src1 src2)) (pulley_xulteq64 src1 src2))
882924

925+
(rule (emit_cond (Cond.IfXeq32I32 src1 src2))
926+
(pulley_xeq32 src1 (imm $I32 (i64_as_u64 (i32_as_i64 src2)))))
927+
(rule (emit_cond (Cond.IfXneq32I32 src1 src2))
928+
(pulley_xneq32 src1 (imm $I32 (i64_as_u64 (i32_as_i64 src2)))))
929+
(rule (emit_cond (Cond.IfXslt32I32 src1 src2))
930+
(pulley_xslt32 src1 (imm $I32 (i64_as_u64 (i32_as_i64 src2)))))
931+
(rule (emit_cond (Cond.IfXslteq32I32 src1 src2))
932+
(pulley_xslteq32 src1 (imm $I32 (i64_as_u64 (i32_as_i64 src2)))))
933+
(rule (emit_cond (Cond.IfXult32I32 src1 src2))
934+
(pulley_xult32 src1 (imm $I32 (u32_as_u64 src2))))
935+
(rule (emit_cond (Cond.IfXulteq32I32 src1 src2))
936+
(pulley_xulteq32 src1 (imm $I32 (u32_as_u64 src2))))
937+
938+
;; Note the operand swaps here
939+
(rule (emit_cond (Cond.IfXsgt32I32 src1 src2))
940+
(pulley_xslteq32 (imm $I32 (i64_as_u64 (i32_as_i64 src2))) src1))
941+
(rule (emit_cond (Cond.IfXsgteq32I32 src1 src2))
942+
(pulley_xslt32 (imm $I32 (i64_as_u64 (i32_as_i64 src2))) src1))
943+
(rule (emit_cond (Cond.IfXugt32I32 src1 src2))
944+
(pulley_xulteq32 (imm $I32 (u32_as_u64 src2)) src1))
945+
(rule (emit_cond (Cond.IfXugteq32I32 src1 src2))
946+
(pulley_xult32 (imm $I32 (u32_as_u64 src2)) src1))
947+
948+
(rule (emit_cond (Cond.IfXeq64I32 src1 src2))
949+
(pulley_xeq64 src1 (imm $I64 (i64_as_u64 (i32_as_i64 src2)))))
950+
(rule (emit_cond (Cond.IfXneq64I32 src1 src2))
951+
(pulley_xneq64 src1 (imm $I64 (i64_as_u64 (i32_as_i64 src2)))))
952+
(rule (emit_cond (Cond.IfXslt64I32 src1 src2))
953+
(pulley_xslt64 src1 (imm $I64 (i64_as_u64 (i32_as_i64 src2)))))
954+
(rule (emit_cond (Cond.IfXslteq64I32 src1 src2))
955+
(pulley_xslteq64 src1 (imm $I64 (i64_as_u64 (i32_as_i64 src2)))))
956+
(rule (emit_cond (Cond.IfXult64I32 src1 src2))
957+
(pulley_xult64 src1 (imm $I64 (u32_as_u64 src2))))
958+
(rule (emit_cond (Cond.IfXulteq64I32 src1 src2))
959+
(pulley_xulteq64 src1 (imm $I64 (u32_as_u64 src2))))
960+
961+
;; Note the operand swaps here
962+
(rule (emit_cond (Cond.IfXsgt64I32 src1 src2))
963+
(pulley_xslteq64 (imm $I64 (i64_as_u64 (i32_as_i64 src2))) src1))
964+
(rule (emit_cond (Cond.IfXsgteq64I32 src1 src2))
965+
(pulley_xslt64 (imm $I64 (i64_as_u64 (i32_as_i64 src2))) src1))
966+
(rule (emit_cond (Cond.IfXugt64I32 src1 src2))
967+
(pulley_xulteq64 (imm $I64 (u32_as_u64 src2)) src1))
968+
(rule (emit_cond (Cond.IfXugteq64I32 src1 src2))
969+
(pulley_xult64 (imm $I64 (u32_as_u64 src2)) src1))
970+
883971
;;;; Rules for `bitcast` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
884972

885973
(rule (lower (has_type $F32 (bitcast _flags val @ (value_type $I32))))

0 commit comments

Comments
 (0)