diff --git a/cranelift/codegen/src/isa/aarch64/lower.rs b/cranelift/codegen/src/isa/aarch64/lower.rs index 4e460496dfb9..1d1068a88700 100644 --- a/cranelift/codegen/src/isa/aarch64/lower.rs +++ b/cranelift/codegen/src/isa/aarch64/lower.rs @@ -107,6 +107,15 @@ pub(crate) enum ResultRegImmShift { ImmShift(ImmShift), } +impl ResultRegImmShift { + pub fn unwrap_reg(self) -> Reg { + match self { + ResultRegImmShift::Reg(r) => r, + _ => panic!("Unwrapped ResultRegImmShift, expected reg, got: {:?}", self), + } + } +} + //============================================================================ // Lowering: convert instruction inputs to forms that we can use. @@ -1468,6 +1477,43 @@ pub(crate) fn materialize_bool_result>( } } +pub(crate) fn lower_shift_amt>( + ctx: &mut C, + amt_input: InsnInput, + dst_ty: Type, + tmp_reg: Writable, +) -> ResultRegImmShift { + let amt_ty = ctx.input_ty(amt_input.insn, amt_input.input); + + match (dst_ty, amt_ty) { + // When shifting for amounts larger than the size of the type, the CLIF shift + // instructions implement a "wrapping" behaviour, such that an i8 << 8 is + // equivalent to i8 << 0 + // + // On i32 and i64 types this matches what the aarch64 spec does, but on smaller + // types (i16, i8) we need to do this manually, so we wrap the shift amount + // with an AND instruction + (I16 | I8, _) => { + // We can ignore the top half of the shift amount register if the type is I128 + let amt_reg = put_input_in_regs(ctx, amt_input).regs()[0]; + let mask = (ty_bits(dst_ty) - 1) as u64; + ctx.emit(Inst::AluRRImmLogic { + alu_op: ALUOp::And32, + rd: tmp_reg, + rn: amt_reg, + imml: ImmLogic::maybe_from_u64(mask, I32).unwrap(), + }); + ResultRegImmShift::Reg(tmp_reg.to_reg()) + } + // TODO: We can use immlogic for i128 types here + (I128, _) | (_, I128) => { + // For I128 shifts, we need a register without immlogic + ResultRegImmShift::Reg(put_input_in_regs(ctx, amt_input).regs()[0]) + } + _ => put_input_in_reg_immshift(ctx, amt_input, ty_bits(dst_ty)), + } +} + /// This is target-word-size dependent. And it excludes booleans and reftypes. pub(crate) fn is_valid_atomic_transaction_ty(ty: Type) -> bool { match ty { diff --git a/cranelift/codegen/src/isa/aarch64/lower_inst.rs b/cranelift/codegen/src/isa/aarch64/lower_inst.rs index 8c46602cbdd0..d5c77c17eccf 100644 --- a/cranelift/codegen/src/isa/aarch64/lower_inst.rs +++ b/cranelift/codegen/src/isa/aarch64/lower_inst.rs @@ -801,10 +801,8 @@ pub(crate) fn lower_insn_to_regs>( let out_regs = get_output_reg(ctx, outputs[0]); let ty = ty.unwrap(); if ty == I128 { - // TODO: We can use immlogic here let src = put_input_in_regs(ctx, inputs[0]); - // We can ignore the top half of the shift amount register - let amt = put_input_in_regs(ctx, inputs[1]).regs()[0]; + let amt = lower_shift_amt(ctx, inputs[1], ty, out_regs.regs()[0]).unwrap_reg(); match op { Opcode::Ishl => emit_shl_i128(ctx, src, out_regs, amt), @@ -828,7 +826,7 @@ pub(crate) fn lower_insn_to_regs>( _ => unreachable!(), }; let rn = put_input_in_reg(ctx, inputs[0], narrow_mode); - let rm = put_input_in_reg_immshift(ctx, inputs[1], ty_bits(ty)); + let rm = lower_shift_amt(ctx, inputs[1], ty, out_regs.regs()[0]); let alu_op = match op { Opcode::Ishl => choose_32_64(ty, ALUOp::Lsl32, ALUOp::Lsl64), Opcode::Ushr => choose_32_64(ty, ALUOp::Lsr32, ALUOp::Lsr64), diff --git a/cranelift/filetests/filetests/isa/aarch64/shift-rotate.clif b/cranelift/filetests/filetests/isa/aarch64/shift-rotate.clif index 7bdfd3404af7..4346713ac7fc 100644 --- a/cranelift/filetests/filetests/isa/aarch64/shift-rotate.clif +++ b/cranelift/filetests/filetests/isa/aarch64/shift-rotate.clif @@ -237,12 +237,9 @@ block0(v0: i16, v1: i16): return v2 } -; check: stp fp, lr, [sp, #-16]! -; nextln: mov fp, sp -; nextln: uxth w0, w0 +; check: uxth w0, w0 +; nextln: and w1, w1, #15 ; nextln: lsr w0, w0, w1 -; nextln: ldp fp, lr, [sp], #16 -; nextln: ret function %f11(i8, i8) -> i8 { block0(v0: i8, v1: i8): @@ -250,12 +247,9 @@ block0(v0: i8, v1: i8): return v2 } -; check: stp fp, lr, [sp, #-16]! -; nextln: mov fp, sp -; nextln: uxtb w0, w0 +; check: uxtb w0, w0 +; nextln: and w1, w1, #7 ; nextln: lsr w0, w0, w1 -; nextln: ldp fp, lr, [sp], #16 -; nextln: ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; LSL, variable @@ -291,11 +285,8 @@ block0(v0: i16, v1: i16): return v2 } -; check: stp fp, lr, [sp, #-16]! -; nextln: mov fp, sp +; check: and w1, w1, #15 ; nextln: lsl w0, w0, w1 -; nextln: ldp fp, lr, [sp], #16 -; nextln: ret function %f15(i8, i8) -> i8 { block0(v0: i8, v1: i8): @@ -303,11 +294,8 @@ block0(v0: i8, v1: i8): return v2 } -; check: stp fp, lr, [sp, #-16]! -; nextln: mov fp, sp +; check: and w1, w1, #7 ; nextln: lsl w0, w0, w1 -; nextln: ldp fp, lr, [sp], #16 -; nextln: ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ASR, variable @@ -343,12 +331,8 @@ block0(v0: i16, v1: i16): return v2 } -; check: stp fp, lr, [sp, #-16]! -; nextln: mov fp, sp -; nextln: sxth w0, w0 +; check: and w1, w1, #15 ; nextln: asr w0, w0, w1 -; nextln: ldp fp, lr, [sp], #16 -; nextln: ret function %f19(i8, i8) -> i8 { block0(v0: i8, v1: i8): @@ -356,12 +340,8 @@ block0(v0: i8, v1: i8): return v2 } -; check: stp fp, lr, [sp, #-16]! -; nextln: mov fp, sp -; nextln: sxtb w0, w0 +; check: and w1, w1, #7 ; nextln: asr w0, w0, w1 -; nextln: ldp fp, lr, [sp], #16 -; nextln: ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; immediate forms diff --git a/cranelift/filetests/filetests/runtests/i128-arithmetic.clif b/cranelift/filetests/filetests/runtests/i128-arithmetic.clif index f78bdb7ed76e..f692a4dacc7a 100644 --- a/cranelift/filetests/filetests/runtests/i128-arithmetic.clif +++ b/cranelift/filetests/filetests/runtests/i128-arithmetic.clif @@ -71,136 +71,3 @@ block0(v0: i64,v1: i64,v2: i64,v3: i64): ; run: %mul_i128(0x00000000_01234567, 0x89ABCDEF_00000000, 0x00000000_FEDCBA98, 0x76543210_00000000) == [0x0121FA00_23E20B28, 0xE2946058_00000000] ; run: %mul_i128(0xC0FFEEEE_C0FFEEEE, 0xC0FFEEEE_C0FFEEEE, 0xDECAFFFF_DECAFFFF, 0xDECAFFFF_DECAFFFF) == [0xDB6B1E48_19BA1112, 0x5ECD38B5_9D1C2B7E] ; run: %mul_i128(0xC0FFEEEE_C0FFEEEE, 0xC0FFEEEE_C0FFEEEE, 0xDECAFFFF_DECAFFFF, 0xDECAFFFF_DECAFFFF) == [0xDB6B1E48_19BA1112, 0x5ECD38B5_9D1C2B7E] - - -function %ishl_i128_i8(i64, i64, i8) -> i64, i64 { -block0(v0: i64, v1: i64, v2: i8): - v3 = iconcat v0, v1 - - v4 = ishl.i128 v3, v2 - - v5, v6 = isplit v4 - return v5, v6 -} -; run: %ishl_i128_i8(0x01010101_01010101, 0x01010101_01010101, 2) == [0x04040404_04040404, 0x04040404_04040404] -; run: %ishl_i128_i8(0x01010101_01010101, 0x01010101_01010101, 9) == [0x02020202_02020200, 0x02020202_02020202] -; run: %ishl_i128_i8(0x01010101_01010101, 0xffffffff_ffffffff, 66) == [0x00000000_00000000, 0x04040404_04040404] -; run: %ishl_i128_i8(0x01010101_01010101, 0x01010101_01010101, 0) == [0x01010101_01010101, 0x01010101_01010101] -; run: %ishl_i128_i8(0x01010101_01010101, 0x01010101_01010101, 128) == [0x01010101_01010101, 0x01010101_01010101] -; run: %ishl_i128_i8(0x00000000_00000001, 0x00000000_00000000, 0) == [0x00000000_00000001, 0x00000000_00000000] -; run: %ishl_i128_i8(0x00000000_00000000, 0x00000000_00000001, 0) == [0x00000000_00000000, 0x00000000_00000001] -; run: %ishl_i128_i8(0x12340000_00000000, 0x56780000_00000000, 0) == [0x12340000_00000000, 0x56780000_00000000] -; run: %ishl_i128_i8(0x12340000_00000000, 0x56780000_00000000, 64) == [0x00000000_00000000, 0x12340000_00000000] -; run: %ishl_i128_i8(0x12340000_00000000, 0x56780000_00000000, 32) == [0x00000000_00000000, 0x00000000_12340000] -; run: %ishl_i128_i8(0x01010101_01010101, 0x01010101_01010101, 129) == [0x02020202_02020202, 0x02020202_02020202] -; run: %ishl_i128_i8(0x01010101_01010101, 0x01010101_01010101, 130) == [0x04040404_04040404, 0x04040404_04040404] - -function %ishl_i128_i128(i64, i64, i8) -> i64, i64 { -block0(v0: i64, v1: i64, v2: i8): - v3 = iconcat v0, v1 - v4 = uextend.i64 v2 - v5 = iconcat v4, v4 - - v6 = ishl.i128 v3, v5 - - v7, v8 = isplit v6 - return v7, v8 -} -; run: %ishl_i128_i128(0x01010101_01010101, 0x01010101_01010101, 2) == [0x04040404_04040404, 0x04040404_04040404] -; run: %ishl_i128_i128(0x01010101_01010101, 0x01010101_01010101, 9) == [0x02020202_02020200, 0x02020202_02020202] -; run: %ishl_i128_i128(0x01010101_01010101, 0xffffffff_ffffffff, 66) == [0x00000000_00000000, 0x04040404_04040404] -; run: %ishl_i128_i128(0x01010101_01010101, 0x01010101_01010101, 0) == [0x01010101_01010101, 0x01010101_01010101] -; run: %ishl_i128_i128(0x01010101_01010101, 0x01010101_01010101, 128) == [0x01010101_01010101, 0x01010101_01010101] -; run: %ishl_i128_i128(0x00000000_00000001, 0x00000000_00000000, 0) == [0x00000000_00000001, 0x00000000_00000000] -; run: %ishl_i128_i128(0x00000000_00000000, 0x00000000_00000001, 0) == [0x00000000_00000000, 0x00000000_00000001] -; run: %ishl_i128_i128(0x12340000_00000000, 0x56780000_00000000, 0) == [0x12340000_00000000, 0x56780000_00000000] -; run: %ishl_i128_i128(0x12340000_00000000, 0x56780000_00000000, 64) == [0x00000000_00000000, 0x12340000_00000000] -; run: %ishl_i128_i128(0x12340000_00000000, 0x56780000_00000000, 32) == [0x00000000_00000000, 0x00000000_12340000] -; run: %ishl_i128_i128(0x01010101_01010101, 0x01010101_01010101, 129) == [0x02020202_02020202, 0x02020202_02020202] -; run: %ishl_i128_i128(0x01010101_01010101, 0x01010101_01010101, 130) == [0x04040404_04040404, 0x04040404_04040404] - - -function %ushr_i128_i8(i64, i64, i8) -> i64, i64 { -block0(v0: i64, v1: i64, v2: i8): - v3 = iconcat v0, v1 - - v4 = ushr.i128 v3, v2 - - v5, v6 = isplit v4 - return v5, v6 -} -; run: %ushr_i128_i8(0x01010101_01010101, 0x01010101_01010101, 2) == [0x40404040_40404040, 0x00404040_40404040] -; run: %ushr_i128_i8(0x01010101_01010101, 0x01010101_01010101, 66) == [0x00404040_40404040, 0x00000000_00000000] -; run: %ushr_i128_i8(0x01010101_01010101, 0x01010101_01010101, 0) == [0x01010101_01010101, 0x01010101_01010101] -; run: %ushr_i128_i8(0x01010101_01010101, 0x01010101_01010101, 128) == [0x01010101_01010101, 0x01010101_01010101] -; run: %ushr_i128_i8(0x00000000_00000001, 0x00000000_00000000, 0) == [0x00000000_00000001, 0x00000000_00000000] -; run: %ushr_i128_i8(0x00000000_00000000, 0x00000000_00000001, 0) == [0x00000000_00000000, 0x00000000_00000001] -; run: %ushr_i128_i8(0x12340000_00000000, 0x56780000_00000000, 0) == [0x12340000_00000000, 0x56780000_00000000] -; run: %ushr_i128_i8(0x12340000_00000000, 0x56780000_00000000, 64) == [0x56780000_00000000, 0x00000000_00000000] -; run: %ushr_i128_i8(0x12340000_00000000, 0x56780000_00000000, 32) == [0x00000000_12340000, 0x00000000_56780000] -; run: %ushr_i128_i8(0x01010101_01010101, 0x01010101_01010101, 129) == [0x80808080_80808080, 0x00808080_80808080] -; run: %ushr_i128_i8(0x01010101_01010101, 0x01010101_01010101, 130) == [0x40404040_40404040, 0x00404040_40404040] - -function %ushr_i128_i128(i64, i64, i8) -> i64, i64 { -block0(v0: i64, v1: i64, v2: i8): - v3 = iconcat v0, v1 - v4 = uextend.i64 v2 - v5 = iconcat v4, v4 - - v6 = ushr.i128 v3, v5 - - v7, v8 = isplit v6 - return v7, v8 -} -; run: %ushr_i128_i128(0x01010101_01010101, 0x01010101_01010101, 2) == [0x40404040_40404040, 0x00404040_40404040] -; run: %ushr_i128_i128(0x01010101_01010101, 0x01010101_01010101, 66) == [0x00404040_40404040, 0x00000000_00000000] -; run: %ushr_i128_i128(0x01010101_01010101, 0x01010101_01010101, 0) == [0x01010101_01010101, 0x01010101_01010101] -; run: %ushr_i128_i128(0x01010101_01010101, 0x01010101_01010101, 128) == [0x01010101_01010101, 0x01010101_01010101] -; run: %ushr_i128_i128(0x00000000_00000001, 0x00000000_00000000, 0) == [0x00000000_00000001, 0x00000000_00000000] -; run: %ushr_i128_i128(0x00000000_00000000, 0x00000000_00000001, 0) == [0x00000000_00000000, 0x00000000_00000001] -; run: %ushr_i128_i128(0x12340000_00000000, 0x56780000_00000000, 0) == [0x12340000_00000000, 0x56780000_00000000] -; run: %ushr_i128_i128(0x12340000_00000000, 0x56780000_00000000, 64) == [0x56780000_00000000, 0x00000000_00000000] -; run: %ushr_i128_i128(0x12340000_00000000, 0x56780000_00000000, 32) == [0x00000000_12340000, 0x00000000_56780000] -; run: %ushr_i128_i128(0x01010101_01010101, 0x01010101_01010101, 129) == [0x80808080_80808080, 0x00808080_80808080] -; run: %ushr_i128_i128(0x01010101_01010101, 0x01010101_01010101, 130) == [0x40404040_40404040, 0x00404040_40404040] - - -function %sshr_i128_i8(i64, i64, i8) -> i64, i64 { -block0(v0: i64, v1: i64, v2: i8): - v3 = iconcat v0, v1 - - v4 = sshr.i128 v3, v2 - - v5, v6 = isplit v4 - return v5, v6 -} -; run: %sshr_i128_i8(0x01010101_01010101, 0x81010101_01010101, 2) == [0x40404040_40404040, 0xe0404040_40404040] -; run: %sshr_i128_i8(0x00000000_00000000, 0xffffffff_ffffffff, 32) == [0xffffffff_00000000, 0xffffffff_ffffffff] -; run: %sshr_i128_i8(0x80000000_00000000, 0xffffffff_00000000, 32) == [0x00000000_80000000, 0xffffffff_ffffffff] -; run: %sshr_i128_i8(0x12345678_9abcdef0, 0x80101010_10101010, 66) == [0xe0040404_04040404, 0xffffffff_ffffffff] -; run: %sshr_i128_i8(0x00000000_00000000, 0x00000000_00000000, 64) == [0x00000000_00000000, 0x00000000_00000000] -; run: %sshr_i128_i8(0x12345678_9abcdef0, 0x80101010_10101010, 0) == [0x12345678_9abcdef0, 0x80101010_10101010] -; run: %sshr_i128_i8(0x12345678_9abcdef0, 0x80101010_10101010, 128) == [0x12345678_9abcdef0, 0x80101010_10101010] -; run: %sshr_i128_i8(0x01010101_01010101, 0x81010101_01010101, 129) == [0x80808080_80808080, 0xc0808080_80808080] -; run: %sshr_i128_i8(0x01010101_01010101, 0x81010101_01010101, 130) == [0x40404040_40404040, 0xe0404040_40404040] - -function %sshr_i128_i128(i64, i64, i8) -> i64, i64 { -block0(v0: i64, v1: i64, v2: i8): - v3 = iconcat v0, v1 - v4 = uextend.i64 v2 - v5 = iconcat v4, v4 - - v6 = sshr.i128 v3, v5 - - v7, v8 = isplit v6 - return v7, v8 -} -; run: %sshr_i128_i128(0x01010101_01010101, 0x81010101_01010101, 2) == [0x40404040_40404040, 0xe0404040_40404040] -; run: %sshr_i128_i128(0x00000000_00000000, 0xffffffff_ffffffff, 32) == [0xffffffff_00000000, 0xffffffff_ffffffff] -; run: %sshr_i128_i128(0x80000000_00000000, 0xffffffff_00000000, 32) == [0x00000000_80000000, 0xffffffff_ffffffff] -; run: %sshr_i128_i128(0x12345678_9abcdef0, 0x80101010_10101010, 66) == [0xe0040404_04040404, 0xffffffff_ffffffff] -; run: %sshr_i128_i128(0x00000000_00000000, 0x00000000_00000000, 64) == [0x00000000_00000000, 0x00000000_00000000] -; run: %sshr_i128_i128(0x12345678_9abcdef0, 0x80101010_10101010, 0) == [0x12345678_9abcdef0, 0x80101010_10101010] -; run: %sshr_i128_i128(0x12345678_9abcdef0, 0x80101010_10101010, 128) == [0x12345678_9abcdef0, 0x80101010_10101010] -; run: %sshr_i128_i128(0x01010101_01010101, 0x81010101_01010101, 129) == [0x80808080_80808080, 0xc0808080_80808080] -; run: %sshr_i128_i128(0x01010101_01010101, 0x81010101_01010101, 130) == [0x40404040_40404040, 0xe0404040_40404040] diff --git a/cranelift/filetests/filetests/runtests/i128-shifts-small-types.clif b/cranelift/filetests/filetests/runtests/i128-shifts-small-types.clif new file mode 100644 index 000000000000..c48609270321 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/i128-shifts-small-types.clif @@ -0,0 +1,90 @@ +test run +target aarch64 + +; TODO: Merge this with the main i128-shifts file when x86_64 passes these. + +function %ishl_i16_i128(i16, i64, i64) -> i16 { +block0(v0: i16, v1: i64, v2: i64): + v3 = iconcat v1, v2 + v4 = ishl.i16 v0, v3 + return v4 +} +; run: %ishl_i16_i128(0x0000, 0, 0) == 0x0000 +; run: %ishl_i16_i128(0x0000, 1, 0) == 0x0000 +; run: %ishl_i16_i128(0x000f, 0, 4) == 0x000f +; run: %ishl_i16_i128(0x000f, 4, 0) == 0x00f0 +; run: %ishl_i16_i128(0x0004, 16, 0) == 0x0004 +; run: %ishl_i16_i128(0x0004, 17, 0) == 0x0008 +; run: %ishl_i16_i128(0x0004, 18, 1) == 0x0010 + +function %ishl_i8_i128(i8, i64, i64) -> i8 { +block0(v0: i8, v1: i64, v2: i64): + v3 = iconcat v1, v2 + v4 = ishl.i8 v0, v3 + return v4 +} +; run: %ishl_i8_i128(0x00, 0, 0) == 0x00 +; run: %ishl_i8_i128(0x00, 1, 0) == 0x00 +; run: %ishl_i8_i128(0x0f, 0, 4) == 0x0f +; run: %ishl_i8_i128(0x0f, 4, 0) == 0xf0 +; run: %ishl_i8_i128(0x04, 8, 0) == 0x04 +; run: %ishl_i8_i128(0x04, 9, 0) == 0x08 +; run: %ishl_i8_i128(0x04, 10, 1) == 0x10 + + +function %ushr_i16_i128(i16, i64, i64) -> i16 { +block0(v0: i16, v1: i64, v2: i64): + v3 = iconcat v1, v2 + v4 = ushr.i16 v0, v3 + return v4 +} +; run: %ushr_i16_i128(0x1000, 0, 0) == 0x1000 +; run: %ushr_i16_i128(0x1000, 1, 0) == 0x0800 +; run: %ushr_i16_i128(0xf000, 0, 4) == 0xf000 +; run: %ushr_i16_i128(0xf000, 4, 0) == 0x0f00 +; run: %ushr_i16_i128(0x4000, 16, 0) == 0x4000 +; run: %ushr_i16_i128(0x4000, 17, 0) == 0x2000 +; run: %ushr_i16_i128(0x4000, 18, 1) == 0x1000 + +function %ushr_i8_i128(i8, i64, i64) -> i8 { +block0(v0: i8, v1: i64, v2: i64): + v3 = iconcat v1, v2 + v4 = ushr.i8 v0, v3 + return v4 +} +; run: %ushr_i8_i128(0x10, 0, 0) == 0x10 +; run: %ushr_i8_i128(0x10, 1, 0) == 0x08 +; run: %ushr_i8_i128(0xf0, 0, 4) == 0xf0 +; run: %ushr_i8_i128(0xf0, 4, 0) == 0x0f +; run: %ushr_i8_i128(0x40, 8, 0) == 0x40 +; run: %ushr_i8_i128(0x40, 9, 0) == 0x20 +; run: %ushr_i8_i128(0x40, 10, 1) == 0x10 + + +function %sshr_i16_i128(i16, i64, i64) -> i16 { +block0(v0: i16, v1: i64, v2: i64): + v3 = iconcat v1, v2 + v4 = sshr.i16 v0, v3 + return v4 +} +; run: %sshr_i16_i128(0x8000, 0, 0) == 0x8000 +; run: %sshr_i16_i128(0x8000, 1, 0) == 0xC000 +; run: %sshr_i16_i128(0xf000, 0, 4) == 0xf000 +; run: %sshr_i16_i128(0xf000, 4, 0) == 0xff00 +; run: %sshr_i16_i128(0x4000, 16, 0) == 0x4000 +; run: %sshr_i16_i128(0x4000, 17, 0) == 0x2000 +; run: %sshr_i16_i128(0x4000, 18, 1) == 0x1000 + +function %sshr_i8_i128(i8, i64, i64) -> i8 { +block0(v0: i8, v1: i64, v2: i64): + v3 = iconcat v1, v2 + v4 = sshr.i8 v0, v3 + return v4 +} +; run: %sshr_i8_i128(0x80, 0, 0) == 0x80 +; run: %sshr_i8_i128(0x80, 1, 0) == 0xC0 +; run: %sshr_i8_i128(0xf0, 0, 4) == 0xf0 +; run: %sshr_i8_i128(0xf0, 4, 0) == 0xff +; run: %sshr_i8_i128(0x40, 8, 0) == 0x40 +; run: %sshr_i8_i128(0x40, 9, 0) == 0x20 +; run: %sshr_i8_i128(0x40, 10, 1) == 0x10 diff --git a/cranelift/filetests/filetests/runtests/i128-shifts.clif b/cranelift/filetests/filetests/runtests/i128-shifts.clif new file mode 100644 index 000000000000..1e862cb7e9ef --- /dev/null +++ b/cranelift/filetests/filetests/runtests/i128-shifts.clif @@ -0,0 +1,412 @@ +test run +target aarch64 +target x86_64 machinst + + +function %ishl_i128_i128(i64, i64, i8) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i8): + v3 = iconcat v0, v1 + v4 = uextend.i64 v2 + v5 = iconcat v4, v4 + + v6 = ishl.i128 v3, v5 + + v7, v8 = isplit v6 + return v7, v8 +} +; run: %ishl_i128_i128(0x01010101_01010101, 0x01010101_01010101, 2) == [0x04040404_04040404, 0x04040404_04040404] +; run: %ishl_i128_i128(0x01010101_01010101, 0x01010101_01010101, 9) == [0x02020202_02020200, 0x02020202_02020202] +; run: %ishl_i128_i128(0x01010101_01010101, 0xffffffff_ffffffff, 66) == [0x00000000_00000000, 0x04040404_04040404] +; run: %ishl_i128_i128(0x01010101_01010101, 0x01010101_01010101, 0) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ishl_i128_i128(0x01010101_01010101, 0x01010101_01010101, 128) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ishl_i128_i128(0x00000000_00000001, 0x00000000_00000000, 0) == [0x00000000_00000001, 0x00000000_00000000] +; run: %ishl_i128_i128(0x00000000_00000000, 0x00000000_00000001, 0) == [0x00000000_00000000, 0x00000000_00000001] +; run: %ishl_i128_i128(0x12340000_00000000, 0x56780000_00000000, 0) == [0x12340000_00000000, 0x56780000_00000000] +; run: %ishl_i128_i128(0x12340000_00000000, 0x56780000_00000000, 64) == [0x00000000_00000000, 0x12340000_00000000] +; run: %ishl_i128_i128(0x12340000_00000000, 0x56780000_00000000, 32) == [0x00000000_00000000, 0x00000000_12340000] +; run: %ishl_i128_i128(0x01010101_01010101, 0x01010101_01010101, 129) == [0x02020202_02020202, 0x02020202_02020202] +; run: %ishl_i128_i128(0x01010101_01010101, 0x01010101_01010101, 130) == [0x04040404_04040404, 0x04040404_04040404] + +function %ishl_i128_i64(i64, i64, i64) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i64): + v3 = iconcat v0, v1 + + v4 = ishl.i128 v3, v2 + + v5, v6 = isplit v4 + return v5, v6 +} +; run: %ishl_i128_i64(0x01010101_01010101, 0x01010101_01010101, 2) == [0x04040404_04040404, 0x04040404_04040404] +; run: %ishl_i128_i64(0x01010101_01010101, 0x01010101_01010101, 9) == [0x02020202_02020200, 0x02020202_02020202] +; run: %ishl_i128_i64(0x01010101_01010101, 0xffffffff_ffffffff, 66) == [0x00000000_00000000, 0x04040404_04040404] +; run: %ishl_i128_i64(0x01010101_01010101, 0x01010101_01010101, 0) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ishl_i128_i64(0x01010101_01010101, 0x01010101_01010101, 128) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ishl_i128_i64(0x00000000_00000001, 0x00000000_00000000, 0) == [0x00000000_00000001, 0x00000000_00000000] +; run: %ishl_i128_i64(0x00000000_00000000, 0x00000000_00000001, 0) == [0x00000000_00000000, 0x00000000_00000001] +; run: %ishl_i128_i64(0x12340000_00000000, 0x56780000_00000000, 0) == [0x12340000_00000000, 0x56780000_00000000] +; run: %ishl_i128_i64(0x12340000_00000000, 0x56780000_00000000, 64) == [0x00000000_00000000, 0x12340000_00000000] +; run: %ishl_i128_i64(0x12340000_00000000, 0x56780000_00000000, 32) == [0x00000000_00000000, 0x00000000_12340000] +; run: %ishl_i128_i64(0x01010101_01010101, 0x01010101_01010101, 129) == [0x02020202_02020202, 0x02020202_02020202] +; run: %ishl_i128_i64(0x01010101_01010101, 0x01010101_01010101, 130) == [0x04040404_04040404, 0x04040404_04040404] + +function %ishl_i128_i32(i64, i64, i32) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i32): + v3 = iconcat v0, v1 + + v4 = ishl.i128 v3, v2 + + v5, v6 = isplit v4 + return v5, v6 +} +; run: %ishl_i128_i32(0x01010101_01010101, 0x01010101_01010101, 2) == [0x04040404_04040404, 0x04040404_04040404] +; run: %ishl_i128_i32(0x01010101_01010101, 0x01010101_01010101, 9) == [0x02020202_02020200, 0x02020202_02020202] +; run: %ishl_i128_i32(0x01010101_01010101, 0xffffffff_ffffffff, 66) == [0x00000000_00000000, 0x04040404_04040404] +; run: %ishl_i128_i32(0x01010101_01010101, 0x01010101_01010101, 0) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ishl_i128_i32(0x01010101_01010101, 0x01010101_01010101, 128) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ishl_i128_i32(0x00000000_00000001, 0x00000000_00000000, 0) == [0x00000000_00000001, 0x00000000_00000000] +; run: %ishl_i128_i32(0x00000000_00000000, 0x00000000_00000001, 0) == [0x00000000_00000000, 0x00000000_00000001] +; run: %ishl_i128_i32(0x12340000_00000000, 0x56780000_00000000, 0) == [0x12340000_00000000, 0x56780000_00000000] +; run: %ishl_i128_i32(0x12340000_00000000, 0x56780000_00000000, 64) == [0x00000000_00000000, 0x12340000_00000000] +; run: %ishl_i128_i32(0x12340000_00000000, 0x56780000_00000000, 32) == [0x00000000_00000000, 0x00000000_12340000] +; run: %ishl_i128_i32(0x01010101_01010101, 0x01010101_01010101, 129) == [0x02020202_02020202, 0x02020202_02020202] +; run: %ishl_i128_i32(0x01010101_01010101, 0x01010101_01010101, 130) == [0x04040404_04040404, 0x04040404_04040404] + +function %ishl_i128_i16(i64, i64, i16) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i16): + v3 = iconcat v0, v1 + + v4 = ishl.i128 v3, v2 + + v5, v6 = isplit v4 + return v5, v6 +} +; run: %ishl_i128_i16(0x01010101_01010101, 0x01010101_01010101, 2) == [0x04040404_04040404, 0x04040404_04040404] +; run: %ishl_i128_i16(0x01010101_01010101, 0x01010101_01010101, 9) == [0x02020202_02020200, 0x02020202_02020202] +; run: %ishl_i128_i16(0x01010101_01010101, 0xffffffff_ffffffff, 66) == [0x00000000_00000000, 0x04040404_04040404] +; run: %ishl_i128_i16(0x01010101_01010101, 0x01010101_01010101, 0) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ishl_i128_i16(0x01010101_01010101, 0x01010101_01010101, 128) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ishl_i128_i16(0x00000000_00000001, 0x00000000_00000000, 0) == [0x00000000_00000001, 0x00000000_00000000] +; run: %ishl_i128_i16(0x00000000_00000000, 0x00000000_00000001, 0) == [0x00000000_00000000, 0x00000000_00000001] +; run: %ishl_i128_i16(0x12340000_00000000, 0x56780000_00000000, 0) == [0x12340000_00000000, 0x56780000_00000000] +; run: %ishl_i128_i16(0x12340000_00000000, 0x56780000_00000000, 64) == [0x00000000_00000000, 0x12340000_00000000] +; run: %ishl_i128_i16(0x12340000_00000000, 0x56780000_00000000, 32) == [0x00000000_00000000, 0x00000000_12340000] +; run: %ishl_i128_i16(0x01010101_01010101, 0x01010101_01010101, 129) == [0x02020202_02020202, 0x02020202_02020202] +; run: %ishl_i128_i16(0x01010101_01010101, 0x01010101_01010101, 130) == [0x04040404_04040404, 0x04040404_04040404] + +function %ishl_i128_i8(i64, i64, i8) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i8): + v3 = iconcat v0, v1 + + v4 = ishl.i128 v3, v2 + + v5, v6 = isplit v4 + return v5, v6 +} +; run: %ishl_i128_i8(0x01010101_01010101, 0x01010101_01010101, 2) == [0x04040404_04040404, 0x04040404_04040404] +; run: %ishl_i128_i8(0x01010101_01010101, 0x01010101_01010101, 9) == [0x02020202_02020200, 0x02020202_02020202] +; run: %ishl_i128_i8(0x01010101_01010101, 0xffffffff_ffffffff, 66) == [0x00000000_00000000, 0x04040404_04040404] +; run: %ishl_i128_i8(0x01010101_01010101, 0x01010101_01010101, 0) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ishl_i128_i8(0x01010101_01010101, 0x01010101_01010101, 128) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ishl_i128_i8(0x00000000_00000001, 0x00000000_00000000, 0) == [0x00000000_00000001, 0x00000000_00000000] +; run: %ishl_i128_i8(0x00000000_00000000, 0x00000000_00000001, 0) == [0x00000000_00000000, 0x00000000_00000001] +; run: %ishl_i128_i8(0x12340000_00000000, 0x56780000_00000000, 0) == [0x12340000_00000000, 0x56780000_00000000] +; run: %ishl_i128_i8(0x12340000_00000000, 0x56780000_00000000, 64) == [0x00000000_00000000, 0x12340000_00000000] +; run: %ishl_i128_i8(0x12340000_00000000, 0x56780000_00000000, 32) == [0x00000000_00000000, 0x00000000_12340000] +; run: %ishl_i128_i8(0x01010101_01010101, 0x01010101_01010101, 129) == [0x02020202_02020202, 0x02020202_02020202] +; run: %ishl_i128_i8(0x01010101_01010101, 0x01010101_01010101, 130) == [0x04040404_04040404, 0x04040404_04040404] + + +function %ishl_i64_i128(i64, i64, i64) -> i64 { +block0(v0: i64, v1: i64, v2: i64): + v3 = iconcat v1, v2 + v4 = ishl.i64 v0, v3 + return v4 +} +; run: %ishl_i64_i128(0x00000000_00000000, 0, 0) == 0x00000000_00000000 +; run: %ishl_i64_i128(0x00000000_00000000, 1, 0) == 0x00000000_00000000 +; run: %ishl_i64_i128(0x0000000f_0000000f, 0, 4) == 0x0000000f_0000000f +; run: %ishl_i64_i128(0x0000000f_0000000f, 4, 0) == 0x000000f0_000000f0 +; run: %ishl_i64_i128(0x00000000_00000004, 64, 0) == 0x00000000_00000004 +; run: %ishl_i64_i128(0x00000000_00000004, 65, 0) == 0x00000000_00000008 +; run: %ishl_i64_i128(0x00000000_00000004, 66, 1) == 0x00000000_00000010 + +function %ishl_i32_i128(i32, i64, i64) -> i32 { +block0(v0: i32, v1: i64, v2: i64): + v3 = iconcat v1, v2 + v4 = ishl.i32 v0, v3 + return v4 +} +; run: %ishl_i32_i128(0x00000000, 0, 0) == 0x00000000 +; run: %ishl_i32_i128(0x00000000, 1, 0) == 0x00000000 +; run: %ishl_i32_i128(0x0000000f, 0, 4) == 0x0000000f +; run: %ishl_i32_i128(0x0000000f, 4, 0) == 0x000000f0 +; run: %ishl_i32_i128(0x00000004, 32, 0) == 0x00000004 +; run: %ishl_i32_i128(0x00000004, 33, 0) == 0x00000008 +; run: %ishl_i32_i128(0x00000004, 34, 1) == 0x00000010 + + + +function %ushr_i128_i128(i64, i64, i8) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i8): + v3 = iconcat v0, v1 + v4 = uextend.i64 v2 + v5 = iconcat v4, v4 + + v6 = ushr.i128 v3, v5 + + v7, v8 = isplit v6 + return v7, v8 +} +; run: %ushr_i128_i128(0x01010101_01010101, 0x01010101_01010101, 2) == [0x40404040_40404040, 0x00404040_40404040] +; run: %ushr_i128_i128(0x01010101_01010101, 0x01010101_01010101, 66) == [0x00404040_40404040, 0x00000000_00000000] +; run: %ushr_i128_i128(0x01010101_01010101, 0x01010101_01010101, 0) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ushr_i128_i128(0x01010101_01010101, 0x01010101_01010101, 128) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ushr_i128_i128(0x00000000_00000001, 0x00000000_00000000, 0) == [0x00000000_00000001, 0x00000000_00000000] +; run: %ushr_i128_i128(0x00000000_00000000, 0x00000000_00000001, 0) == [0x00000000_00000000, 0x00000000_00000001] +; run: %ushr_i128_i128(0x12340000_00000000, 0x56780000_00000000, 0) == [0x12340000_00000000, 0x56780000_00000000] +; run: %ushr_i128_i128(0x12340000_00000000, 0x56780000_00000000, 64) == [0x56780000_00000000, 0x00000000_00000000] +; run: %ushr_i128_i128(0x12340000_00000000, 0x56780000_00000000, 32) == [0x00000000_12340000, 0x00000000_56780000] +; run: %ushr_i128_i128(0x01010101_01010101, 0x01010101_01010101, 129) == [0x80808080_80808080, 0x00808080_80808080] +; run: %ushr_i128_i128(0x01010101_01010101, 0x01010101_01010101, 130) == [0x40404040_40404040, 0x00404040_40404040] + +function %ushr_i128_i64(i64, i64, i64) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i64): + v3 = iconcat v0, v1 + + v4 = ushr.i128 v3, v2 + + v5, v6 = isplit v4 + return v5, v6 +} +; run: %ushr_i128_i64(0x01010101_01010101, 0x01010101_01010101, 2) == [0x40404040_40404040, 0x00404040_40404040] +; run: %ushr_i128_i64(0x01010101_01010101, 0x01010101_01010101, 66) == [0x00404040_40404040, 0x00000000_00000000] +; run: %ushr_i128_i64(0x01010101_01010101, 0x01010101_01010101, 0) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ushr_i128_i64(0x01010101_01010101, 0x01010101_01010101, 128) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ushr_i128_i64(0x00000000_00000001, 0x00000000_00000000, 0) == [0x00000000_00000001, 0x00000000_00000000] +; run: %ushr_i128_i64(0x00000000_00000000, 0x00000000_00000001, 0) == [0x00000000_00000000, 0x00000000_00000001] +; run: %ushr_i128_i64(0x12340000_00000000, 0x56780000_00000000, 0) == [0x12340000_00000000, 0x56780000_00000000] +; run: %ushr_i128_i64(0x12340000_00000000, 0x56780000_00000000, 64) == [0x56780000_00000000, 0x00000000_00000000] +; run: %ushr_i128_i64(0x12340000_00000000, 0x56780000_00000000, 32) == [0x00000000_12340000, 0x00000000_56780000] +; run: %ushr_i128_i64(0x01010101_01010101, 0x01010101_01010101, 129) == [0x80808080_80808080, 0x00808080_80808080] +; run: %ushr_i128_i64(0x01010101_01010101, 0x01010101_01010101, 130) == [0x40404040_40404040, 0x00404040_40404040] + +function %ushr_i128_i32(i64, i64, i32) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i32): + v3 = iconcat v0, v1 + + v4 = ushr.i128 v3, v2 + + v5, v6 = isplit v4 + return v5, v6 +} +; run: %ushr_i128_i32(0x01010101_01010101, 0x01010101_01010101, 2) == [0x40404040_40404040, 0x00404040_40404040] +; run: %ushr_i128_i32(0x01010101_01010101, 0x01010101_01010101, 66) == [0x00404040_40404040, 0x00000000_00000000] +; run: %ushr_i128_i32(0x01010101_01010101, 0x01010101_01010101, 0) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ushr_i128_i32(0x01010101_01010101, 0x01010101_01010101, 128) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ushr_i128_i32(0x00000000_00000001, 0x00000000_00000000, 0) == [0x00000000_00000001, 0x00000000_00000000] +; run: %ushr_i128_i32(0x00000000_00000000, 0x00000000_00000001, 0) == [0x00000000_00000000, 0x00000000_00000001] +; run: %ushr_i128_i32(0x12340000_00000000, 0x56780000_00000000, 0) == [0x12340000_00000000, 0x56780000_00000000] +; run: %ushr_i128_i32(0x12340000_00000000, 0x56780000_00000000, 64) == [0x56780000_00000000, 0x00000000_00000000] +; run: %ushr_i128_i32(0x12340000_00000000, 0x56780000_00000000, 32) == [0x00000000_12340000, 0x00000000_56780000] +; run: %ushr_i128_i32(0x01010101_01010101, 0x01010101_01010101, 129) == [0x80808080_80808080, 0x00808080_80808080] +; run: %ushr_i128_i32(0x01010101_01010101, 0x01010101_01010101, 130) == [0x40404040_40404040, 0x00404040_40404040] + +function %ushr_i128_i16(i64, i64, i16) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i16): + v3 = iconcat v0, v1 + + v4 = ushr.i128 v3, v2 + + v5, v6 = isplit v4 + return v5, v6 +} +; run: %ushr_i128_i16(0x01010101_01010101, 0x01010101_01010101, 2) == [0x40404040_40404040, 0x00404040_40404040] +; run: %ushr_i128_i16(0x01010101_01010101, 0x01010101_01010101, 66) == [0x00404040_40404040, 0x00000000_00000000] +; run: %ushr_i128_i16(0x01010101_01010101, 0x01010101_01010101, 0) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ushr_i128_i16(0x01010101_01010101, 0x01010101_01010101, 128) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ushr_i128_i16(0x00000000_00000001, 0x00000000_00000000, 0) == [0x00000000_00000001, 0x00000000_00000000] +; run: %ushr_i128_i16(0x00000000_00000000, 0x00000000_00000001, 0) == [0x00000000_00000000, 0x00000000_00000001] +; run: %ushr_i128_i16(0x12340000_00000000, 0x56780000_00000000, 0) == [0x12340000_00000000, 0x56780000_00000000] +; run: %ushr_i128_i16(0x12340000_00000000, 0x56780000_00000000, 64) == [0x56780000_00000000, 0x00000000_00000000] +; run: %ushr_i128_i16(0x12340000_00000000, 0x56780000_00000000, 32) == [0x00000000_12340000, 0x00000000_56780000] +; run: %ushr_i128_i16(0x01010101_01010101, 0x01010101_01010101, 129) == [0x80808080_80808080, 0x00808080_80808080] +; run: %ushr_i128_i16(0x01010101_01010101, 0x01010101_01010101, 130) == [0x40404040_40404040, 0x00404040_40404040] + +function %ushr_i128_i8(i64, i64, i8) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i8): + v3 = iconcat v0, v1 + + v4 = ushr.i128 v3, v2 + + v5, v6 = isplit v4 + return v5, v6 +} +; run: %ushr_i128_i8(0x01010101_01010101, 0x01010101_01010101, 2) == [0x40404040_40404040, 0x00404040_40404040] +; run: %ushr_i128_i8(0x01010101_01010101, 0x01010101_01010101, 66) == [0x00404040_40404040, 0x00000000_00000000] +; run: %ushr_i128_i8(0x01010101_01010101, 0x01010101_01010101, 0) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ushr_i128_i8(0x01010101_01010101, 0x01010101_01010101, 128) == [0x01010101_01010101, 0x01010101_01010101] +; run: %ushr_i128_i8(0x00000000_00000001, 0x00000000_00000000, 0) == [0x00000000_00000001, 0x00000000_00000000] +; run: %ushr_i128_i8(0x00000000_00000000, 0x00000000_00000001, 0) == [0x00000000_00000000, 0x00000000_00000001] +; run: %ushr_i128_i8(0x12340000_00000000, 0x56780000_00000000, 0) == [0x12340000_00000000, 0x56780000_00000000] +; run: %ushr_i128_i8(0x12340000_00000000, 0x56780000_00000000, 64) == [0x56780000_00000000, 0x00000000_00000000] +; run: %ushr_i128_i8(0x12340000_00000000, 0x56780000_00000000, 32) == [0x00000000_12340000, 0x00000000_56780000] +; run: %ushr_i128_i8(0x01010101_01010101, 0x01010101_01010101, 129) == [0x80808080_80808080, 0x00808080_80808080] +; run: %ushr_i128_i8(0x01010101_01010101, 0x01010101_01010101, 130) == [0x40404040_40404040, 0x00404040_40404040] + +function %ushr_i64_i128(i64, i64, i64) -> i64 { +block0(v0: i64, v1: i64, v2: i64): + v3 = iconcat v1, v2 + v4 = ushr.i64 v0, v3 + return v4 +} +; run: %ushr_i64_i128(0x10000000_10000000, 0, 0) == 0x10000000_10000000 +; run: %ushr_i64_i128(0x10000000_10000000, 1, 0) == 0x08000000_08000000 +; run: %ushr_i64_i128(0xf0000000_f0000000, 0, 4) == 0xf0000000_f0000000 +; run: %ushr_i64_i128(0xf0000000_f0000000, 4, 0) == 0x0f000000_0f000000 +; run: %ushr_i64_i128(0x40000000_40000000, 64, 0) == 0x40000000_40000000 +; run: %ushr_i64_i128(0x40000000_40000000, 65, 0) == 0x20000000_20000000 +; run: %ushr_i64_i128(0x40000000_40000000, 66, 1) == 0x10000000_10000000 + +function %ushr_i32_i128(i32, i64, i64) -> i32 { +block0(v0: i32, v1: i64, v2: i64): + v3 = iconcat v1, v2 + v4 = ushr.i32 v0, v3 + return v4 +} +; run: %ushr_i32_i128(0x10000000, 0, 0) == 0x10000000 +; run: %ushr_i32_i128(0x10000000, 1, 0) == 0x08000000 +; run: %ushr_i32_i128(0xf0000000, 0, 4) == 0xf0000000 +; run: %ushr_i32_i128(0xf0000000, 4, 0) == 0x0f000000 +; run: %ushr_i32_i128(0x40000000, 32, 0) == 0x40000000 +; run: %ushr_i32_i128(0x40000000, 33, 0) == 0x20000000 +; run: %ushr_i32_i128(0x40000000, 34, 1) == 0x10000000 + + + +function %sshr_i128_i128(i64, i64, i8) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i8): + v3 = iconcat v0, v1 + v4 = uextend.i64 v2 + v5 = iconcat v4, v4 + + v6 = sshr.i128 v3, v5 + + v7, v8 = isplit v6 + return v7, v8 +} +; run: %sshr_i128_i128(0x01010101_01010101, 0x81010101_01010101, 2) == [0x40404040_40404040, 0xe0404040_40404040] +; run: %sshr_i128_i128(0x00000000_00000000, 0xffffffff_ffffffff, 32) == [0xffffffff_00000000, 0xffffffff_ffffffff] +; run: %sshr_i128_i128(0x80000000_00000000, 0xffffffff_00000000, 32) == [0x00000000_80000000, 0xffffffff_ffffffff] +; run: %sshr_i128_i128(0x12345678_9abcdef0, 0x80101010_10101010, 66) == [0xe0040404_04040404, 0xffffffff_ffffffff] +; run: %sshr_i128_i128(0x00000000_00000000, 0x00000000_00000000, 64) == [0x00000000_00000000, 0x00000000_00000000] +; run: %sshr_i128_i128(0x12345678_9abcdef0, 0x80101010_10101010, 0) == [0x12345678_9abcdef0, 0x80101010_10101010] +; run: %sshr_i128_i128(0x12345678_9abcdef0, 0x80101010_10101010, 128) == [0x12345678_9abcdef0, 0x80101010_10101010] +; run: %sshr_i128_i128(0x01010101_01010101, 0x81010101_01010101, 129) == [0x80808080_80808080, 0xc0808080_80808080] +; run: %sshr_i128_i128(0x01010101_01010101, 0x81010101_01010101, 130) == [0x40404040_40404040, 0xe0404040_40404040] + +function %sshr_i128_i64(i64, i64, i64) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i64): + v3 = iconcat v0, v1 + + v4 = sshr.i128 v3, v2 + + v5, v6 = isplit v4 + return v5, v6 +} +; run: %sshr_i128_i64(0x01010101_01010101, 0x81010101_01010101, 2) == [0x40404040_40404040, 0xe0404040_40404040] +; run: %sshr_i128_i64(0x00000000_00000000, 0xffffffff_ffffffff, 32) == [0xffffffff_00000000, 0xffffffff_ffffffff] +; run: %sshr_i128_i64(0x80000000_00000000, 0xffffffff_00000000, 32) == [0x00000000_80000000, 0xffffffff_ffffffff] +; run: %sshr_i128_i64(0x12345678_9abcdef0, 0x80101010_10101010, 66) == [0xe0040404_04040404, 0xffffffff_ffffffff] +; run: %sshr_i128_i64(0x00000000_00000000, 0x00000000_00000000, 64) == [0x00000000_00000000, 0x00000000_00000000] +; run: %sshr_i128_i64(0x12345678_9abcdef0, 0x80101010_10101010, 0) == [0x12345678_9abcdef0, 0x80101010_10101010] +; run: %sshr_i128_i64(0x12345678_9abcdef0, 0x80101010_10101010, 128) == [0x12345678_9abcdef0, 0x80101010_10101010] +; run: %sshr_i128_i64(0x01010101_01010101, 0x81010101_01010101, 129) == [0x80808080_80808080, 0xc0808080_80808080] +; run: %sshr_i128_i64(0x01010101_01010101, 0x81010101_01010101, 130) == [0x40404040_40404040, 0xe0404040_40404040] + + +function %sshr_i128_i32(i64, i64, i32) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i32): + v3 = iconcat v0, v1 + + v4 = sshr.i128 v3, v2 + + v5, v6 = isplit v4 + return v5, v6 +} +; run: %sshr_i128_i32(0x01010101_01010101, 0x81010101_01010101, 2) == [0x40404040_40404040, 0xe0404040_40404040] +; run: %sshr_i128_i32(0x00000000_00000000, 0xffffffff_ffffffff, 32) == [0xffffffff_00000000, 0xffffffff_ffffffff] +; run: %sshr_i128_i32(0x80000000_00000000, 0xffffffff_00000000, 32) == [0x00000000_80000000, 0xffffffff_ffffffff] +; run: %sshr_i128_i32(0x12345678_9abcdef0, 0x80101010_10101010, 66) == [0xe0040404_04040404, 0xffffffff_ffffffff] +; run: %sshr_i128_i32(0x00000000_00000000, 0x00000000_00000000, 64) == [0x00000000_00000000, 0x00000000_00000000] +; run: %sshr_i128_i32(0x12345678_9abcdef0, 0x80101010_10101010, 0) == [0x12345678_9abcdef0, 0x80101010_10101010] +; run: %sshr_i128_i32(0x12345678_9abcdef0, 0x80101010_10101010, 128) == [0x12345678_9abcdef0, 0x80101010_10101010] +; run: %sshr_i128_i32(0x01010101_01010101, 0x81010101_01010101, 129) == [0x80808080_80808080, 0xc0808080_80808080] +; run: %sshr_i128_i32(0x01010101_01010101, 0x81010101_01010101, 130) == [0x40404040_40404040, 0xe0404040_40404040] + + +function %sshr_i128_i16(i64, i64, i16) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i16): + v3 = iconcat v0, v1 + + v4 = sshr.i128 v3, v2 + + v5, v6 = isplit v4 + return v5, v6 +} +; run: %sshr_i128_i16(0x01010101_01010101, 0x81010101_01010101, 2) == [0x40404040_40404040, 0xe0404040_40404040] +; run: %sshr_i128_i16(0x00000000_00000000, 0xffffffff_ffffffff, 32) == [0xffffffff_00000000, 0xffffffff_ffffffff] +; run: %sshr_i128_i16(0x80000000_00000000, 0xffffffff_00000000, 32) == [0x00000000_80000000, 0xffffffff_ffffffff] +; run: %sshr_i128_i16(0x12345678_9abcdef0, 0x80101010_10101010, 66) == [0xe0040404_04040404, 0xffffffff_ffffffff] +; run: %sshr_i128_i16(0x00000000_00000000, 0x00000000_00000000, 64) == [0x00000000_00000000, 0x00000000_00000000] +; run: %sshr_i128_i16(0x12345678_9abcdef0, 0x80101010_10101010, 0) == [0x12345678_9abcdef0, 0x80101010_10101010] +; run: %sshr_i128_i16(0x12345678_9abcdef0, 0x80101010_10101010, 128) == [0x12345678_9abcdef0, 0x80101010_10101010] +; run: %sshr_i128_i16(0x01010101_01010101, 0x81010101_01010101, 129) == [0x80808080_80808080, 0xc0808080_80808080] +; run: %sshr_i128_i16(0x01010101_01010101, 0x81010101_01010101, 130) == [0x40404040_40404040, 0xe0404040_40404040] + +function %sshr_i128_i8(i64, i64, i8) -> i64, i64 { +block0(v0: i64, v1: i64, v2: i8): + v3 = iconcat v0, v1 + + v4 = sshr.i128 v3, v2 + + v5, v6 = isplit v4 + return v5, v6 +} +; run: %sshr_i128_i8(0x01010101_01010101, 0x81010101_01010101, 2) == [0x40404040_40404040, 0xe0404040_40404040] +; run: %sshr_i128_i8(0x00000000_00000000, 0xffffffff_ffffffff, 32) == [0xffffffff_00000000, 0xffffffff_ffffffff] +; run: %sshr_i128_i8(0x80000000_00000000, 0xffffffff_00000000, 32) == [0x00000000_80000000, 0xffffffff_ffffffff] +; run: %sshr_i128_i8(0x12345678_9abcdef0, 0x80101010_10101010, 66) == [0xe0040404_04040404, 0xffffffff_ffffffff] +; run: %sshr_i128_i8(0x00000000_00000000, 0x00000000_00000000, 64) == [0x00000000_00000000, 0x00000000_00000000] +; run: %sshr_i128_i8(0x12345678_9abcdef0, 0x80101010_10101010, 0) == [0x12345678_9abcdef0, 0x80101010_10101010] +; run: %sshr_i128_i8(0x12345678_9abcdef0, 0x80101010_10101010, 128) == [0x12345678_9abcdef0, 0x80101010_10101010] +; run: %sshr_i128_i8(0x01010101_01010101, 0x81010101_01010101, 129) == [0x80808080_80808080, 0xc0808080_80808080] +; run: %sshr_i128_i8(0x01010101_01010101, 0x81010101_01010101, 130) == [0x40404040_40404040, 0xe0404040_40404040] + + +function %sshr_i64_i128(i64, i64, i64) -> i64 { +block0(v0: i64, v1: i64, v2: i64): + v3 = iconcat v1, v2 + v4 = sshr.i64 v0, v3 + return v4 +} +; run: %sshr_i64_i128(0x80000000_80000000, 0, 0) == 0x80000000_80000000 +; run: %sshr_i64_i128(0x80000000_80000000, 1, 0) == 0xC0000000_40000000 +; run: %sshr_i64_i128(0xf0000000_f0000000, 0, 4) == 0xf0000000_f0000000 +; run: %sshr_i64_i128(0xf0000000_f0000000, 4, 0) == 0xff000000_0f000000 +; run: %sshr_i64_i128(0x40000000_40000000, 64, 0) == 0x40000000_40000000 +; run: %sshr_i64_i128(0x40000000_40000000, 65, 0) == 0x20000000_20000000 +; run: %sshr_i64_i128(0x40000000_40000000, 66, 1) == 0x10000000_10000000 + +function %sshr_i32_i128(i32, i64, i64) -> i32 { +block0(v0: i32, v1: i64, v2: i64): + v3 = iconcat v1, v2 + v4 = sshr.i32 v0, v3 + return v4 +} +; run: %sshr_i32_i128(0x80000000, 0, 0) == 0x80000000 +; run: %sshr_i32_i128(0x80000000, 1, 0) == 0xC0000000 +; run: %sshr_i32_i128(0xf0000000, 0, 4) == 0xf0000000 +; run: %sshr_i32_i128(0xf0000000, 4, 0) == 0xff000000 +; run: %sshr_i32_i128(0x40000000, 32, 0) == 0x40000000 +; run: %sshr_i32_i128(0x40000000, 33, 0) == 0x20000000 +; run: %sshr_i32_i128(0x40000000, 34, 1) == 0x10000000 diff --git a/cranelift/filetests/filetests/runtests/shifts-small-types.clif b/cranelift/filetests/filetests/runtests/shifts-small-types.clif new file mode 100644 index 000000000000..eae20a8ef01e --- /dev/null +++ b/cranelift/filetests/filetests/runtests/shifts-small-types.clif @@ -0,0 +1,321 @@ +test run +target aarch64 + +; TODO: Merge this with the main shifts file when x86_64 & s390x passes these. + +function %ishl_i16_i64(i16, i64) -> i16 { +block0(v0: i16, v1: i64): + v2 = ishl.i16 v0, v1 + return v2 +} +; run: %ishl_i16_i64(0x0000, 0) == 0x0000 +; run: %ishl_i16_i64(0x0000, 1) == 0x0000 +; run: %ishl_i16_i64(0x000f, 0) == 0x000f +; run: %ishl_i16_i64(0x000f, 4) == 0x00f0 +; run: %ishl_i16_i64(0x0004, 16) == 0x0004 +; run: %ishl_i16_i64(0x0004, 17) == 0x0008 +; run: %ishl_i16_i64(0x0004, 18) == 0x0010 + +function %ishl_i16_i32(i16, i32) -> i16 { +block0(v0: i16, v1: i32): + v2 = ishl.i16 v0, v1 + return v2 +} +; run: %ishl_i16_i32(0x0000, 0) == 0x0000 +; run: %ishl_i16_i32(0x0000, 1) == 0x0000 +; run: %ishl_i16_i32(0x000f, 0) == 0x000f +; run: %ishl_i16_i32(0x000f, 4) == 0x00f0 +; run: %ishl_i16_i32(0x0004, 16) == 0x0004 +; run: %ishl_i16_i32(0x0004, 17) == 0x0008 +; run: %ishl_i16_i32(0x0004, 18) == 0x0010 + +function %ishl_i16_i16(i16, i16) -> i16 { +block0(v0: i16, v1: i16): + v2 = ishl.i16 v0, v1 + return v2 +} +; run: %ishl_i16_i16(0x0000, 0) == 0x0000 +; run: %ishl_i16_i16(0x0000, 1) == 0x0000 +; run: %ishl_i16_i16(0x000f, 0) == 0x000f +; run: %ishl_i16_i16(0x000f, 4) == 0x00f0 +; run: %ishl_i16_i16(0x0004, 16) == 0x0004 +; run: %ishl_i16_i16(0x0004, 17) == 0x0008 +; run: %ishl_i16_i16(0x0004, 18) == 0x0010 + +function %ishl_i16_i8(i16, i8) -> i16 { +block0(v0: i16, v1: i8): + v2 = ishl.i16 v0, v1 + return v2 +} +; run: %ishl_i16_i8(0x0000, 0) == 0x0000 +; run: %ishl_i16_i8(0x0000, 1) == 0x0000 +; run: %ishl_i16_i8(0x000f, 0) == 0x000f +; run: %ishl_i16_i8(0x000f, 4) == 0x00f0 +; run: %ishl_i16_i8(0x0004, 16) == 0x0004 +; run: %ishl_i16_i8(0x0004, 17) == 0x0008 +; run: %ishl_i16_i8(0x0004, 18) == 0x0010 + + +function %ishl_i8_i64(i8, i64) -> i8 { +block0(v0: i8, v1: i64): + v2 = ishl.i8 v0, v1 + return v2 +} +; run: %ishl_i8_i64(0x00, 0) == 0x00 +; run: %ishl_i8_i64(0x00, 1) == 0x00 +; run: %ishl_i8_i64(0x0f, 0) == 0x0f +; run: %ishl_i8_i64(0x0f, 4) == 0xf0 +; run: %ishl_i8_i64(0x04, 8) == 0x04 +; run: %ishl_i8_i64(0x04, 9) == 0x08 +; run: %ishl_i8_i64(0x04, 10) == 0x10 + +function %ishl_i8_i32(i8, i32) -> i8 { +block0(v0: i8, v1: i32): + v2 = ishl.i8 v0, v1 + return v2 +} +; run: %ishl_i8_i32(0x00, 0) == 0x00 +; run: %ishl_i8_i32(0x00, 1) == 0x00 +; run: %ishl_i8_i32(0x0f, 0) == 0x0f +; run: %ishl_i8_i32(0x0f, 4) == 0xf0 +; run: %ishl_i8_i32(0x04, 8) == 0x04 +; run: %ishl_i8_i32(0x04, 9) == 0x08 +; run: %ishl_i8_i32(0x04, 10) == 0x10 + +function %ishl_i8_i16(i8, i16) -> i8 { +block0(v0: i8, v1: i16): + v2 = ishl.i8 v0, v1 + return v2 +} +; run: %ishl_i8_i16(0x00, 0) == 0x00 +; run: %ishl_i8_i16(0x00, 1) == 0x00 +; run: %ishl_i8_i16(0x0f, 0) == 0x0f +; run: %ishl_i8_i16(0x0f, 4) == 0xf0 +; run: %ishl_i8_i16(0x04, 8) == 0x04 +; run: %ishl_i8_i16(0x04, 9) == 0x08 +; run: %ishl_i8_i16(0x04, 10) == 0x10 + +function %ishl_i8_i8(i8, i8) -> i8 { +block0(v0: i8, v1: i8): + v2 = ishl.i8 v0, v1 + return v2 +} +; run: %ishl_i8_i8(0x00, 0) == 0x00 +; run: %ishl_i8_i8(0x00, 1) == 0x00 +; run: %ishl_i8_i8(0x0f, 0) == 0x0f +; run: %ishl_i8_i8(0x0f, 4) == 0xf0 +; run: %ishl_i8_i8(0x04, 8) == 0x04 +; run: %ishl_i8_i8(0x04, 9) == 0x08 +; run: %ishl_i8_i8(0x04, 10) == 0x10 + + + +function %ushr_i16_i64(i16, i64) -> i16 { +block0(v0: i16, v1: i64): + v2 = ushr.i16 v0, v1 + return v2 +} +; run: %ushr_i16_i64(0x1000, 0) == 0x1000 +; run: %ushr_i16_i64(0x1000, 1) == 0x0800 +; run: %ushr_i16_i64(0xf000, 0) == 0xf000 +; run: %ushr_i16_i64(0xf000, 4) == 0x0f00 +; run: %ushr_i16_i64(0x4000, 16) == 0x4000 +; run: %ushr_i16_i64(0x4000, 17) == 0x2000 +; run: %ushr_i16_i64(0x4000, 18) == 0x1000 + +function %ushr_i16_i32(i16, i32) -> i16 { +block0(v0: i16, v1: i32): + v2 = ushr.i16 v0, v1 + return v2 +} +; run: %ushr_i16_i32(0x1000, 0) == 0x1000 +; run: %ushr_i16_i32(0x1000, 1) == 0x0800 +; run: %ushr_i16_i32(0xf000, 0) == 0xf000 +; run: %ushr_i16_i32(0xf000, 4) == 0x0f00 +; run: %ushr_i16_i32(0x4000, 16) == 0x4000 +; run: %ushr_i16_i32(0x4000, 17) == 0x2000 +; run: %ushr_i16_i32(0x4000, 18) == 0x1000 + +function %ushr_i16_i16(i16, i16) -> i16 { +block0(v0: i16, v1: i16): + v2 = ushr.i16 v0, v1 + return v2 +} +; run: %ushr_i16_i16(0x1000, 0) == 0x1000 +; run: %ushr_i16_i16(0x1000, 1) == 0x0800 +; run: %ushr_i16_i16(0xf000, 0) == 0xf000 +; run: %ushr_i16_i16(0xf000, 4) == 0x0f00 +; run: %ushr_i16_i16(0x4000, 16) == 0x4000 +; run: %ushr_i16_i16(0x4000, 17) == 0x2000 +; run: %ushr_i16_i16(0x4000, 18) == 0x1000 + +function %ushr_i16_i8(i16, i8) -> i16 { +block0(v0: i16, v1: i8): + v2 = ushr.i16 v0, v1 + return v2 +} +; run: %ushr_i16_i8(0x1000, 0) == 0x1000 +; run: %ushr_i16_i8(0x1000, 1) == 0x0800 +; run: %ushr_i16_i8(0xf000, 0) == 0xf000 +; run: %ushr_i16_i8(0xf000, 4) == 0x0f00 +; run: %ushr_i16_i8(0x4000, 16) == 0x4000 +; run: %ushr_i16_i8(0x4000, 17) == 0x2000 +; run: %ushr_i16_i8(0x4000, 18) == 0x1000 + +function %ushr_i8_i64(i8, i64) -> i8 { +block0(v0: i8, v1: i64): + v2 = ushr.i8 v0, v1 + return v2 +} +; run: %ushr_i8_i64(0x10, 0) == 0x10 +; run: %ushr_i8_i64(0x10, 1) == 0x08 +; run: %ushr_i8_i64(0xf0, 0) == 0xf0 +; run: %ushr_i8_i64(0xf0, 4) == 0x0f +; run: %ushr_i8_i64(0x40, 8) == 0x40 +; run: %ushr_i8_i64(0x40, 9) == 0x20 +; run: %ushr_i8_i64(0x40, 10) == 0x10 + +function %ushr_i8_i32(i8, i32) -> i8 { +block0(v0: i8, v1: i32): + v2 = ushr.i8 v0, v1 + return v2 +} +; run: %ushr_i8_i32(0x10, 0) == 0x10 +; run: %ushr_i8_i32(0x10, 1) == 0x08 +; run: %ushr_i8_i32(0xf0, 0) == 0xf0 +; run: %ushr_i8_i32(0xf0, 4) == 0x0f +; run: %ushr_i8_i32(0x40, 8) == 0x40 +; run: %ushr_i8_i32(0x40, 9) == 0x20 +; run: %ushr_i8_i32(0x40, 10) == 0x10 + +function %ushr_i8_i16(i8, i16) -> i8 { +block0(v0: i8, v1: i16): + v2 = ushr.i8 v0, v1 + return v2 +} +; run: %ushr_i8_i16(0x10, 0) == 0x10 +; run: %ushr_i8_i16(0x10, 1) == 0x08 +; run: %ushr_i8_i16(0xf0, 0) == 0xf0 +; run: %ushr_i8_i16(0xf0, 4) == 0x0f +; run: %ushr_i8_i16(0x40, 8) == 0x40 +; run: %ushr_i8_i16(0x40, 9) == 0x20 +; run: %ushr_i8_i16(0x40, 10) == 0x10 + +function %ushr_i8_i8(i8, i8) -> i8 { +block0(v0: i8, v1: i8): + v2 = ushr.i8 v0, v1 + return v2 +} +; run: %ushr_i8_i8(0x10, 0) == 0x10 +; run: %ushr_i8_i8(0x10, 1) == 0x08 +; run: %ushr_i8_i8(0xf0, 0) == 0xf0 +; run: %ushr_i8_i8(0xf0, 4) == 0x0f +; run: %ushr_i8_i8(0x40, 8) == 0x40 +; run: %ushr_i8_i8(0x40, 9) == 0x20 +; run: %ushr_i8_i8(0x40, 10) == 0x10 + + + +function %sshr_i16_i64(i16, i64) -> i16 { +block0(v0: i16, v1: i64): + v2 = sshr.i16 v0, v1 + return v2 +} +; run: %sshr_i16_i64(0x8000, 0) == 0x8000 +; run: %sshr_i16_i64(0x8000, 1) == 0xC000 +; run: %sshr_i16_i64(0xf000, 0) == 0xf000 +; run: %sshr_i16_i64(0xf000, 4) == 0xff00 +; run: %sshr_i16_i64(0x4000, 16) == 0x4000 +; run: %sshr_i16_i64(0x4000, 17) == 0x2000 +; run: %sshr_i16_i64(0x4000, 18) == 0x1000 + +function %sshr_i16_i32(i16, i32) -> i16 { +block0(v0: i16, v1: i32): + v2 = sshr.i16 v0, v1 + return v2 +} +; run: %sshr_i16_i32(0x8000, 0) == 0x8000 +; run: %sshr_i16_i32(0x8000, 1) == 0xC000 +; run: %sshr_i16_i32(0xf000, 0) == 0xf000 +; run: %sshr_i16_i32(0xf000, 4) == 0xff00 +; run: %sshr_i16_i32(0x4000, 16) == 0x4000 +; run: %sshr_i16_i32(0x4000, 17) == 0x2000 +; run: %sshr_i16_i32(0x4000, 18) == 0x1000 + +function %sshr_i16_i16(i16, i16) -> i16 { +block0(v0: i16, v1: i16): + v2 = sshr.i16 v0, v1 + return v2 +} +; run: %sshr_i16_i16(0x8000, 0) == 0x8000 +; run: %sshr_i16_i16(0x8000, 1) == 0xC000 +; run: %sshr_i16_i16(0xf000, 0) == 0xf000 +; run: %sshr_i16_i16(0xf000, 4) == 0xff00 +; run: %sshr_i16_i16(0x4000, 16) == 0x4000 +; run: %sshr_i16_i16(0x4000, 17) == 0x2000 +; run: %sshr_i16_i16(0x4000, 18) == 0x1000 + +function %sshr_i16_i8(i16, i8) -> i16 { +block0(v0: i16, v1: i8): + v2 = sshr.i16 v0, v1 + return v2 +} +; run: %sshr_i16_i8(0x8000, 0) == 0x8000 +; run: %sshr_i16_i8(0x8000, 1) == 0xC000 +; run: %sshr_i16_i8(0xf000, 0) == 0xf000 +; run: %sshr_i16_i8(0xf000, 4) == 0xff00 +; run: %sshr_i16_i8(0x4000, 16) == 0x4000 +; run: %sshr_i16_i8(0x4000, 17) == 0x2000 +; run: %sshr_i16_i8(0x4000, 18) == 0x1000 + +function %sshr_i8_i64(i8, i64) -> i8 { +block0(v0: i8, v1: i64): + v2 = sshr.i8 v0, v1 + return v2 +} +; run: %sshr_i8_i64(0x80, 0) == 0x80 +; run: %sshr_i8_i64(0x80, 1) == 0xC0 +; run: %sshr_i8_i64(0xf0, 0) == 0xf0 +; run: %sshr_i8_i64(0xf0, 4) == 0xff +; run: %sshr_i8_i64(0x40, 8) == 0x40 +; run: %sshr_i8_i64(0x40, 9) == 0x20 +; run: %sshr_i8_i64(0x40, 10) == 0x10 + +function %sshr_i8_i32(i8, i32) -> i8 { +block0(v0: i8, v1: i32): + v2 = sshr.i8 v0, v1 + return v2 +} +; run: %sshr_i8_i32(0x80, 0) == 0x80 +; run: %sshr_i8_i32(0x80, 1) == 0xC0 +; run: %sshr_i8_i32(0xf0, 0) == 0xf0 +; run: %sshr_i8_i32(0xf0, 4) == 0xff +; run: %sshr_i8_i32(0x40, 8) == 0x40 +; run: %sshr_i8_i32(0x40, 9) == 0x20 +; run: %sshr_i8_i32(0x40, 10) == 0x10 + +function %sshr_i8_i16(i8, i16) -> i8 { +block0(v0: i8, v1: i16): + v2 = sshr.i8 v0, v1 + return v2 +} +; run: %sshr_i8_i16(0x80, 0) == 0x80 +; run: %sshr_i8_i16(0x80, 1) == 0xC0 +; run: %sshr_i8_i16(0xf0, 0) == 0xf0 +; run: %sshr_i8_i16(0xf0, 4) == 0xff +; run: %sshr_i8_i16(0x40, 8) == 0x40 +; run: %sshr_i8_i16(0x40, 9) == 0x20 +; run: %sshr_i8_i16(0x40, 10) == 0x10 + +function %sshr_i8_i64(i8, i64) -> i8 { +block0(v0: i8, v1: i64): + v2 = sshr.i8 v0, v1 + return v2 +} +; run: %sshr_i8_i64(0x80, 0) == 0x80 +; run: %sshr_i8_i64(0x80, 1) == 0xC0 +; run: %sshr_i8_i64(0xf0, 0) == 0xf0 +; run: %sshr_i8_i64(0xf0, 4) == 0xff +; run: %sshr_i8_i64(0x40, 8) == 0x40 +; run: %sshr_i8_i64(0x40, 9) == 0x20 +; run: %sshr_i8_i64(0x40, 10) == 0x10 diff --git a/cranelift/filetests/filetests/runtests/shifts.clif b/cranelift/filetests/filetests/runtests/shifts.clif new file mode 100644 index 000000000000..a7b27ca3ed90 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/shifts.clif @@ -0,0 +1,320 @@ +test run +target aarch64 +target x86_64 machinst +target s390x + + +function %ishl_i64_i64(i64, i64) -> i64 { +block0(v0: i64, v1: i64): + v2 = ishl.i64 v0, v1 + return v2 +} +; run: %ishl_i64_i64(0x00000000_00000000, 0) == 0x00000000_00000000 +; run: %ishl_i64_i64(0x00000000_00000000, 1) == 0x00000000_00000000 +; run: %ishl_i64_i64(0x0000000f_0000000f, 0) == 0x0000000f_0000000f +; run: %ishl_i64_i64(0x0000000f_0000000f, 4) == 0x000000f0_000000f0 +; run: %ishl_i64_i64(0x00000000_00000004, 64) == 0x00000000_00000004 +; run: %ishl_i64_i64(0x00000000_00000004, 65) == 0x00000000_00000008 +; run: %ishl_i64_i64(0x00000000_00000004, 66) == 0x00000000_00000010 + +function %ishl_i64_i32(i64, i32) -> i64 { +block0(v0: i64, v1: i32): + v2 = ishl.i64 v0, v1 + return v2 +} +; run: %ishl_i64_i32(0x00000000_00000000, 0) == 0x00000000_00000000 +; run: %ishl_i64_i32(0x00000000_00000000, 1) == 0x00000000_00000000 +; run: %ishl_i64_i32(0x0000000f_0000000f, 0) == 0x0000000f_0000000f +; run: %ishl_i64_i32(0x0000000f_0000000f, 4) == 0x000000f0_000000f0 +; run: %ishl_i64_i32(0x00000000_00000004, 64) == 0x00000000_00000004 +; run: %ishl_i64_i32(0x00000000_00000004, 65) == 0x00000000_00000008 +; run: %ishl_i64_i32(0x00000000_00000004, 66) == 0x00000000_00000010 + +function %ishl_i64_i16(i64, i16) -> i64 { +block0(v0: i64, v1: i16): + v2 = ishl.i64 v0, v1 + return v2 +} +; run: %ishl_i64_i16(0x00000000_00000000, 0) == 0x00000000_00000000 +; run: %ishl_i64_i16(0x00000000_00000000, 1) == 0x00000000_00000000 +; run: %ishl_i64_i16(0x0000000f_0000000f, 0) == 0x0000000f_0000000f +; run: %ishl_i64_i16(0x0000000f_0000000f, 4) == 0x000000f0_000000f0 +; run: %ishl_i64_i16(0x00000000_00000004, 64) == 0x00000000_00000004 +; run: %ishl_i64_i16(0x00000000_00000004, 65) == 0x00000000_00000008 +; run: %ishl_i64_i16(0x00000000_00000004, 66) == 0x00000000_00000010 + +function %ishl_i64_i8(i64, i8) -> i64 { +block0(v0: i64, v1: i8): + v2 = ishl.i64 v0, v1 + return v2 +} +; run: %ishl_i64_i8(0x00000000_00000000, 0) == 0x00000000_00000000 +; run: %ishl_i64_i8(0x00000000_00000000, 1) == 0x00000000_00000000 +; run: %ishl_i64_i8(0x0000000f_0000000f, 0) == 0x0000000f_0000000f +; run: %ishl_i64_i8(0x0000000f_0000000f, 4) == 0x000000f0_000000f0 +; run: %ishl_i64_i8(0x00000000_00000004, 64) == 0x00000000_00000004 +; run: %ishl_i64_i8(0x00000000_00000004, 65) == 0x00000000_00000008 +; run: %ishl_i64_i8(0x00000000_00000004, 66) == 0x00000000_00000010 + + +function %ishl_i32_i64(i32, i64) -> i32 { +block0(v0: i32, v1: i64): + v2 = ishl.i32 v0, v1 + return v2 +} +; run: %ishl_i32_i64(0x00000000, 0) == 0x00000000 +; run: %ishl_i32_i64(0x00000000, 1) == 0x00000000 +; run: %ishl_i32_i64(0x0000000f, 0) == 0x0000000f +; run: %ishl_i32_i64(0x0000000f, 4) == 0x000000f0 +; run: %ishl_i32_i64(0x00000004, 32) == 0x00000004 +; run: %ishl_i32_i64(0x00000004, 33) == 0x00000008 +; run: %ishl_i32_i64(0x00000004, 34) == 0x00000010 + +function %ishl_i32_i32(i32, i32) -> i32 { +block0(v0: i32, v1: i32): + v2 = ishl.i32 v0, v1 + return v2 +} +; run: %ishl_i32_i32(0x00000000, 0) == 0x00000000 +; run: %ishl_i32_i32(0x00000000, 1) == 0x00000000 +; run: %ishl_i32_i32(0x0000000f, 0) == 0x0000000f +; run: %ishl_i32_i32(0x0000000f, 4) == 0x000000f0 +; run: %ishl_i32_i32(0x00000004, 32) == 0x00000004 +; run: %ishl_i32_i32(0x00000004, 33) == 0x00000008 +; run: %ishl_i32_i32(0x00000004, 34) == 0x00000010 + +function %ishl_i32_i16(i32, i16) -> i32 { +block0(v0: i32, v1: i16): + v2 = ishl.i32 v0, v1 + return v2 +} +; run: %ishl_i32_i16(0x00000000, 0) == 0x00000000 +; run: %ishl_i32_i16(0x00000000, 1) == 0x00000000 +; run: %ishl_i32_i16(0x0000000f, 0) == 0x0000000f +; run: %ishl_i32_i16(0x0000000f, 4) == 0x000000f0 +; run: %ishl_i32_i16(0x00000004, 32) == 0x00000004 +; run: %ishl_i32_i16(0x00000004, 33) == 0x00000008 +; run: %ishl_i32_i16(0x00000004, 34) == 0x00000010 + +function %ishl_i32_i8(i32, i8) -> i32 { +block0(v0: i32, v1: i8): + v2 = ishl.i32 v0, v1 + return v2 +} +; run: %ishl_i32_i8(0x00000000, 0) == 0x00000000 +; run: %ishl_i32_i8(0x00000000, 1) == 0x00000000 +; run: %ishl_i32_i8(0x0000000f, 0) == 0x0000000f +; run: %ishl_i32_i8(0x0000000f, 4) == 0x000000f0 +; run: %ishl_i32_i8(0x00000004, 32) == 0x00000004 +; run: %ishl_i32_i8(0x00000004, 33) == 0x00000008 +; run: %ishl_i32_i8(0x00000004, 34) == 0x00000010 + + +function %ushr_i64_i64(i64, i64) -> i64 { +block0(v0: i64, v1: i64): + v2 = ushr.i64 v0, v1 + return v2 +} +; run: %ushr_i64_i64(0x10000000_10000000, 0) == 0x10000000_10000000 +; run: %ushr_i64_i64(0x10000000_10000000, 1) == 0x08000000_08000000 +; run: %ushr_i64_i64(0xf0000000_f0000000, 0) == 0xf0000000_f0000000 +; run: %ushr_i64_i64(0xf0000000_f0000000, 4) == 0x0f000000_0f000000 +; run: %ushr_i64_i64(0x40000000_40000000, 64) == 0x40000000_40000000 +; run: %ushr_i64_i64(0x40000000_40000000, 65) == 0x20000000_20000000 +; run: %ushr_i64_i64(0x40000000_40000000, 66) == 0x10000000_10000000 + +function %ushr_i64_i32(i64, i32) -> i64 { +block0(v0: i64, v1: i32): + v2 = ushr.i64 v0, v1 + return v2 +} +; run: %ushr_i64_i32(0x10000000_10000000, 0) == 0x10000000_10000000 +; run: %ushr_i64_i32(0x10000000_10000000, 1) == 0x08000000_08000000 +; run: %ushr_i64_i32(0xf0000000_f0000000, 0) == 0xf0000000_f0000000 +; run: %ushr_i64_i32(0xf0000000_f0000000, 4) == 0x0f000000_0f000000 +; run: %ushr_i64_i32(0x40000000_40000000, 64) == 0x40000000_40000000 +; run: %ushr_i64_i32(0x40000000_40000000, 65) == 0x20000000_20000000 +; run: %ushr_i64_i32(0x40000000_40000000, 66) == 0x10000000_10000000 + +function %ushr_i64_i16(i64, i16) -> i64 { +block0(v0: i64, v1: i16): + v2 = ushr.i64 v0, v1 + return v2 +} +; run: %ushr_i64_i16(0x10000000_10000000, 0) == 0x10000000_10000000 +; run: %ushr_i64_i16(0x10000000_10000000, 1) == 0x08000000_08000000 +; run: %ushr_i64_i16(0xf0000000_f0000000, 0) == 0xf0000000_f0000000 +; run: %ushr_i64_i16(0xf0000000_f0000000, 4) == 0x0f000000_0f000000 +; run: %ushr_i64_i16(0x40000000_40000000, 64) == 0x40000000_40000000 +; run: %ushr_i64_i16(0x40000000_40000000, 65) == 0x20000000_20000000 +; run: %ushr_i64_i16(0x40000000_40000000, 66) == 0x10000000_10000000 + +function %ushr_i64_i8(i64, i8) -> i64 { +block0(v0: i64, v1: i8): + v2 = ushr.i64 v0, v1 + return v2 +} +; run: %ushr_i64_i8(0x10000000_10000000, 0) == 0x10000000_10000000 +; run: %ushr_i64_i8(0x10000000_10000000, 1) == 0x08000000_08000000 +; run: %ushr_i64_i8(0xf0000000_f0000000, 0) == 0xf0000000_f0000000 +; run: %ushr_i64_i8(0xf0000000_f0000000, 4) == 0x0f000000_0f000000 +; run: %ushr_i64_i8(0x40000000_40000000, 64) == 0x40000000_40000000 +; run: %ushr_i64_i8(0x40000000_40000000, 65) == 0x20000000_20000000 +; run: %ushr_i64_i8(0x40000000_40000000, 66) == 0x10000000_10000000 + +function %ushr_i32_i64(i32, i64) -> i32 { +block0(v0: i32, v1: i64): + v2 = ushr.i32 v0, v1 + return v2 +} +; run: %ushr_i32_i64(0x10000000, 0) == 0x10000000 +; run: %ushr_i32_i64(0x10000000, 1) == 0x08000000 +; run: %ushr_i32_i64(0xf0000000, 0) == 0xf0000000 +; run: %ushr_i32_i64(0xf0000000, 4) == 0x0f000000 +; run: %ushr_i32_i64(0x40000000, 32) == 0x40000000 +; run: %ushr_i32_i64(0x40000000, 33) == 0x20000000 +; run: %ushr_i32_i64(0x40000000, 34) == 0x10000000 + +function %ushr_i32_i32(i32, i32) -> i32 { +block0(v0: i32, v1: i32): + v2 = ushr.i32 v0, v1 + return v2 +} +; run: %ushr_i32_i32(0x10000000, 0) == 0x10000000 +; run: %ushr_i32_i32(0x10000000, 1) == 0x08000000 +; run: %ushr_i32_i32(0xf0000000, 0) == 0xf0000000 +; run: %ushr_i32_i32(0xf0000000, 4) == 0x0f000000 +; run: %ushr_i32_i32(0x40000000, 32) == 0x40000000 +; run: %ushr_i32_i32(0x40000000, 33) == 0x20000000 +; run: %ushr_i32_i32(0x40000000, 34) == 0x10000000 + +function %ushr_i32_i16(i32, i16) -> i32 { +block0(v0: i32, v1: i16): + v2 = ushr.i32 v0, v1 + return v2 +} +; run: %ushr_i32_i16(0x10000000, 0) == 0x10000000 +; run: %ushr_i32_i16(0x10000000, 1) == 0x08000000 +; run: %ushr_i32_i16(0xf0000000, 0) == 0xf0000000 +; run: %ushr_i32_i16(0xf0000000, 4) == 0x0f000000 +; run: %ushr_i32_i16(0x40000000, 32) == 0x40000000 +; run: %ushr_i32_i16(0x40000000, 33) == 0x20000000 +; run: %ushr_i32_i16(0x40000000, 34) == 0x10000000 + +function %ushr_i32_i8(i32, i8) -> i32 { +block0(v0: i32, v1: i8): + v2 = ushr.i32 v0, v1 + return v2 +} +; run: %ushr_i32_i8(0x10000000, 0) == 0x10000000 +; run: %ushr_i32_i8(0x10000000, 1) == 0x08000000 +; run: %ushr_i32_i8(0xf0000000, 0) == 0xf0000000 +; run: %ushr_i32_i8(0xf0000000, 4) == 0x0f000000 +; run: %ushr_i32_i8(0x40000000, 32) == 0x40000000 +; run: %ushr_i32_i8(0x40000000, 33) == 0x20000000 +; run: %ushr_i32_i8(0x40000000, 34) == 0x10000000 + + +function %sshr_i64_i64(i64, i64) -> i64 { +block0(v0: i64, v1: i64): + v2 = sshr.i64 v0, v1 + return v2 +} +; run: %sshr_i64_i64(0x80000000_80000000, 0) == 0x80000000_80000000 +; run: %sshr_i64_i64(0x80000000_80000000, 1) == 0xC0000000_40000000 +; run: %sshr_i64_i64(0xf0000000_f0000000, 0) == 0xf0000000_f0000000 +; run: %sshr_i64_i64(0xf0000000_f0000000, 4) == 0xff000000_0f000000 +; run: %sshr_i64_i64(0x40000000_40000000, 64) == 0x40000000_40000000 +; run: %sshr_i64_i64(0x40000000_40000000, 65) == 0x20000000_20000000 +; run: %sshr_i64_i64(0x40000000_40000000, 66) == 0x10000000_10000000 + +function %sshr_i64_i32(i64, i32) -> i64 { +block0(v0: i64, v1: i32): + v2 = sshr.i64 v0, v1 + return v2 +} +; run: %sshr_i64_i32(0x80000000_80000000, 0) == 0x80000000_80000000 +; run: %sshr_i64_i32(0x80000000_80000000, 1) == 0xC0000000_40000000 +; run: %sshr_i64_i32(0xf0000000_f0000000, 0) == 0xf0000000_f0000000 +; run: %sshr_i64_i32(0xf0000000_f0000000, 4) == 0xff000000_0f000000 +; run: %sshr_i64_i32(0x40000000_40000000, 64) == 0x40000000_40000000 +; run: %sshr_i64_i32(0x40000000_40000000, 65) == 0x20000000_20000000 +; run: %sshr_i64_i32(0x40000000_40000000, 66) == 0x10000000_10000000 + +function %sshr_i64_i16(i64, i16) -> i64 { +block0(v0: i64, v1: i16): + v2 = sshr.i64 v0, v1 + return v2 +} +; run: %sshr_i64_i16(0x80000000_80000000, 0) == 0x80000000_80000000 +; run: %sshr_i64_i16(0x80000000_80000000, 1) == 0xC0000000_40000000 +; run: %sshr_i64_i16(0xf0000000_f0000000, 0) == 0xf0000000_f0000000 +; run: %sshr_i64_i16(0xf0000000_f0000000, 4) == 0xff000000_0f000000 +; run: %sshr_i64_i16(0x40000000_40000000, 64) == 0x40000000_40000000 +; run: %sshr_i64_i16(0x40000000_40000000, 65) == 0x20000000_20000000 +; run: %sshr_i64_i16(0x40000000_40000000, 66) == 0x10000000_10000000 + +function %sshr_i64_i8(i64, i8) -> i64 { +block0(v0: i64, v1: i8): + v2 = sshr.i64 v0, v1 + return v2 +} +; run: %sshr_i64_i8(0x80000000_80000000, 0) == 0x80000000_80000000 +; run: %sshr_i64_i8(0x80000000_80000000, 1) == 0xC0000000_40000000 +; run: %sshr_i64_i8(0xf0000000_f0000000, 0) == 0xf0000000_f0000000 +; run: %sshr_i64_i8(0xf0000000_f0000000, 4) == 0xff000000_0f000000 +; run: %sshr_i64_i8(0x40000000_40000000, 64) == 0x40000000_40000000 +; run: %sshr_i64_i8(0x40000000_40000000, 65) == 0x20000000_20000000 +; run: %sshr_i64_i8(0x40000000_40000000, 66) == 0x10000000_10000000 + +function %sshr_i32_i64(i32, i64) -> i32 { +block0(v0: i32, v1: i64): + v2 = sshr.i32 v0, v1 + return v2 +} +; run: %sshr_i32_i64(0x80000000, 0) == 0x80000000 +; run: %sshr_i32_i64(0x80000000, 1) == 0xC0000000 +; run: %sshr_i32_i64(0xf0000000, 0) == 0xf0000000 +; run: %sshr_i32_i64(0xf0000000, 4) == 0xff000000 +; run: %sshr_i32_i64(0x40000000, 32) == 0x40000000 +; run: %sshr_i32_i64(0x40000000, 33) == 0x20000000 +; run: %sshr_i32_i64(0x40000000, 34) == 0x10000000 + +function %sshr_i32_i32(i32, i32) -> i32 { +block0(v0: i32, v1: i32): + v2 = sshr.i32 v0, v1 + return v2 +} +; run: %sshr_i32_i32(0x80000000, 0) == 0x80000000 +; run: %sshr_i32_i32(0x80000000, 1) == 0xC0000000 +; run: %sshr_i32_i32(0xf0000000, 0) == 0xf0000000 +; run: %sshr_i32_i32(0xf0000000, 4) == 0xff000000 +; run: %sshr_i32_i32(0x40000000, 32) == 0x40000000 +; run: %sshr_i32_i32(0x40000000, 33) == 0x20000000 +; run: %sshr_i32_i32(0x40000000, 34) == 0x10000000 + +function %sshr_i32_i16(i32, i16) -> i32 { +block0(v0: i32, v1: i16): + v2 = sshr.i32 v0, v1 + return v2 +} +; run: %sshr_i32_i16(0x80000000, 0) == 0x80000000 +; run: %sshr_i32_i16(0x80000000, 1) == 0xC0000000 +; run: %sshr_i32_i16(0xf0000000, 0) == 0xf0000000 +; run: %sshr_i32_i16(0xf0000000, 4) == 0xff000000 +; run: %sshr_i32_i16(0x40000000, 32) == 0x40000000 +; run: %sshr_i32_i16(0x40000000, 33) == 0x20000000 +; run: %sshr_i32_i16(0x40000000, 34) == 0x10000000 + +function %sshr_i32_i8(i32, i8) -> i32 { +block0(v0: i32, v1: i8): + v2 = sshr.i32 v0, v1 + return v2 +} +; run: %sshr_i32_i8(0x80000000, 0) == 0x80000000 +; run: %sshr_i32_i8(0x80000000, 1) == 0xC0000000 +; run: %sshr_i32_i8(0xf0000000, 0) == 0xf0000000 +; run: %sshr_i32_i8(0xf0000000, 4) == 0xff000000 +; run: %sshr_i32_i8(0x40000000, 32) == 0x40000000 +; run: %sshr_i32_i8(0x40000000, 33) == 0x20000000 +; run: %sshr_i32_i8(0x40000000, 34) == 0x10000000