Skip to content

Commit 2e4073a

Browse files
committed
[Cranelift] add imm64 abs/min/max helpers
1 parent bd7d5f6 commit 2e4073a

2 files changed

Lines changed: 66 additions & 0 deletions

File tree

cranelift/codegen/src/isle_prelude.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,57 @@ macro_rules! isle_common_prelude_methods {
137137
Imm64::new(x.bits().wrapping_neg() & ty_mask)
138138
}
139139

140+
#[inline]
141+
fn imm64_abs(&mut self, ty: Type, x: Imm64) -> Option<Imm64> {
142+
let type_width = ty.bits();
143+
assert!(type_width <= 64);
144+
145+
let x = x.sign_extend_from_width(type_width).bits();
146+
let shift = 64 - type_width;
147+
let min = ((self.ty_smin(ty) as i64) << shift) >> shift;
148+
if x == min {
149+
return None;
150+
}
151+
152+
Some(Imm64::new(x.abs()).mask_to_width(type_width))
153+
}
154+
155+
#[inline]
156+
fn imm64_umin(&mut self, ty: Type, x: Imm64, y: Imm64) -> Imm64 {
157+
let ty_mask = self.ty_mask(ty);
158+
let x_u = (x.bits() as u64) & ty_mask;
159+
let y_u = (y.bits() as u64) & ty_mask;
160+
Imm64::new((if x_u <= y_u { x_u } else { y_u }) as i64)
161+
}
162+
163+
#[inline]
164+
fn imm64_umax(&mut self, ty: Type, x: Imm64, y: Imm64) -> Imm64 {
165+
let ty_mask = self.ty_mask(ty);
166+
let x_u = (x.bits() as u64) & ty_mask;
167+
let y_u = (y.bits() as u64) & ty_mask;
168+
Imm64::new((if x_u >= y_u { x_u } else { y_u }) as i64)
169+
}
170+
171+
#[inline]
172+
fn imm64_smin(&mut self, ty: Type, x: Imm64, y: Imm64) -> Imm64 {
173+
let type_width = ty.bits();
174+
assert!(type_width <= 64);
175+
let x_s = x.sign_extend_from_width(type_width).bits();
176+
let y_s = y.sign_extend_from_width(type_width).bits();
177+
let selected = if x_s <= y_s { x_s } else { y_s };
178+
Imm64::new(selected).mask_to_width(type_width)
179+
}
180+
181+
#[inline]
182+
fn imm64_smax(&mut self, ty: Type, x: Imm64, y: Imm64) -> Imm64 {
183+
let type_width = ty.bits();
184+
assert!(type_width <= 64);
185+
let x_s = x.sign_extend_from_width(type_width).bits();
186+
let y_s = y.sign_extend_from_width(type_width).bits();
187+
let selected = if x_s >= y_s { x_s } else { y_s };
188+
Imm64::new(selected).mask_to_width(type_width)
189+
}
190+
140191
#[inline]
141192
fn imm64_shl(&mut self, ty: Type, x: Imm64, y: Imm64) -> Imm64 {
142193
// Mask off any excess shift bits.

cranelift/codegen/src/prelude.isle

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,21 @@
100100
(decl pure imm64_neg (Type Imm64) Imm64)
101101
(extern constructor imm64_neg imm64_neg)
102102

103+
(decl pure partial imm64_abs (Type Imm64) Imm64)
104+
(extern constructor imm64_abs imm64_abs)
105+
106+
(decl pure imm64_umin (Type Imm64 Imm64) Imm64)
107+
(extern constructor imm64_umin imm64_umin)
108+
109+
(decl pure imm64_umax (Type Imm64 Imm64) Imm64)
110+
(extern constructor imm64_umax imm64_umax)
111+
112+
(decl pure imm64_smin (Type Imm64 Imm64) Imm64)
113+
(extern constructor imm64_smin imm64_smin)
114+
115+
(decl pure imm64_smax (Type Imm64 Imm64) Imm64)
116+
(extern constructor imm64_smax imm64_smax)
117+
103118
(decl pure imm64_shl (Type Imm64 Imm64) Imm64)
104119
(extern constructor imm64_shl imm64_shl)
105120

0 commit comments

Comments
 (0)