577 lines
14 KiB
LLVM
577 lines
14 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple=avr -mattr=movw -verify-machineinstrs | FileCheck %s
|
|
|
|
define i32 @shl_i32_1(i32 %a) {
|
|
; CHECK-LABEL: shl_i32_1:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsl r22
|
|
; CHECK-NEXT: rol r23
|
|
; CHECK-NEXT: rol r24
|
|
; CHECK-NEXT: rol r25
|
|
; CHECK-NEXT: ret
|
|
%res = shl i32 %a, 1
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @shl_i32_2(i32 %a) {
|
|
; CHECK-LABEL: shl_i32_2:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsl r22
|
|
; CHECK-NEXT: rol r23
|
|
; CHECK-NEXT: rol r24
|
|
; CHECK-NEXT: rol r25
|
|
; CHECK-NEXT: lsl r22
|
|
; CHECK-NEXT: rol r23
|
|
; CHECK-NEXT: rol r24
|
|
; CHECK-NEXT: rol r25
|
|
; CHECK-NEXT: ret
|
|
%res = shl i32 %a, 2
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @shl_i32_4(i32 %a) {
|
|
; CHECK-LABEL: shl_i32_4:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: swap r25
|
|
; CHECK-NEXT: andi r25, 240
|
|
; CHECK-NEXT: swap r24
|
|
; CHECK-NEXT: eor r25, r24
|
|
; CHECK-NEXT: andi r24, 240
|
|
; CHECK-NEXT: eor r25, r24
|
|
; CHECK-NEXT: swap r23
|
|
; CHECK-NEXT: eor r24, r23
|
|
; CHECK-NEXT: andi r23, 240
|
|
; CHECK-NEXT: eor r24, r23
|
|
; CHECK-NEXT: swap r22
|
|
; CHECK-NEXT: eor r23, r22
|
|
; CHECK-NEXT: andi r22, 240
|
|
; CHECK-NEXT: eor r23, r22
|
|
; CHECK-NEXT: ret
|
|
%res = shl i32 %a, 4
|
|
ret i32 %res
|
|
}
|
|
|
|
; shift four bits and then shift one bit
|
|
define i32 @shl_i32_5(i32 %a) {
|
|
; CHECK-LABEL: shl_i32_5:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: swap r25
|
|
; CHECK-NEXT: andi r25, 240
|
|
; CHECK-NEXT: swap r24
|
|
; CHECK-NEXT: eor r25, r24
|
|
; CHECK-NEXT: andi r24, 240
|
|
; CHECK-NEXT: eor r25, r24
|
|
; CHECK-NEXT: swap r23
|
|
; CHECK-NEXT: eor r24, r23
|
|
; CHECK-NEXT: andi r23, 240
|
|
; CHECK-NEXT: eor r24, r23
|
|
; CHECK-NEXT: swap r22
|
|
; CHECK-NEXT: eor r23, r22
|
|
; CHECK-NEXT: andi r22, 240
|
|
; CHECK-NEXT: eor r23, r22
|
|
; CHECK-NEXT: lsl r22
|
|
; CHECK-NEXT: rol r23
|
|
; CHECK-NEXT: rol r24
|
|
; CHECK-NEXT: rol r25
|
|
; CHECK-NEXT: ret
|
|
%res = shl i32 %a, 5
|
|
ret i32 %res
|
|
}
|
|
|
|
; shift two to the right and move the registers around
|
|
define i32 @shl_i32_6(i32 %a) {
|
|
; CHECK-LABEL: shl_i32_6:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsr r25
|
|
; CHECK-NEXT: ror r24
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: ror r22
|
|
; CHECK-NEXT: mov r18, r1
|
|
; CHECK-NEXT: ror r18
|
|
; CHECK-NEXT: lsr r25
|
|
; CHECK-NEXT: ror r24
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: ror r22
|
|
; CHECK-NEXT: ror r18
|
|
; CHECK-NEXT: mov r25, r24
|
|
; CHECK-NEXT: mov r24, r23
|
|
; CHECK-NEXT: mov r19, r22
|
|
; CHECK-NEXT: movw r22, r18
|
|
; CHECK-NEXT: ret
|
|
%res = shl i32 %a, 6
|
|
ret i32 %res
|
|
}
|
|
|
|
|
|
; shift one to the right and move registers around
|
|
define i32 @shl_i32_7(i32 %a) {
|
|
; CHECK-LABEL: shl_i32_7:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsr r25
|
|
; CHECK-NEXT: ror r24
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: ror r22
|
|
; CHECK-NEXT: mov r18, r1
|
|
; CHECK-NEXT: ror r18
|
|
; CHECK-NEXT: mov r25, r24
|
|
; CHECK-NEXT: mov r24, r23
|
|
; CHECK-NEXT: mov r19, r22
|
|
; CHECK-NEXT: movw r22, r18
|
|
; CHECK-NEXT: ret
|
|
%res = shl i32 %a, 7
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @shl_i32_8(i32 %a) {
|
|
; CHECK-LABEL: shl_i32_8:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: mov r25, r24
|
|
; CHECK-NEXT: mov r24, r23
|
|
; CHECK-NEXT: mov r23, r22
|
|
; CHECK-NEXT: mov r22, r1
|
|
; CHECK-NEXT: ret
|
|
%res = shl i32 %a, 8
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @shl_i32_9(i32 %a) {
|
|
; CHECK-LABEL: shl_i32_9:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsl r22
|
|
; CHECK-NEXT: rol r23
|
|
; CHECK-NEXT: rol r24
|
|
; CHECK-NEXT: mov r25, r24
|
|
; CHECK-NEXT: mov r24, r23
|
|
; CHECK-NEXT: mov r23, r22
|
|
; CHECK-NEXT: mov r22, r1
|
|
; CHECK-NEXT: ret
|
|
%res = shl i32 %a, 9
|
|
ret i32 %res
|
|
}
|
|
|
|
; shift 3 of 4 registers and move the others around
|
|
define i32 @shl_i32_12(i32 %a) {
|
|
; CHECK-LABEL: shl_i32_12:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: swap r24
|
|
; CHECK-NEXT: andi r24, 240
|
|
; CHECK-NEXT: swap r23
|
|
; CHECK-NEXT: eor r24, r23
|
|
; CHECK-NEXT: andi r23, 240
|
|
; CHECK-NEXT: eor r24, r23
|
|
; CHECK-NEXT: swap r22
|
|
; CHECK-NEXT: eor r23, r22
|
|
; CHECK-NEXT: andi r22, 240
|
|
; CHECK-NEXT: eor r23, r22
|
|
; CHECK-NEXT: mov r25, r24
|
|
; CHECK-NEXT: mov r24, r23
|
|
; CHECK-NEXT: mov r23, r22
|
|
; CHECK-NEXT: mov r22, r1
|
|
; CHECK-NEXT: ret
|
|
%res = shl i32 %a, 12
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @shl_i32_15(i32 %a) {
|
|
; CHECK-LABEL: shl_i32_15:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: movw r18, r22
|
|
; CHECK-NEXT: lsr r24
|
|
; CHECK-NEXT: ror r19
|
|
; CHECK-NEXT: ror r18
|
|
; CHECK-NEXT: mov r23, r1
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: mov r22, r1
|
|
; CHECK-NEXT: movw r24, r18
|
|
; CHECK-NEXT: ret
|
|
%res = shl i32 %a, 15
|
|
ret i32 %res
|
|
}
|
|
|
|
; This is a special case: this shift is performed directly inside SelectionDAG
|
|
; instead of as a custom lowering like the other shift operations.
|
|
define i32 @shl_i32_16(i32 %a) {
|
|
; CHECK-LABEL: shl_i32_16:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: movw r24, r22
|
|
; CHECK-NEXT: ldi r22, 0
|
|
; CHECK-NEXT: ldi r23, 0
|
|
; CHECK-NEXT: ret
|
|
%res = shl i32 %a, 16
|
|
ret i32 %res
|
|
}
|
|
|
|
; Combined with the register allocator, shift instructions can sometimes be
|
|
; optimized away entirely. The least significant registers are simply stored
|
|
; directly instead of moving them first.
|
|
define void @shl_i32_16_ptr(i32 %a, ptr %ptr) {
|
|
; CHECK-LABEL: shl_i32_16_ptr:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: movw r30, r20
|
|
; CHECK-NEXT: std Z+3, r23
|
|
; CHECK-NEXT: std Z+2, r22
|
|
; CHECK-NEXT: ldi r24, 0
|
|
; CHECK-NEXT: ldi r25, 0
|
|
; CHECK-NEXT: std Z+1, r25
|
|
; CHECK-NEXT: st Z, r24
|
|
; CHECK-NEXT: ret
|
|
%res = shl i32 %a, 16
|
|
store i32 %res, ptr %ptr
|
|
ret void
|
|
}
|
|
|
|
; shift only the most significant byte and then move it
|
|
define i32 @shl_i32_28(i32 %a) {
|
|
; CHECK-LABEL: shl_i32_28:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: swap r22
|
|
; CHECK-NEXT: andi r22, 240
|
|
; CHECK-NEXT: mov r25, r22
|
|
; CHECK-NEXT: mov r24, r1
|
|
; CHECK-NEXT: mov r23, r1
|
|
; CHECK-NEXT: mov r22, r1
|
|
; CHECK-NEXT: ret
|
|
%res = shl i32 %a, 28
|
|
ret i32 %res
|
|
}
|
|
|
|
; move the rightmost bit to the leftmost bit and clear the rest
|
|
define i32 @shl_i32_31(i32 %a) {
|
|
; CHECK-LABEL: shl_i32_31:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsr r22
|
|
; CHECK-NEXT: mov r25, r1
|
|
; CHECK-NEXT: ror r25
|
|
; CHECK-NEXT: mov r24, r1
|
|
; CHECK-NEXT: mov r23, r1
|
|
; CHECK-NEXT: mov r22, r1
|
|
; CHECK-NEXT: ret
|
|
%res = shl i32 %a, 31
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @lshr_i32_1(i32 %a) {
|
|
; CHECK-LABEL: lshr_i32_1:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsr r25
|
|
; CHECK-NEXT: ror r24
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: ror r22
|
|
; CHECK-NEXT: ret
|
|
%res = lshr i32 %a, 1
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @lshr_i32_2(i32 %a) {
|
|
; CHECK-LABEL: lshr_i32_2:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsr r25
|
|
; CHECK-NEXT: ror r24
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: ror r22
|
|
; CHECK-NEXT: lsr r25
|
|
; CHECK-NEXT: ror r24
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: ror r22
|
|
; CHECK-NEXT: ret
|
|
%res = lshr i32 %a, 2
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @lshr_i32_4(i32 %a) {
|
|
; CHECK-LABEL: lshr_i32_4:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: swap r22
|
|
; CHECK-NEXT: andi r22, 15
|
|
; CHECK-NEXT: swap r23
|
|
; CHECK-NEXT: eor r22, r23
|
|
; CHECK-NEXT: andi r23, 15
|
|
; CHECK-NEXT: eor r22, r23
|
|
; CHECK-NEXT: swap r24
|
|
; CHECK-NEXT: eor r23, r24
|
|
; CHECK-NEXT: andi r24, 15
|
|
; CHECK-NEXT: eor r23, r24
|
|
; CHECK-NEXT: swap r25
|
|
; CHECK-NEXT: eor r24, r25
|
|
; CHECK-NEXT: andi r25, 15
|
|
; CHECK-NEXT: eor r24, r25
|
|
; CHECK-NEXT: ret
|
|
%res = lshr i32 %a, 4
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @lshr_i32_6(i32 %a) {
|
|
; CHECK-LABEL: lshr_i32_6:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsl r22
|
|
; CHECK-NEXT: rol r23
|
|
; CHECK-NEXT: rol r24
|
|
; CHECK-NEXT: rol r25
|
|
; CHECK-NEXT: mov r19, r1
|
|
; CHECK-NEXT: rol r19
|
|
; CHECK-NEXT: lsl r22
|
|
; CHECK-NEXT: rol r23
|
|
; CHECK-NEXT: rol r24
|
|
; CHECK-NEXT: rol r25
|
|
; CHECK-NEXT: rol r19
|
|
; CHECK-NEXT: mov r22, r23
|
|
; CHECK-NEXT: mov r23, r24
|
|
; CHECK-NEXT: mov r18, r25
|
|
; CHECK-NEXT: movw r24, r18
|
|
; CHECK-NEXT: ret
|
|
%res = lshr i32 %a, 6
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @lshr_i32_7(i32 %a) {
|
|
; CHECK-LABEL: lshr_i32_7:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsl r22
|
|
; CHECK-NEXT: rol r23
|
|
; CHECK-NEXT: rol r24
|
|
; CHECK-NEXT: rol r25
|
|
; CHECK-NEXT: mov r19, r1
|
|
; CHECK-NEXT: rol r19
|
|
; CHECK-NEXT: mov r22, r23
|
|
; CHECK-NEXT: mov r23, r24
|
|
; CHECK-NEXT: mov r18, r25
|
|
; CHECK-NEXT: movw r24, r18
|
|
; CHECK-NEXT: ret
|
|
%res = lshr i32 %a, 7
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @lshr_i32_8(i32 %a) {
|
|
; CHECK-LABEL: lshr_i32_8:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: mov r22, r23
|
|
; CHECK-NEXT: mov r23, r24
|
|
; CHECK-NEXT: mov r24, r25
|
|
; CHECK-NEXT: mov r25, r1
|
|
; CHECK-NEXT: ret
|
|
%res = lshr i32 %a, 8
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @lshr_i32_9(i32 %a) {
|
|
; CHECK-LABEL: lshr_i32_9:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsr r25
|
|
; CHECK-NEXT: ror r24
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: mov r22, r23
|
|
; CHECK-NEXT: mov r23, r24
|
|
; CHECK-NEXT: mov r24, r25
|
|
; CHECK-NEXT: mov r25, r1
|
|
; CHECK-NEXT: ret
|
|
%res = lshr i32 %a, 9
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @lshr_i32_16(i32 %a) {
|
|
; CHECK-LABEL: lshr_i32_16:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: movw r22, r24
|
|
; CHECK-NEXT: ldi r24, 0
|
|
; CHECK-NEXT: ldi r25, 0
|
|
; CHECK-NEXT: ret
|
|
%res = lshr i32 %a, 16
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @lshr_i32_24(i32 %a) {
|
|
; CHECK-LABEL: lshr_i32_24:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: mov r22, r25
|
|
; CHECK-NEXT: mov r23, r1
|
|
; CHECK-NEXT: mov r24, r1
|
|
; CHECK-NEXT: mov r25, r1
|
|
; CHECK-NEXT: ret
|
|
%res = lshr i32 %a, 24
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @lshr_i32_31(i32 %a) {
|
|
; CHECK-LABEL: lshr_i32_31:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsl r25
|
|
; CHECK-NEXT: mov r22, r1
|
|
; CHECK-NEXT: rol r22
|
|
; CHECK-NEXT: mov r23, r1
|
|
; CHECK-NEXT: mov r24, r1
|
|
; CHECK-NEXT: mov r25, r1
|
|
; CHECK-NEXT: ret
|
|
%res = lshr i32 %a, 31
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @ashr_i32_1(i32 %a) {
|
|
; CHECK-LABEL: ashr_i32_1:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: asr r25
|
|
; CHECK-NEXT: ror r24
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: ror r22
|
|
; CHECK-NEXT: ret
|
|
%res = ashr i32 %a, 1
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @ashr_i32_2(i32 %a) {
|
|
; CHECK-LABEL: ashr_i32_2:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: asr r25
|
|
; CHECK-NEXT: ror r24
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: ror r22
|
|
; CHECK-NEXT: asr r25
|
|
; CHECK-NEXT: ror r24
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: ror r22
|
|
; CHECK-NEXT: ret
|
|
%res = ashr i32 %a, 2
|
|
ret i32 %res
|
|
}
|
|
|
|
; can't use the swap/andi/eor trick here
|
|
define i32 @ashr_i32_4(i32 %a) {
|
|
; CHECK-LABEL: ashr_i32_4:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: asr r25
|
|
; CHECK-NEXT: ror r24
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: ror r22
|
|
; CHECK-NEXT: asr r25
|
|
; CHECK-NEXT: ror r24
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: ror r22
|
|
; CHECK-NEXT: asr r25
|
|
; CHECK-NEXT: ror r24
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: ror r22
|
|
; CHECK-NEXT: asr r25
|
|
; CHECK-NEXT: ror r24
|
|
; CHECK-NEXT: ror r23
|
|
; CHECK-NEXT: ror r22
|
|
; CHECK-NEXT: ret
|
|
%res = ashr i32 %a, 4
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @ashr_i32_7(i32 %a) {
|
|
; CHECK-LABEL: ashr_i32_7:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsl r22
|
|
; CHECK-NEXT: rol r23
|
|
; CHECK-NEXT: rol r24
|
|
; CHECK-NEXT: rol r25
|
|
; CHECK-NEXT: sbc r19, r19
|
|
; CHECK-NEXT: mov r22, r23
|
|
; CHECK-NEXT: mov r23, r24
|
|
; CHECK-NEXT: mov r18, r25
|
|
; CHECK-NEXT: movw r24, r18
|
|
; CHECK-NEXT: ret
|
|
%res = ashr i32 %a, 7
|
|
ret i32 %res
|
|
}
|
|
|
|
; TODO: this could be optimized to 4 movs, instead of 5.
|
|
define i32 @ashr_i32_8(i32 %a) {
|
|
; CHECK-LABEL: ashr_i32_8:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: mov r19, r25
|
|
; CHECK-NEXT: lsl r19
|
|
; CHECK-NEXT: sbc r19, r19
|
|
; CHECK-NEXT: mov r22, r23
|
|
; CHECK-NEXT: mov r23, r24
|
|
; CHECK-NEXT: mov r18, r25
|
|
; CHECK-NEXT: movw r24, r18
|
|
; CHECK-NEXT: ret
|
|
%res = ashr i32 %a, 8
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @ashr_i32_16(i32 %a) {
|
|
; CHECK-LABEL: ashr_i32_16:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: movw r22, r24
|
|
; CHECK-NEXT: lsl r25
|
|
; CHECK-NEXT: sbc r25, r25
|
|
; CHECK-NEXT: mov r24, r25
|
|
; CHECK-NEXT: ret
|
|
%res = ashr i32 %a, 16
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @ashr_i32_17(i32 %a) {
|
|
; CHECK-LABEL: ashr_i32_17:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: movw r22, r24
|
|
; CHECK-NEXT: lsl r25
|
|
; CHECK-NEXT: sbc r25, r25
|
|
; CHECK-NEXT: asr r23
|
|
; CHECK-NEXT: ror r22
|
|
; CHECK-NEXT: mov r24, r25
|
|
; CHECK-NEXT: ret
|
|
%res = ashr i32 %a, 17
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @ashr_i32_22(i32 %a) {
|
|
; CHECK-LABEL: ashr_i32_22:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsl r24
|
|
; CHECK-NEXT: rol r25
|
|
; CHECK-NEXT: sbc r18, r18
|
|
; CHECK-NEXT: lsl r24
|
|
; CHECK-NEXT: rol r25
|
|
; CHECK-NEXT: mov r19, r18
|
|
; CHECK-NEXT: mov r23, r18
|
|
; CHECK-NEXT: rol r23
|
|
; CHECK-NEXT: mov r22, r25
|
|
; CHECK-NEXT: movw r24, r18
|
|
; CHECK-NEXT: ret
|
|
%res = ashr i32 %a, 22
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @ashr_i32_23(i32 %a) {
|
|
; CHECK-LABEL: ashr_i32_23:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsl r24
|
|
; CHECK-NEXT: rol r25
|
|
; CHECK-NEXT: sbc r23, r23
|
|
; CHECK-NEXT: mov r22, r25
|
|
; CHECK-NEXT: mov r24, r23
|
|
; CHECK-NEXT: mov r25, r23
|
|
; CHECK-NEXT: ret
|
|
%res = ashr i32 %a, 23
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @ashr_i32_30(i32 %a) {
|
|
; CHECK-LABEL: ashr_i32_30:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsl r25
|
|
; CHECK-NEXT: sbc r23, r23
|
|
; CHECK-NEXT: lsl r25
|
|
; CHECK-NEXT: mov r22, r23
|
|
; CHECK-NEXT: rol r22
|
|
; CHECK-NEXT: mov r24, r23
|
|
; CHECK-NEXT: mov r25, r23
|
|
; CHECK-NEXT: ret
|
|
%res = ashr i32 %a, 30
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @ashr_i32_31(i32 %a) {
|
|
; CHECK-LABEL: ashr_i32_31:
|
|
; CHECK: ; %bb.0:
|
|
; CHECK-NEXT: lsl r25
|
|
; CHECK-NEXT: sbc r22, r22
|
|
; CHECK-NEXT: mov r23, r22
|
|
; CHECK-NEXT: movw r24, r22
|
|
; CHECK-NEXT: ret
|
|
%res = ashr i32 %a, 31
|
|
ret i32 %res
|
|
}
|