def FeatureUseRSqrt : SubtargetFeature<
"use-reciprocal-square-root", "UseRSqrt", "true",
"Use the reciprocal square root approximation">;
+
+def FeatureNoNegativeImmediates : SubtargetFeature<"no-neg-immediates",
+ "NegativeImmediates", "false",
+ "Convert immediates and instructions "
+ "to their negated or complemented "
+ "equivalent when the immediate does "
+ "not fit in the encoding.">;
+
//===----------------------------------------------------------------------===//
// Architectures.
//
let Constraints = cstr;
}
+class InstSubst<string Asm, dag Result, bit EmitPriority = 0>
+ : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>;
+
// Pseudo instructions (don't have encoding information)
class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">
: AArch64Inst<PseudoFrm, cstr> {
}
// add Rd, Rb, -imm -> sub Rd, Rn, imm
- def : InstAlias<alias#"\t$Rd, $Rn, $imm",
+ def : InstSubst<alias#"\t$Rd, $Rn, $imm",
(!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
addsub_shifted_imm32_neg:$imm), 0>;
- def : InstAlias<alias#"\t$Rd, $Rn, $imm",
+ def : InstSubst<alias#"\t$Rd, $Rn, $imm",
(!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
addsub_shifted_imm64_neg:$imm), 0>;
} // Defs = [NZCV]
// Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
- def : InstAlias<alias#"\t$Rd, $Rn, $imm",
+ def : InstSubst<alias#"\t$Rd, $Rn, $imm",
(!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
addsub_shifted_imm32_neg:$imm), 0>;
- def : InstAlias<alias#"\t$Rd, $Rn, $imm",
+ def : InstSubst<alias#"\t$Rd, $Rn, $imm",
(!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
addsub_shifted_imm64_neg:$imm), 0>;
XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
// Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
- def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
+ def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
- def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
+ def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
// Compare shorthands
let Inst{31} = 1;
}
- def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
+ def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
(!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
logical_imm32_not:$imm), 0>;
- def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
+ def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
(!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
logical_imm64_not:$imm), 0>;
}
}
} // end Defs = [NZCV]
- def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
+ def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
(!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
logical_imm32_not:$imm), 0>;
- def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
+ def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
(!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
logical_imm64_not:$imm), 0>;
}
def UseAlternateSExtLoadCVTF32
: Predicate<"Subtarget->useAlternateSExtLoadCVTF32Pattern()">;
+def UseNegativeImmediates
+ : Predicate<"false">, AssemblerPredicate<"!FeatureNoNegativeImmediates",
+ "NegativeImmediates">;
+
+
//===----------------------------------------------------------------------===//
// AArch64-specific DAG Nodes.
//
// StrictAlign - Disallow unaligned memory accesses.
bool StrictAlign = false;
+
+ // NegativeImmediates - transform instructions with negative immediates
+ bool NegativeImmediates = true;
+
bool UseAA = false;
bool PredictableSelectIsExpensive = false;
bool BalanceFPOps = false;
// RUN: llvm-mc -triple=aarch64-none-linux-gnu < %s | FileCheck %s
+// RUN: not llvm-mc -mattr=+no-neg-immediates -triple=aarch64-none-linux-gnu < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-NEG-IMM
// CHECK: sub w0, w2, #2, lsl #12
// CHECK: sub w0, w2, #2, lsl #12
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
sub w0, w2, #2, lsl 12
add w0, w2, #-2, lsl 12
// CHECK: sub x1, x3, #2, lsl #12
// CHECK: sub x1, x3, #2, lsl #12
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
sub x1, x3, #2, lsl 12
add x1, x3, #-2, lsl 12
// CHECK: sub x1, x3, #4
// CHECK: sub x1, x3, #4
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
sub x1, x3, #4
add x1, x3, #-4
// CHECK: sub x1, x3, #4095
// CHECK: sub x1, x3, #4095
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
sub x1, x3, #4095, lsl 0
add x1, x3, #-4095, lsl 0
// CHECK: sub x3, x4, #0
// CHECK: add w0, w2, #2, lsl #12
// CHECK: add w0, w2, #2, lsl #12
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
add w0, w2, #2, lsl 12
sub w0, w2, #-2, lsl 12
// CHECK: add x1, x3, #2, lsl #12
// CHECK: add x1, x3, #2, lsl #12
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
add x1, x3, #2, lsl 12
sub x1, x3, #-2, lsl 12
// CHECK: add x1, x3, #4
// CHECK: add x1, x3, #4
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
add x1, x3, #4
sub x1, x3, #-4
// CHECK: add x1, x3, #4095
// CHECK: add x1, x3, #4095
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
add x1, x3, #4095, lsl 0
sub x1, x3, #-4095, lsl 0
// CHECK: add x2, x5, #0
// CHECK: subs w0, w2, #2, lsl #12
// CHECK: subs w0, w2, #2, lsl #12
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
subs w0, w2, #2, lsl 12
adds w0, w2, #-2, lsl 12
// CHECK: subs x1, x3, #2, lsl #12
// CHECK: subs x1, x3, #2, lsl #12
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
subs x1, x3, #2, lsl 12
adds x1, x3, #-2, lsl 12
// CHECK: subs x1, x3, #4
// CHECK: subs x1, x3, #4
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
subs x1, x3, #4
adds x1, x3, #-4
// CHECK: subs x1, x3, #4095
// CHECK: subs x1, x3, #4095
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
subs x1, x3, #4095, lsl 0
adds x1, x3, #-4095, lsl 0
// CHECK: subs x3, x4, #0
// CHECK: adds w0, w2, #2, lsl #12
// CHECK: adds w0, w2, #2, lsl #12
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
adds w0, w2, #2, lsl 12
subs w0, w2, #-2, lsl 12
// CHECK: adds x1, x3, #2, lsl #12
// CHECK: adds x1, x3, #2, lsl #12
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
adds x1, x3, #2, lsl 12
subs x1, x3, #-2, lsl 12
// CHECK: adds x1, x3, #4
// CHECK: adds x1, x3, #4
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
adds x1, x3, #4
subs x1, x3, #-4
// CHECK: adds x1, x3, #4095
// CHECK: adds x1, x3, #4095
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
adds x1, x3, #4095, lsl 0
subs x1, x3, #-4095, lsl 0
// CHECK: adds x2, x5, #0
// CHECK: {{adds xzr,|cmn}} x5, #5
// CHECK: {{adds xzr,|cmn}} x5, #5
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
cmn x5, #5
cmp x5, #-5
// CHECK: {{subs xzr,|cmp}} x6, #4095
// CHECK: {{subs xzr,|cmp}} x6, #4095
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
cmp x6, #4095
cmn x6, #-4095
// CHECK: {{adds wzr,|cmn}} w7, #5
// CHECK: {{adds wzr,|cmn}} w7, #5
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
cmn w7, #5
cmp w7, #-5
// CHECK: {{subs wzr,|cmp}} w8, #4095
// CHECK: {{subs wzr,|cmp}} w8, #4095
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
cmp w8, #4095
cmn w8, #-4095
// RUN: llvm-mc -triple=aarch64-none-linux-gnu < %s | FileCheck %s
+// RUN: not llvm-mc -mattr=+no-neg-immediates -triple=aarch64-none-linux-gnu < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-NEG-IMM
// CHECK: and x0, x1, #0xfffffffffffffffd
// CHECK: and x0, x1, #0xfffffffffffffffd
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
and x0, x1, #~2
bic x0, x1, #2
// CHECK: and w0, w1, #0xfffffffd
// CHECK: and w0, w1, #0xfffffffd
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
and w0, w1, #~2
bic w0, w1, #2
// CHECK: ands x0, x1, #0xfffffffffffffffd
// CHECK: ands x0, x1, #0xfffffffffffffffd
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
ands x0, x1, #~2
bics x0, x1, #2
// CHECK: ands w0, w1, #0xfffffffd
// CHECK: ands w0, w1, #0xfffffffd
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
ands w0, w1, #~2
bics w0, w1, #2
// CHECK: orr x0, x1, #0xfffffffffffffffd
// CHECK: orr x0, x1, #0xfffffffffffffffd
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
orr x0, x1, #~2
orn x0, x1, #2
// CHECK: orr w2, w1, #0xfffffffc
// CHECK: orr w2, w1, #0xfffffffc
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
orr w2, w1, #~3
orn w2, w1, #3
// CHECK: eor x0, x1, #0xfffffffffffffffd
// CHECK: eor x0, x1, #0xfffffffffffffffd
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
eor x0, x1, #~2
eon x0, x1, #2
// CHECK: eor w2, w1, #0xfffffffc
// CHECK: eor w2, w1, #0xfffffffc
+// CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates
eor w2, w1, #~3
eon w2, w1, #3