return;
}
+ if (Opcode == ARM64::BFMXri || Opcode == ARM64::BFMWri) {
+ const MCOperand &Op0 = MI->getOperand(0); // Op1 == Op0
+ const MCOperand &Op2 = MI->getOperand(2);
+ int ImmR = MI->getOperand(3).getImm();
+ int ImmS = MI->getOperand(4).getImm();
+
+ // BFI alias
+ if (ImmS < ImmR) {
+ int BitWidth = Opcode == ARM64::BFMXri ? 64 : 32;
+ int LSB = (BitWidth - ImmR) % BitWidth;
+ int Width = ImmS + 1;
+ O << "\tbfi\t" << getRegisterName(Op0.getReg()) << ", "
+ << getRegisterName(Op2.getReg()) << ", #" << LSB << ", #" << Width;
+ printAnnotation(O, Annot);
+ return;
+ }
+
+ int LSB = ImmR;
+ int Width = ImmS - ImmR + 1;
+ // Otherwise BFXIL the prefered form
+ O << "\tbfxil\t"
+ << getRegisterName(Op0.getReg()) << ", " << getRegisterName(Op2.getReg())
+ << ", #" << LSB << ", #" << Width;
+ printAnnotation(O, Annot);
+ return;
+ }
+
// Symbolic operands for MOVZ, MOVN and MOVK already imply a shift
// (e.g. :gottprel_g1: is always going to be "lsl #16") so it should not be
// printed.
define [1 x i64] @from_clang([1 x i64] %f.coerce, i32 %n) nounwind readnone {
; CHECK-LABEL: from_clang:
-; CHECK-AARCH64: bfi w0, w1, #3, #4
-; CHECK-ARCH64-NEXT: ret
-
-; CHECK-ARM64: bfm {{w[0-9]+}}, {{w[0-9]+}}, #29, #3
+; CHECK: bfi {{w[0-9]+}}, {{w[0-9]+}}, #3, #4
entry:
%f.coerce.fca.0.extract = extractvalue [1 x i64] %f.coerce, 0
define void @test_whole32(i32* %existing, i32* %new) {
; CHECK-LABEL: test_whole32:
-; CHECK-AARCH64: bfi {{w[0-9]+}}, {{w[0-9]+}}, #26, #5
-; CHECK-ARM64: bfm {{w[0-9]+}}, {{w[0-9]+}}, #6, #4
+; CHECK: bfi {{w[0-9]+}}, {{w[0-9]+}}, #26, #5
%oldval = load volatile i32* %existing
%oldval_keep = and i32 %oldval, 2214592511 ; =0x83ffffff
define void @test_whole64(i64* %existing, i64* %new) {
; CHECK-LABEL: test_whole64:
-; CHECK-AARCH64: bfi {{x[0-9]+}}, {{x[0-9]+}}, #26, #14
-; CHECK-ARM64: bfm {{x[0-9]+}}, {{x[0-9]+}}, #38, #13
+; CHECK: bfi {{x[0-9]+}}, {{x[0-9]+}}, #26, #14
; CHECK-NOT: and
; CHECK: ret
; CHECK-AARCH64: bfi {{w[0-9]+}}, {{w[0-9]+}}, #{{0|16}}, #16
; CHECK-AARCH64-NOT: and
-; CHECK-ARM64: bfm {{x[0-9]+}}, {{x[0-9]+}}, #0, #15
+
+; CHECK-ARM64: bfxil {{x[0-9]+}}, {{x[0-9]+}}, #0, #16
; CHECK: ret
define void @test_32bit_masked(i32 *%existing, i32 *%new) {
; CHECK-LABEL: test_32bit_masked:
-; CHECK-AARCH64: bfi [[INSERT:w[0-9]+]], {{w[0-9]+}}, #3, #4
-; CHECK-AARCH64: and {{w[0-9]+}}, [[INSERT]], #0xff
-
; CHECK-ARM64: and
-; CHECK-ARM64: bfm {{w[0-9]+}}, {{w[0-9]+}}, #29, #3
+; CHECK: bfi [[INSERT:w[0-9]+]], {{w[0-9]+}}, #3, #4
+; CHECK-AARCH64: and {{w[0-9]+}}, [[INSERT]], #0xff
%oldval = load volatile i32* %existing
%oldval_keep = and i32 %oldval, 135 ; = 0x87
define void @test_64bit_masked(i64 *%existing, i64 *%new) {
; CHECK-LABEL: test_64bit_masked:
-; CHECK-AARCH64: bfi [[INSERT:x[0-9]+]], {{x[0-9]+}}, #40, #8
-; CHECK-AARCH64: and {{x[0-9]+}}, [[INSERT]], #0xffff00000000
-
; CHECK-ARM64: and
-; CHECK-ARM64: bfm {{x[0-9]+}}, {{x[0-9]+}}, #24, #7
+; CHECK: bfi [[INSERT:x[0-9]+]], {{x[0-9]+}}, #40, #8
+; CHECK-AARCH64: and {{x[0-9]+}}, [[INSERT]], #0xffff00000000
%oldval = load volatile i64* %existing
%oldval_keep = and i64 %oldval, 1095216660480 ; = 0xff_0000_0000
define void @test_32bit_complexmask(i32 *%existing, i32 *%new) {
; CHECK-LABEL: test_32bit_complexmask:
-; CHECK-AARCH64: bfi {{w[0-9]+}}, {{w[0-9]+}}, #3, #4
-; CHECK-AARCH64: and {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}
-
; CHECK-ARM64: and
-; CHECK-ARM64: bfm {{w[0-9]+}}, {{w[0-9]+}}, #29, #3
+; CHECK: bfi {{w[0-9]+}}, {{w[0-9]+}}, #3, #4
+; CHECK-AARCH64: and {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}
%oldval = load volatile i32* %existing
%oldval_keep = and i32 %oldval, 647 ; = 0x287
%combined = or i32 %oldval_keep, %newval_masked
store volatile i32 %combined, i32* %existing
; CHECK: lsr [[BIT:w[0-9]+]], {{w[0-9]+}}, #14
-; CHECK-AARCH64: bfi {{w[0-9]+}}, [[BIT]], #26, #5
-; CHECK-ARM64: bfm {{w[0-9]+}}, [[BIT]], #6, #4
+; CHECK: bfi {{w[0-9]+}}, [[BIT]], #26, #5
ret void
}
entry:
; CHECK-LABEL: fct4:
; CHECK: ldr [[REG1:x[0-9]+]],
-; CHECK-NEXT: bfm [[REG1]], x1, #16, #39
+; CHECK-NEXT: bfxil [[REG1]], x1, #16, #24
; CHECK-NEXT: str [[REG1]],
; CHECK-NEXT: ret
%0 = load i64* %y, align 8
entry:
; CHECK-LABEL: fct5:
; CHECK: ldr [[REG1:w[0-9]+]],
-; CHECK-NEXT: bfm [[REG1]], w1, #16, #18
+; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3
; CHECK-NEXT: str [[REG1]],
; CHECK-NEXT: ret
%0 = load i32* %y, align 8
entry:
; CHECK-LABEL: fct6:
; CHECK: ldr [[REG1:w[0-9]+]],
-; CHECK-NEXT: bfm [[REG1]], w1, #16, #18
+; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3
; lsr is an alias of ubfm
; CHECK-NEXT: lsr [[REG2:w[0-9]+]], [[REG1]], #2
; CHECK-NEXT: str [[REG2]],
entry:
; CHECK-LABEL: fct7:
; CHECK: ldr [[REG1:w[0-9]+]],
-; CHECK-NEXT: bfm [[REG1]], w1, #16, #18
+; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3
; lsl is an alias of ubfm
; CHECK-NEXT: lsl [[REG2:w[0-9]+]], [[REG1]], #2
; CHECK-NEXT: str [[REG2]],
entry:
; CHECK-LABEL: fct8:
; CHECK: ldr [[REG1:x[0-9]+]],
-; CHECK-NEXT: bfm [[REG1]], x1, #16, #18
+; CHECK-NEXT: bfxil [[REG1]], x1, #16, #3
; lsr is an alias of ubfm
; CHECK-NEXT: lsr [[REG2:x[0-9]+]], [[REG1]], #2
; CHECK-NEXT: str [[REG2]],
entry:
; CHECK-LABEL: fct9:
; CHECK: ldr [[REG1:x[0-9]+]],
-; CHECK-NEXT: bfm [[REG1]], x1, #16, #18
+; CHECK-NEXT: bfxil [[REG1]], x1, #16, #3
; lsr is an alias of ubfm
; CHECK-NEXT: lsl [[REG2:x[0-9]+]], [[REG1]], #2
; CHECK-NEXT: str [[REG2]],
entry:
; CHECK-LABEL: fct10:
; CHECK: ldr [[REG1:w[0-9]+]],
-; CHECK-NEXT: bfm [[REG1]], w1, #0, #2
+; CHECK-NEXT: bfxil [[REG1]], w1, #0, #3
; lsl is an alias of ubfm
; CHECK-NEXT: lsl [[REG2:w[0-9]+]], [[REG1]], #2
; CHECK-NEXT: str [[REG2]],
entry:
; CHECK-LABEL: fct11:
; CHECK: ldr [[REG1:x[0-9]+]],
-; CHECK-NEXT: bfm [[REG1]], x1, #0, #2
+; CHECK-NEXT: bfxil [[REG1]], x1, #0, #3
; lsl is an alias of ubfm
; CHECK-NEXT: lsl [[REG2:x[0-9]+]], [[REG1]], #2
; CHECK-NEXT: str [[REG2]],
entry:
; CHECK-LABEL: fct12:
; CHECK: ldr [[REG1:w[0-9]+]],
-; CHECK-NEXT: bfm [[REG1]], w1, #16, #18
+; CHECK-NEXT: bfxil [[REG1]], w1, #16, #3
; lsr is an alias of ubfm
; CHECK-NEXT: ubfx [[REG2:w[0-9]+]], [[REG1]], #2, #28
; CHECK-NEXT: str [[REG2]],
entry:
; CHECK-LABEL: fct13:
; CHECK: ldr [[REG1:x[0-9]+]],
-; CHECK-NEXT: bfm [[REG1]], x1, #16, #18
+; CHECK-NEXT: bfxil [[REG1]], x1, #16, #3
; lsr is an alias of ubfm
; CHECK-NEXT: ubfx [[REG2:x[0-9]+]], [[REG1]], #2, #60
; CHECK-NEXT: str [[REG2]],
entry:
; CHECK-LABEL: fct14:
; CHECK: ldr [[REG1:w[0-9]+]],
-; CHECK-NEXT: bfm [[REG1]], w1, #16, #23
+; CHECK-NEXT: bfxil [[REG1]], w1, #16, #8
; lsr is an alias of ubfm
; CHECK-NEXT: lsr [[REG2:w[0-9]+]], [[REG1]], #4
-; CHECK-NEXT: bfm [[REG2]], w2, #5, #7
+; CHECK-NEXT: bfxil [[REG2]], w2, #5, #3
; lsl is an alias of ubfm
; CHECK-NEXT: lsl [[REG3:w[0-9]+]], [[REG2]], #2
; CHECK-NEXT: str [[REG3]],
entry:
; CHECK-LABEL: fct15:
; CHECK: ldr [[REG1:x[0-9]+]],
-; CHECK-NEXT: bfm [[REG1]], x1, #16, #23
+; CHECK-NEXT: bfxil [[REG1]], x1, #16, #8
; lsr is an alias of ubfm
; CHECK-NEXT: lsr [[REG2:x[0-9]+]], [[REG1]], #4
-; CHECK-NEXT: bfm [[REG2]], x2, #5, #7
+; CHECK-NEXT: bfxil [[REG2]], x2, #5, #3
; lsl is an alias of ubfm
; CHECK-NEXT: lsl [[REG3:x[0-9]+]], [[REG2]], #2
; CHECK-NEXT: str [[REG3]],
; CHECK: movk [[REGCST]], #0x8160
; Do the masking
; CHECK: and [[REG2:w[0-9]+]], [[REG1]], [[REGCST]]
-; CHECK-NEXT: bfm [[REG2]], w1, #16, #18
+; CHECK-NEXT: bfxil [[REG2]], w1, #16, #3
; lsr is an alias of ubfm
; CHECK-NEXT: ubfx [[REG3:w[0-9]+]], [[REG2]], #2, #28
; CHECK-NEXT: str [[REG3]],
; CHECK: movk w[[REGCST]], #0x8160
; Do the masking
; CHECK: and [[REG2:x[0-9]+]], [[REG1]], x[[REGCST]]
-; CHECK-NEXT: bfm [[REG2]], x1, #16, #18
+; CHECK-NEXT: bfxil [[REG2]], x1, #16, #3
; lsr is an alias of ubfm
; CHECK-NEXT: ubfx [[REG3:x[0-9]+]], [[REG2]], #2, #60
; CHECK-NEXT: str [[REG3]],
%positioned_masked_field = and i32 %positioned_field, 120
%masked_dst = and i32 %dst, 7
%insertion = or i32 %masked_dst, %positioned_masked_field
-; CHECK: {{bfm|bfi}}
+; CHECK: {{bfm|bfi|bfxil}}
%shl16 = shl i32 %insertion, 8
%or18 = or i32 %shl16, %insertion
%conv19 = trunc i32 %or18 to i16
-; CHECK: {{bfm w[0-9]+, w[0-9]+, #24, #6|bfi w[0-9]+, w[0-9]+, #8, #7}}
+; CHECK: bfi {{w[0-9]+}}, {{w[0-9]+}}, #8, #7
ret i16 %conv19
}
define i32 @f0(i32* nocapture %p) nounwind {
; CHECK-STRICT: ldrh [[HIGH:w[0-9]+]], [x0, #2]
; CHECK-STRICT: ldrh [[LOW:w[0-9]+]], [x0]
-; CHECK-STRICT: bfm [[LOW]], [[HIGH]], #16, #15
+; CHECK-STRICT: bfi [[LOW]], [[HIGH]], #16, #16
; CHECK-STRICT: ret
; CHECK: ldr w0, [x0]
define i64 @f1(i64* nocapture %p) nounwind {
; CHECK-STRICT: ldp w[[LOW:[0-9]+]], w[[HIGH:[0-9]+]], [x0]
-; CHECK-STRICT: bfm x[[LOW]], x[[HIGH]], #32, #31
+; CHECK-STRICT: bfi x[[LOW]], x[[HIGH]], #32, #32
; CHECK-STRICT: ret
; CHECK: ldr x0, [x0]
bfm xzr, x4, #0, #0
bfm x4, xzr, #63, #5
bfm x5, x6, #12, #63
-// CHECK: bfm x4, x5, #12, #10 // encoding: [0xa4,0x28,0x4c,0xb3]
-// CHECK: bfm xzr, x4, #0, #0 // encoding: [0x9f,0x00,0x40,0xb3]
-// CHECK: bfm x4, xzr, #63, #5 // encoding: [0xe4,0x17,0x7f,0xb3]
-// CHECK: bfm x5, x6, #12, #63 // encoding: [0xc5,0xfc,0x4c,0xb3]
+// CHECK-AARCH64: bfm x4, x5, #12, #10 // encoding: [0xa4,0x28,0x4c,0xb3]
+// CHECK-AARCH64: bfm xzr, x4, #0, #0 // encoding: [0x9f,0x00,0x40,0xb3]
+// CHECK-AARCH64: bfm x4, xzr, #63, #5 // encoding: [0xe4,0x17,0x7f,0xb3]
+// CHECK-AARCH64: bfm x5, x6, #12, #63 // encoding: [0xc5,0xfc,0x4c,0xb3]
+// CHECK-ARM64: bfi x4, x5, #52, #11 // encoding: [0xa4,0x28,0x4c,0xb3]
+// CHECK-ARM64: bfxil xzr, x4, #0, #1 // encoding: [0x9f,0x00,0x40,0xb3]
+// CHECK-ARM64: bfi x4, xzr, #1, #6 // encoding: [0xe4,0x17,0x7f,0xb3]
+// CHECK-ARM64: bfxil x5, x6, #12, #52 // encoding: [0xc5,0xfc,0x4c,0xb3]
+
sxtb w1, w2
sxtb xzr, w3
sxth w9, w10
// CHECK-AARCH64: bfi w13, w14, #29, #3 // encoding: [0xcd,0x09,0x03,0x33]
// CHECK-AARCH64: bfi xzr, xzr, #10, #11 // encoding: [0xff,0x2b,0x76,0xb3]
-// CHECK-ARM64: bfm w9, w10, #0, #0 // encoding: [0x49,0x01,0x00,0x33]
-// CHECK-ARM64: bfm x2, x3, #1, #0 // encoding: [0x62,0x00,0x41,0xb3]
-// CHECK-ARM64: bfm x19, x20, #0, #63 // encoding: [0x93,0xfe,0x40,0xb3]
-// CHECK-ARM64: bfm x9, x10, #59, #58 // encoding: [0x49,0xe9,0x7b,0xb3]
-// CHECK-ARM64: bfm w9, w10, #0, #31 // encoding: [0x49,0x7d,0x00,0x33]
-// CHECK-ARM64: bfm w11, w12, #1, #0 // encoding: [0x8b,0x01,0x01,0x33]
-// CHECK-ARM64: bfm w13, w14, #3, #2 // encoding: [0xcd,0x09,0x03,0x33]
-// CHECK-ARM64: bfm xzr, xzr, #54, #10 // encoding: [0xff,0x2b,0x76,0xb3]
+// CHECK-ARM64: bfxil w9, w10, #0, #1 // encoding: [0x49,0x01,0x00,0x33]
+// CHECK-ARM64: bfi x2, x3, #63, #1 // encoding: [0x62,0x00,0x41,0xb3]
+// CHECK-ARM64: bfxil x19, x20, #0, #64 // encoding: [0x93,0xfe,0x40,0xb3]
+// CHECK-ARM64: bfi x9, x10, #5, #59 // encoding: [0x49,0xe9,0x7b,0xb3]
+// CHECK-ARM64: bfxil w9, w10, #0, #32 // encoding: [0x49,0x7d,0x00,0x33]
+// CHECK-ARM64: bfi w11, w12, #31, #1 // encoding: [0x8b,0x01,0x01,0x33]
+// CHECK-ARM64: bfi w13, w14, #29, #3 // encoding: [0xcd,0x09,0x03,0x33]
+// CHECK-ARM64: bfi xzr, xzr, #10, #11 // encoding: [0xff,0x2b,0x76,0xb3]
bfxil w9, w10, #0, #1
bfxil x2, x3, #63, #1
bfxil w11, w12, #31, #1
bfxil w13, w14, #29, #3
bfxil xzr, xzr, #10, #11
-// CHECK-AARCH64: bfxil w9, w10, #0, #1 // encoding: [0x49,0x01,0x00,0x33]
-// CHECK-AARCH64: bfxil x2, x3, #63, #1 // encoding: [0x62,0xfc,0x7f,0xb3]
-// CHECK-AARCH64: bfxil x19, x20, #0, #64 // encoding: [0x93,0xfe,0x40,0xb3]
-// CHECK-AARCH64: bfxil x9, x10, #5, #59 // encoding: [0x49,0xfd,0x45,0xb3]
-// CHECK-AARCH64: bfxil w9, w10, #0, #32 // encoding: [0x49,0x7d,0x00,0x33]
-// CHECK-AARCH64: bfxil w11, w12, #31, #1 // encoding: [0x8b,0x7d,0x1f,0x33]
-// CHECK-AARCH64: bfxil w13, w14, #29, #3 // encoding: [0xcd,0x7d,0x1d,0x33]
-// CHECK-AARCH64: bfxil xzr, xzr, #10, #11 // encoding: [0xff,0x53,0x4a,0xb3]
-
-// CHECK-ARM64: bfm w9, w10, #0, #0 // encoding: [0x49,0x01,0x00,0x33]
-// CHECK-ARM64: bfm x2, x3, #63, #63 // encoding: [0x62,0xfc,0x7f,0xb3]
-// CHECK-ARM64: bfm x19, x20, #0, #63 // encoding: [0x93,0xfe,0x40,0xb3]
-// CHECK-ARM64: bfm x9, x10, #5, #63 // encoding: [0x49,0xfd,0x45,0xb3]
-// CHECK-ARM64: bfm w9, w10, #0, #31 // encoding: [0x49,0x7d,0x00,0x33]
-// CHECK-ARM64: bfm w11, w12, #31, #31 // encoding: [0x8b,0x7d,0x1f,0x33]
-// CHECK-ARM64: bfm w13, w14, #29, #31 // encoding: [0xcd,0x7d,0x1d,0x33]
-// CHECK-ARM64: bfm xzr, xzr, #10, #20 // encoding: [0xff,0x53,0x4a,0xb3]
+// CHECK: bfxil w9, w10, #0, #1 // encoding: [0x49,0x01,0x00,0x33]
+// CHECK: bfxil x2, x3, #63, #1 // encoding: [0x62,0xfc,0x7f,0xb3]
+// CHECK: bfxil x19, x20, #0, #64 // encoding: [0x93,0xfe,0x40,0xb3]
+// CHECK: bfxil x9, x10, #5, #59 // encoding: [0x49,0xfd,0x45,0xb3]
+// CHECK: bfxil w9, w10, #0, #32 // encoding: [0x49,0x7d,0x00,0x33]
+// CHECK: bfxil w11, w12, #31, #1 // encoding: [0x8b,0x7d,0x1f,0x33]
+// CHECK: bfxil w13, w14, #29, #3 // encoding: [0xcd,0x7d,0x1d,0x33]
+// CHECK: bfxil xzr, xzr, #10, #11 // encoding: [0xff,0x53,0x4a,0xb3]
ubfiz w9, w10, #0, #1
ubfiz x2, x3, #63, #1
ubfx w0, w0, #2, #3
ubfx x0, x0, #2, #3
-; CHECK: bfm w0, w0, #31, #3
-; CHECK: bfm x0, x0, #63, #3
-; CHECK: bfm w0, w0, #0, #1
-; CHECK: bfm x0, x0, #0, #1
-; CHECK: bfm w0, w0, #2, #4
-; CHECK: bfm x0, x0, #2, #4
+; CHECK: bfi w0, w0, #1, #4
+; CHECK: bfi x0, x0, #1, #4
+; CHECK: bfxil w0, w0, #0, #2
+; CHECK: bfxil x0, x0, #0, #2
+; CHECK: bfxil w0, w0, #2, #3
+; CHECK: bfxil x0, x0, #2, #3
; CHECK: sbfiz w0, w0, #1, #4
; CHECK: sbfiz x0, x0, #1, #4
; CHECK: sbfx w0, w0, #2, #3
ubfiz wzr, w0, #31, #1
ubfiz xzr, x0, #31, #1
-; CHECK: bfm w1, w2, #1, #15 ; encoding: [0x41,0x3c,0x01,0x33]
-; CHECK: bfm x1, x2, #1, #15 ; encoding: [0x41,0x3c,0x41,0xb3]
+; CHECK: bfxil w1, w2, #1, #15 ; encoding: [0x41,0x3c,0x01,0x33]
+; CHECK: bfxil x1, x2, #1, #15 ; encoding: [0x41,0x3c,0x41,0xb3]
; CHECK: sbfx w1, w2, #1, #15 ; encoding: [0x41,0x3c,0x01,0x13]
; CHECK: sbfx x1, x2, #1, #15 ; encoding: [0x41,0x3c,0x41,0x93]
; CHECK: ubfx w1, w2, #1, #15 ; encoding: [0x41,0x3c,0x01,0x53]
0x41 0x3c 0x01 0x53
0x41 0x3c 0x41 0xd3
-# CHECK: bfm w1, w2, #1, #15
-# CHECK: bfm x1, x2, #1, #15
+# CHECK: bfxil w1, w2, #1, #15
+# CHECK: bfxil x1, x2, #1, #15
# CHECK: sbfx w1, w2, #1, #15
# CHECK: sbfx x1, x2, #1, #15
# CHECK: ubfx w1, w2, #1, #15