diff --git a/cranelift/codegen/meta/src/shared/instructions.rs b/cranelift/codegen/meta/src/shared/instructions.rs index ef141c8a92..abf7e0e32a 100644 --- a/cranelift/codegen/meta/src/shared/instructions.rs +++ b/cranelift/codegen/meta/src/shared/instructions.rs @@ -693,6 +693,72 @@ fn define_simd_arithmetic( .operands_in(vec![x, y]) .operands_out(vec![a]), ); + + ig.push( + Inst::new( + "uadd_sat", + r#" + Add with unsigned saturation. + + This is similar to `iadd` but the operands are interpreted as unsigned integers and their + summed result, instead of wrapping, will be saturated to the highest unsigned integer for + the controlling type (e.g. `0xFF` for i8). + "#, + &formats.binary, + ) + .operands_in(vec![x, y]) + .operands_out(vec![a]), + ); + + ig.push( + Inst::new( + "sadd_sat", + r#" + Add with signed saturation. + + This is similar to `iadd` but the operands are interpreted as signed integers and their + summed result, instead of wrapping, will be saturated to the lowest or highest + signed integer for the controlling type (e.g. `0x80` or `0x7F` for i8). For example, + since an `sadd_sat.i8` of `0x70` and `0x70` is greater than `0x7F`, the result will be + clamped to `0x7F`. + "#, + &formats.binary, + ) + .operands_in(vec![x, y]) + .operands_out(vec![a]), + ); + + ig.push( + Inst::new( + "usub_sat", + r#" + Subtract with unsigned saturation. + + This is similar to `isub` but the operands are interpreted as unsigned integers and their + difference, instead of wrapping, will be saturated to the lowest unsigned integer for + the controlling type (e.g. `0x00` for i8). + "#, + &formats.binary, + ) + .operands_in(vec![x, y]) + .operands_out(vec![a]), + ); + + ig.push( + Inst::new( + "ssub_sat", + r#" + Subtract with signed saturation. + + This is similar to `isub` but the operands are interpreted as signed integers and their + difference, instead of wrapping, will be saturated to the lowest or highest + signed integer for the controlling type (e.g. `0x80` or `0x7F` for i8). + "#, + &formats.binary, + ) + .operands_in(vec![x, y]) + .operands_out(vec![a]), + ); } #[allow(clippy::many_single_char_names)] @@ -2325,40 +2391,6 @@ pub(crate) fn define( .operands_out(vec![a]), ); - ig.push( - Inst::new( - "uadd_sat", - r#" - Add with unsigned saturation. - - This is similar to `iadd` but the operands are interpreted as unsigned integers and their - summed result, instead of wrapping, will be saturated to the highest unsigned integer for - the controlling type (e.g. `0xFF` for i8). - "#, - &formats.binary, - ) - .operands_in(vec![x, y]) - .operands_out(vec![a]), - ); - - ig.push( - Inst::new( - "sadd_sat", - r#" - Add with signed saturation. - - This is similar to `iadd` but the operands are interpreted as signed integers and their - summed result, instead of wrapping, will be saturated to the lowest or highest - signed integer for the controlling type (e.g. `0x80` or `0x7F` for i8). For example, - since an `sadd_sat.i8` of `0x70` and `0x70` is greater than `0x7F`, the result will be - clamped to `0x7F`. - "#, - &formats.binary, - ) - .operands_in(vec![x, y]) - .operands_out(vec![a]), - ); - ig.push( Inst::new( "isub", @@ -2374,38 +2406,6 @@ pub(crate) fn define( .operands_out(vec![a]), ); - ig.push( - Inst::new( - "usub_sat", - r#" - Subtract with unsigned saturation. - - This is similar to `isub` but the operands are interpreted as unsigned integers and their - difference, instead of wrapping, will be saturated to the lowest unsigned integer for - the controlling type (e.g. `0x00` for i8). - "#, - &formats.binary, - ) - .operands_in(vec![x, y]) - .operands_out(vec![a]), - ); - - ig.push( - Inst::new( - "ssub_sat", - r#" - Subtract with signed saturation. - - This is similar to `isub` but the operands are interpreted as signed integers and their - difference, instead of wrapping, will be saturated to the lowest or highest - signed integer for the controlling type (e.g. `0x80` or `0x7F` for i8). - "#, - &formats.binary, - ) - .operands_in(vec![x, y]) - .operands_out(vec![a]), - ); - ig.push( Inst::new( "ineg", diff --git a/cranelift/filetests/filetests/isa/aarch64/saturating-ops.clif b/cranelift/filetests/filetests/isa/aarch64/saturating-ops.clif deleted file mode 100644 index 4baa039c68..0000000000 --- a/cranelift/filetests/filetests/isa/aarch64/saturating-ops.clif +++ /dev/null @@ -1,35 +0,0 @@ -test compile -set unwind_info=false -target aarch64 - -function %uaddsat64(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = uadd_sat.i64 v0, v1 - return v2 -} - -; check: stp fp, lr, [sp, #-16]! -; nextln: mov fp, sp -; nextln: fmov d0, x0 -; nextln: fmov d1, x1 -; nextln: uqadd d0, d0, d1 -; nextln: mov x0, v0.d[0] -; nextln: ldp fp, lr, [sp], #16 -; nextln: ret - -function %uaddsat8(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = uadd_sat.i8 v0, v1 - return v2 -} - -; check: stp fp, lr, [sp, #-16]! -; nextln: mov fp, sp -; nextln: uxtb w0, w0 -; nextln: uxtb w1, w1 -; nextln: fmov d0, x0 -; nextln: fmov d1, x1 -; nextln: uqadd d0, d0, d1 -; nextln: mov x0, v0.d[0] -; nextln: ldp fp, lr, [sp], #16 -; nextln: ret diff --git a/cranelift/filetests/filetests/isa/arm32/aluops.clif b/cranelift/filetests/filetests/isa/arm32/aluops.clif index fe47fd37f1..af11be4817 100644 --- a/cranelift/filetests/filetests/isa/arm32/aluops.clif +++ b/cranelift/filetests/filetests/isa/arm32/aluops.clif @@ -40,19 +40,6 @@ block0(v0: i32, v1: i32): ; nextln: pop {fp, lr} ; nextln: bx lr -function %sadd_sat(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = sadd_sat v0, v1 - return v2 -} - -; check: push {fp, lr} -; nextln: mov fp, sp -; nextln: qadd r0, r0, r1 -; nextln: mov sp, fp -; nextln: pop {fp, lr} -; nextln: bx lr - function %isub(i32, i32) -> i32 { block0(v0: i32, v1: i32): v2 = isub v0, v1 @@ -66,19 +53,6 @@ block0(v0: i32, v1: i32): ; nextln: pop {fp, lr} ; nextln: bx lr -function %ssub_sat(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = ssub_sat v0, v1 - return v2 -} - -; check: push {fp, lr} -; nextln: mov fp, sp -; nextln: qsub r0, r0, r1 -; nextln: mov sp, fp -; nextln: pop {fp, lr} -; nextln: bx lr - function %ineg(i32) -> i32 { block0(v0: i32): v1 = ineg v0