llvm.org GIT mirror llvm / 94612f1
[ARM] [Assembler] Support negative immediates for A32, T32 and T16 Summary: To support negative immediates for certain arithmetic instructions, the instruction is converted to the inverse instruction with a negated (or inverted) immediate. For example, "ADD r0, r1, #FFFFFFFF" cannot be encoded as an ADD instruction. However, "SUB r0, r1, #1" is equivalent. These conversions are different from instruction aliases. An alias maps several assembler instructions onto one encoding. A conversion, however, maps an *invalid* instruction--e.g. with an immediate that cannot be represented in the encoding--to a different (but equivalent) instruction. Several instructions with negative immediates were being converted already, but this was not systematically tested, nor did it cover all instructions. This patch implements all possible substitutions for ARM, Thumb1 and Thumb2 assembler and adds tests. It also adds a feature flag (-mattr=+no-neg-immediates) to turn these substitutions off. This is helpful for users who want their code to assemble to exactly what they wrote. Reviewers: t.p.northover, rovka, samparker, javed.absar, peter.smith, rengolin Reviewed By: javed.absar Subscribers: aadg, aemerson, llvm-commits Differential Revision: https://reviews.llvm.org/D30571 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298380 91177308-0d34-0410-b5e6-96231b3b80d8 Sanne Wouda 3 years ago
11 changed file(s) with 320 addition(s) and 33 deletion(s). Raw diff Collapse all Expand all
260260 "Don't use movt/movw pairs for 32-bit "
261261 "imms">;
262262
263 def FeatureNoNegativeImmediates : SubtargetFeature<"no-neg-immediates",
264 "NegativeImmediates", "false",
265 "Convert immediates and instructions "
266 "to their negated or complemented "
267 "equivalent when the immediate does "
268 "not fit in the encoding.">;
263269
264270 //===----------------------------------------------------------------------===//
265271 // ARM ISAa.
260260 // Note: When EmitPriority == 1, the alias will be used for printing
261261 class ARMInstAlias
262262 : InstAlias, Requires<[IsARM]>;
263 class ARMInstSubst
264 : InstAlias,
265 Requires<[IsARM,UseNegativeImmediates]>;
263266 class tInstAlias
264267 : InstAlias, Requires<[IsThumb]>;
268 class tInstSubst
269 : InstAlias,
270 Requires<[IsThumb,UseNegativeImmediates]>;
265271 class t2InstAlias
266272 : InstAlias, Requires<[IsThumb2]>;
273 class t2InstSubst
274 : InstAlias,
275 Requires<[IsThumb2,UseNegativeImmediates]>;
267276 class VFP2InstAlias
268277 : InstAlias, Requires<[HasVFP2]>;
269278 class VFP2DPInstAlias
310310 AssemblerPredicate<"FeatureNaClTrap", "NaCl">;
311311 def DontUseNaClTrap : Predicate<"!Subtarget->useNaClTrap()">;
312312
313 def UseNegativeImmediates :
314 Predicate<"false">,
315 AssemblerPredicate<"!FeatureNoNegativeImmediates",
316 "NegativeImmediates">;
317
313318 // FIXME: Eventually this will be just "hasV6T2Ops".
314319 def UseMovt : Predicate<"Subtarget->useMovt(*MF)">;
315320 def DontUseMovt : Predicate<"!Subtarget->useMovt(*MF)">;
57895794
57905795 // "mov Rd, mod_imm_not" can be handled via "mvn" in assembly, just like
57915796 // for isel.
5792 def : ARMInstAlias<"mov${s}${p} $Rd, $imm",
5797 def : ARMInstSubst<"mov${s}${p} $Rd, $imm",
57935798 (MVNi rGPR:$Rd, mod_imm_not:$imm, pred:$p, cc_out:$s)>;
5794 def : ARMInstAlias<"mvn${s}${p} $Rd, $imm",
5799 def : ARMInstSubst<"mvn${s}${p} $Rd, $imm",
57955800 (MOVi rGPR:$Rd, mod_imm_not:$imm, pred:$p, cc_out:$s)>;
57965801 // Same for AND <--> BIC
5797 def : ARMInstAlias<"bic${s}${p} $Rd, $Rn, $imm",
5802 def : ARMInstSubst<"bic${s}${p} $Rd, $Rn, $imm",
57985803 (ANDri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm,
57995804 pred:$p, cc_out:$s)>;
5800 def : ARMInstAlias<"bic${s}${p} $Rdn, $imm",
5805 def : ARMInstSubst<"bic${s}${p} $Rdn, $imm",
58015806 (ANDri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm,
58025807 pred:$p, cc_out:$s)>;
5803 def : ARMInstAlias<"and${s}${p} $Rd, $Rn, $imm",
5808 def : ARMInstSubst<"and${s}${p} $Rd, $Rn, $imm",
58045809 (BICri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm,
58055810 pred:$p, cc_out:$s)>;
5806 def : ARMInstAlias<"and${s}${p} $Rdn, $imm",
5811 def : ARMInstSubst<"and${s}${p} $Rdn, $imm",
58075812 (BICri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm,
58085813 pred:$p, cc_out:$s)>;
58095814
58105815 // Likewise, "add Rd, mod_imm_neg" -> sub
5811 def : ARMInstAlias<"add${s}${p} $Rd, $Rn, $imm",
5816 def : ARMInstSubst<"add${s}${p} $Rd, $Rn, $imm",
58125817 (SUBri GPR:$Rd, GPR:$Rn, mod_imm_neg:$imm, pred:$p, cc_out:$s)>;
5813 def : ARMInstAlias<"add${s}${p} $Rd, $imm",
5818 def : ARMInstSubst<"add${s}${p} $Rd, $imm",
58145819 (SUBri GPR:$Rd, GPR:$Rd, mod_imm_neg:$imm, pred:$p, cc_out:$s)>;
5820 // Likewise, "sub Rd, mod_imm_neg" -> add
5821 def : ARMInstSubst<"sub${s}${p} $Rd, $Rn, $imm",
5822 (ADDri GPR:$Rd, GPR:$Rn, mod_imm_neg:$imm, pred:$p, cc_out:$s)>;
5823 def : ARMInstSubst<"sub${s}${p} $Rd, $imm",
5824 (ADDri GPR:$Rd, GPR:$Rd, mod_imm_neg:$imm, pred:$p, cc_out:$s)>;
5825
5826
5827 def : ARMInstSubst<"adc${s}${p} $Rd, $Rn, $imm",
5828 (SBCri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm, pred:$p, cc_out:$s)>;
5829 def : ARMInstSubst<"adc${s}${p} $Rdn, $imm",
5830 (SBCri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm, pred:$p, cc_out:$s)>;
5831 def : ARMInstSubst<"sbc${s}${p} $Rd, $Rn, $imm",
5832 (ADCri GPR:$Rd, GPR:$Rn, mod_imm_not:$imm, pred:$p, cc_out:$s)>;
5833 def : ARMInstSubst<"sbc${s}${p} $Rdn, $imm",
5834 (ADCri GPR:$Rdn, GPR:$Rdn, mod_imm_not:$imm, pred:$p, cc_out:$s)>;
5835
58155836 // Same for CMP <--> CMN via mod_imm_neg
5816 def : ARMInstAlias<"cmp${p} $Rd, $imm",
5837 def : ARMInstSubst<"cmp${p} $Rd, $imm",
58175838 (CMNri rGPR:$Rd, mod_imm_neg:$imm, pred:$p)>;
5818 def : ARMInstAlias<"cmn${p} $Rd, $imm",
5839 def : ARMInstSubst<"cmn${p} $Rd, $imm",
58195840 (CMPri rGPR:$Rd, mod_imm_neg:$imm, pred:$p)>;
58205841
58215842 // The shifter forms of the MOV instruction are aliased to the ASR, LSL,
3030 def imm0_7_neg : PatLeaf<(i32 imm), [{
3131 return (uint32_t)-N->getZExtValue() < 8;
3232 }], imm_neg_XFORM>;
33
34 def ThumbModImmNeg1_7AsmOperand : AsmOperandClass { let Name = "ThumbModImmNeg1_7"; }
35 def mod_imm1_7_neg : Operand, PatLeaf<(imm), [{
36 unsigned Value = -(unsigned)N->getZExtValue();
37 return 0 < Value && Value < 8;
38 }], imm_neg_XFORM> {
39 let ParserMatchClass = ThumbModImmNeg1_7AsmOperand;
40 }
41
42 def ThumbModImmNeg8_255AsmOperand : AsmOperandClass { let Name = "ThumbModImmNeg8_255"; }
43 def mod_imm8_255_neg : Operand, PatLeaf<(imm), [{
44 unsigned Value = -(unsigned)N->getZExtValue();
45 return 7 < Value && Value < 256;
46 }], imm_neg_XFORM> {
47 let ParserMatchClass = ThumbModImmNeg8_255AsmOperand;
48 }
49
3350
3451 def imm0_255_comp : PatLeaf<(i32 imm), [{
3552 return ~((uint32_t)N->getZExtValue()) < 256;
401418 let DecoderMethod = "DecodeThumbAddSPImm";
402419 }
403420
404 def : tInstAlias<"add${p} sp, $imm",
421 def : tInstSubst<"add${p} sp, $imm",
405422 (tSUBspi SP, t_imm0_508s4_neg:$imm, pred:$p)>;
406 def : tInstAlias<"add${p} sp, sp, $imm",
423 def : tInstSubst<"add${p} sp, sp, $imm",
407424 (tSUBspi SP, t_imm0_508s4_neg:$imm, pred:$p)>;
408425
409426 // Can optionally specify SP as a three operand instruction.
945962 }
946963 }
947964
965 def : tInstSubst<"sub${s}${p} $rd, $rn, $imm",
966 (tADDi3 tGPR:$rd, s_cc_out:$s, tGPR:$rn, mod_imm1_7_neg:$imm, pred:$p)>;
967 def : tInstSubst<"sub${s}${p} $rdn, $imm",
968 (tADDi8 tGPR:$rdn, s_cc_out:$s, mod_imm8_255_neg:$imm, pred:$p)>;
969
970
948971 // AND register
949972 let isCommutable = 1 in
950973 def tAND : // A8.6.12
12111234 "sub", "\t$Rdn, $imm8",
12121235 [(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255_neg:$imm8))]>,
12131236 Sched<[WriteALU]>;
1237
1238 def : tInstSubst<"add${s}${p} $rd, $rn, $imm",
1239 (tSUBi3 tGPR:$rd, s_cc_out:$s, tGPR:$rn, mod_imm1_7_neg:$imm, pred:$p)>;
1240
1241
1242 def : tInstSubst<"add${s}${p} $rdn, $imm",
1243 (tSUBi8 tGPR:$rdn, s_cc_out:$s, mod_imm8_255_neg:$imm, pred:$p)>;
1244
12141245
12151246 // Subtract register
12161247 def tSUBrr : // A8.6.212
20782078 defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc", ARMsube>;
20792079 }
20802080
2081 def : t2InstSubst<"adc${s}${p} $rd, $rn, $imm",
2082 (t2SBCri rGPR:$rd, rGPR:$rn, t2_so_imm_not:$imm, pred:$p, s_cc_out:$s)>;
2083 def : t2InstSubst<"sbc${s}${p} $rd, $rn, $imm",
2084 (t2ADCri rGPR:$rd, rGPR:$rn, t2_so_imm_not:$imm, pred:$p, s_cc_out:$s)>;
2085
2086 def : t2InstSubst<"add${s}${p}.w $rd, $rn, $imm",
2087 (t2SUBri GPRnopc:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
2088 def : t2InstSubst<"addw${p} $rd, $rn, $imm",
2089 (t2SUBri12 GPRnopc:$rd, GPR:$rn, t2_so_imm_neg:$imm, pred:$p)>;
2090 def : t2InstSubst<"sub${s}${p}.w $rd, $rn, $imm",
2091 (t2ADDri GPRnopc:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
2092 def : t2InstSubst<"subw${p} $rd, $rn, $imm",
2093 (t2ADDri12 GPRnopc:$rd, GPR:$rn, t2_so_imm_neg:$imm, pred:$p)>;
20812094 // RSB
20822095 defm t2RSB : T2I_rbin_irs <0b1110, "rsb", sub>;
20832096
43744387 pred:$p, cc_out:$s)>;
43754388
43764389 // add w/ negative immediates is just a sub.
4377 def : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm",
4390 def : t2InstSubst<"add${s}${p} $Rd, $Rn, $imm",
43784391 (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p,
43794392 cc_out:$s)>;
4380 def : t2InstAlias<"add${p} $Rd, $Rn, $imm",
4393 def : t2InstSubst<"add${p} $Rd, $Rn, $imm",
43814394 (t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
4382 def : t2InstAlias<"add${s}${p} $Rdn, $imm",
4395 def : t2InstSubst<"add${s}${p} $Rdn, $imm",
43834396 (t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm_neg:$imm, pred:$p,
43844397 cc_out:$s)>;
4385 def : t2InstAlias<"add${p} $Rdn, $imm",
4398 def : t2InstSubst<"add${p} $Rdn, $imm",
43864399 (t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
43874400
4388 def : t2InstAlias<"add${s}${p}.w $Rd, $Rn, $imm",
4401 def : t2InstSubst<"add${s}${p}.w $Rd, $Rn, $imm",
43894402 (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p,
43904403 cc_out:$s)>;
4391 def : t2InstAlias<"addw${p} $Rd, $Rn, $imm",
4404 def : t2InstSubst<"addw${p} $Rd, $Rn, $imm",
43924405 (t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
4393 def : t2InstAlias<"add${s}${p}.w $Rdn, $imm",
4406 def : t2InstSubst<"add${s}${p}.w $Rdn, $imm",
43944407 (t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm_neg:$imm, pred:$p,
43954408 cc_out:$s)>;
4396 def : t2InstAlias<"addw${p} $Rdn, $imm",
4409 def : t2InstSubst<"addw${p} $Rdn, $imm",
43974410 (t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
43984411
43994412
46244637
46254638 // "mov Rd, t2_so_imm_not" can be handled via "mvn" in assembly, just like
46264639 // for isel.
4627 def : t2InstAlias<"mov${p} $Rd, $imm",
4640 def : t2InstSubst<"mov${p} $Rd, $imm",
46284641 (t2MVNi rGPR:$Rd, t2_so_imm_not:$imm, pred:$p, zero_reg)>;
4629 def : t2InstAlias<"mvn${p} $Rd, $imm",
4630 (t2MOVi rGPR:$Rd, t2_so_imm_not:$imm, pred:$p, zero_reg)>;
4642 def : t2InstSubst<"mvn${s}${p} $Rd, $imm",
4643 (t2MOVi rGPR:$Rd, t2_so_imm_not:$imm, pred:$p, s_cc_out:$s)>;
46314644 // Same for AND <--> BIC
4632 def : t2InstAlias<"bic${s}${p} $Rd, $Rn, $imm",
4645 def : t2InstSubst<"bic${s}${p} $Rd, $Rn, $imm",
46334646 (t2ANDri rGPR:$Rd, rGPR:$Rn, t2_so_imm_not:$imm,
46344647 pred:$p, cc_out:$s)>;
4635 def : t2InstAlias<"bic${s}${p} $Rdn, $imm",
4648 def : t2InstSubst<"bic${s}${p} $Rdn, $imm",
46364649 (t2ANDri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm_not:$imm,
46374650 pred:$p, cc_out:$s)>;
4638 def : t2InstAlias<"and${s}${p} $Rd, $Rn, $imm",
4651 def : t2InstSubst<"and${s}${p} $Rd, $Rn, $imm",
46394652 (t2BICri rGPR:$Rd, rGPR:$Rn, t2_so_imm_not:$imm,
46404653 pred:$p, cc_out:$s)>;
4641 def : t2InstAlias<"and${s}${p} $Rdn, $imm",
4654 def : t2InstSubst<"and${s}${p} $Rdn, $imm",
46424655 (t2BICri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm_not:$imm,
46434656 pred:$p, cc_out:$s)>;
46444657 // Likewise, "add Rd, t2_so_imm_neg" -> sub
4645 def : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm",
4658 def : t2InstSubst<"add${s}${p} $Rd, $Rn, $imm",
46464659 (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm,
46474660 pred:$p, cc_out:$s)>;
4648 def : t2InstAlias<"add${s}${p} $Rd, $imm",
4661 def : t2InstSubst<"add${s}${p} $Rd, $imm",
46494662 (t2SUBri GPRnopc:$Rd, GPRnopc:$Rd, t2_so_imm_neg:$imm,
46504663 pred:$p, cc_out:$s)>;
46514664 // Same for CMP <--> CMN via t2_so_imm_neg
4652 def : t2InstAlias<"cmp${p} $Rd, $imm",
4665 def : t2InstSubst<"cmp${p} $Rd, $imm",
46534666 (t2CMNri rGPR:$Rd, t2_so_imm_neg:$imm, pred:$p)>;
4654 def : t2InstAlias<"cmn${p} $Rd, $imm",
4667 def : t2InstSubst<"cmn${p} $Rd, $imm",
46554668 (t2CMPri rGPR:$Rd, t2_so_imm_neg:$imm, pred:$p)>;
46564669
46574670
349349
350350 /// UseSjLjEH - If true, the target uses SjLj exception handling (e.g. iOS).
351351 bool UseSjLjEH = false;
352
353 /// Implicitly convert an instruction to a different one if its immediates
354 /// cannot be encoded. For example, ADD r0, r1, #FFFFFFFF -> SUB r0, r1, #1.
355 bool NegativeImmediates = true;
352356
353357 /// stackAlignment - The minimum alignment known to hold of the stack frame on
354358 /// entry to the function and which must be maintained by every function.
12441244 return ARM_AM::getSOImmVal(Value) == -1 &&
12451245 ARM_AM::getSOImmVal(-Value) != -1;
12461246 }
1247 bool isThumbModImmNeg1_7() const {
1248 if (!isImm()) return false;
1249 const MCConstantExpr *CE = dyn_cast(getImm());
1250 if (!CE) return false;
1251 int32_t Value = -(int32_t)CE->getValue();
1252 return 0 < Value && Value < 8;
1253 }
1254 bool isThumbModImmNeg8_255() const {
1255 if (!isImm()) return false;
1256 const MCConstantExpr *CE = dyn_cast(getImm());
1257 if (!CE) return false;
1258 int32_t Value = -(int32_t)CE->getValue();
1259 return 7 < Value && Value < 256;
1260 }
12471261 bool isConstantPoolImm() const { return Kind == k_ConstantPoolImmediate; }
12481262 bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
12491263 bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
20342048 Inst.addOperand(MCOperand::createImm(Enc));
20352049 }
20362050
2051 void addThumbModImmNeg8_255Operands(MCInst &Inst, unsigned N) const {
2052 assert(N == 1 && "Invalid number of operands!");
2053 const MCConstantExpr *CE = dyn_cast(getImm());
2054 uint32_t Val = -CE->getValue();
2055 Inst.addOperand(MCOperand::createImm(Val));
2056 }
2057
2058 void addThumbModImmNeg1_7Operands(MCInst &Inst, unsigned N) const {
2059 assert(N == 1 && "Invalid number of operands!");
2060 const MCConstantExpr *CE = dyn_cast(getImm());
2061 uint32_t Val = -CE->getValue();
2062 Inst.addOperand(MCOperand::createImm(Val));
2063 }
2064
20372065 void addBitfieldOperands(MCInst &Inst, unsigned N) const {
20382066 assert(N == 1 && "Invalid number of operands!");
20392067 // Munge the lsb/width into a bitfield mask.
21402168 // The operand is actually a t2_so_imm, but we have its bitwise
21412169 // negation in the assembly source, so twiddle it here.
21422170 const MCConstantExpr *CE = dyn_cast(getImm());
2143 Inst.addOperand(MCOperand::createImm(~CE->getValue()));
2171 Inst.addOperand(MCOperand::createImm(~(uint32_t)CE->getValue()));
21442172 }
21452173
21462174 void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
21482176 // The operand is actually a t2_so_imm, but we have its
21492177 // negation in the assembly source, so twiddle it here.
21502178 const MCConstantExpr *CE = dyn_cast(getImm());
2151 Inst.addOperand(MCOperand::createImm(-CE->getValue()));
2179 Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
21522180 }
21532181
21542182 void addImm0_4095NegOperands(MCInst &Inst, unsigned N) const {
0 # RUN: not llvm-mc -triple armv7 %s 2>&1| FileCheck %s
1
2 .arm
3
4 ADC r0, r1, #0xFFFFFEEE
5 # CHECK: error: invalid operand for instruction
6 ADC r0, r1, #0xABFEABFF
7 # CHECK: error: invalid operand for instruction
8 ADC r0, r1, #0xFFFFFE02
9 # CHECK: error: invalid operand for instruction
10
11 ADD.W r0, r0, #0xFF01FF01
12 # CHECK: error: invalid operand for instruction
0 # RUN: not llvm-mc -triple thumbv7 -mcpu=cortex-m0 %s 2>&1 | FileCheck %s
1
2 .thumb
3
4 ADDs r1, r0, #0xFFFFFFF5
5 # CHECK: error: instruction requires: arm-mode
6
7 ADDs r0, #0xFFFFFEFF
8 # CHECK: error: invalid operand for instruction
9
10 SUBs r1, r0, #0xFFFFFFF5
11 # CHECK: error: instruction requires: arm-mode
12
13 SUBs r0, #0xFFFFFEFF
14 # CHECK: error: invalid operand for instruction
0 # RUN: llvm-mc -triple thumbv7 -mcpu=cortex-m0 %s -show-encoding | FileCheck %s
1 # RUN: not llvm-mc -triple thumbv7 -mcpu=cortex-m0 %s -show-encoding -mattr=+no-neg-immediates 2>&1 | FileCheck %s -check-prefix=CHECK-DISABLED
2
3 .thumb
4
5 ADDs r1, r0, #0xFFFFFFF9
6 # CHECK: subs r1, r0, #7
7 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
8 ADDs r0, #0xFFFFFF01
9 # CHECK: subs r0, #255
10 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
11
12 SUBs r0, #0xFFFFFF01
13 # CHECK: adds r0, #255
14 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
15
16 SUBs r1, r0, #0xFFFFFFF9
17 # CHECK: adds r1, r0, #7
18 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
0 # RUN: llvm-mc -triple armv7 %s -show-encoding | FileCheck %s
1 # RUN: not llvm-mc -triple armv7 %s -show-encoding -mattr=+no-neg-immediates 2>&1 | FileCheck %s -check-prefix=CHECK-DISABLED
2
3 .arm
4
5 ADC r0, r1, #0xFFFFFF00
6 # CHECK: sbc r0, r1, #255
7 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
8 # CHECK-DISABLED: ADC
9 ADC r0, r1, #0xFFFFFE03
10 # CHECK: sbc r0, r1, #508
11 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
12 # CHECK-DISABLED: ADC
13 ADD r0, r1, #0xFFFFFF01
14 # CHECK: sub r0, r1, #255
15 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
16 # CHECK-DISABLED: ADD
17 AND r0, r1, #0xFFFFFF00
18 # CHECK: bic r0, r1, #255
19 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
20 # CHECK-DISABLED: AND
21 BIC r0, r1, #0xFFFFFF00
22 # CHECK: and r0, r1, #255
23 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
24 # CHECK-DISABLED: BIC
25 CMP r0, #0xFFFFFF01
26 # CHECK: cmn r0, #255
27 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
28 # CHECK-DISABLED: CMP
29 CMN r0, #0xFFFFFF01
30 # CHECK: cmp r0, #255
31 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
32 # CHECK-DISABLED: CMN
33 MOV r0, #0xFFFFFF00
34 # CHECK: mvn r0, #255
35 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
36 # CHECK-DISABLED: MOV
37 MVN r0, #0xFFFFFF00
38 # CHECK: mov r0, #255
39 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
40 # CHECK-DISABLED: MVN
41 SBC r0, r1, #0xFFFFFF00
42 # CHECK: adc r0, r1, #255
43 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
44 # CHECK-DISABLED: SBC
45 SUB r0, r1, #0xFFFFFF01
46 # CHECK: add r0, r1, #255
47 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
48 # CHECK-DISABLED: SUB
49
50 .thumb
51
52 ADC r0, r1, #0xFFFFFF00
53 # CHECK: sbc r0, r1, #255
54 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
55 # CHECK-DISABLED: ADC
56 ADC r0, r1, #0xFFFF00FF
57 # CHECK: sbc r0, r1, #65280
58 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
59 # CHECK-DISABLED: ADC
60 ADC r0, r1, #0xFFFEFFFE
61 # CHECK: sbc r0, r1, #65537 @ encoding: [0x61,0xf1,0x01,0x10]
62 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
63 # CHECK-DISABLED: ADC
64 ADC r0, r1, #0xFEFFFEFF
65 # CHECK: sbc r0, r1, #16777472 @ encoding: [0x61,0xf1,0x01,0x20]
66 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
67 # CHECK-DISABLED: ADC
68 ADD.W r0, r0, #0xFFFFFF01
69 # CHECK: sub.w r0, r0, #255
70 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
71 # CHECK-DISABLED: ADD.W
72 ADD.W r0, r0, #0xFF01FF02
73 # CHECK: sub.w r0, r0, #16646398 @ encoding: [0xa0,0xf1,0xfe,0x10]
74 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
75 # CHECK-DISABLED: ADD.W
76 ADDW r0, r1, #0xFFFFFF01
77 # CHECK: subw r0, r1, #255 @ encoding: [0xa1,0xf2,0xff,0x00]
78 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
79 # CHECK-DISABLED: ADDW
80 ADD.W r0, r1, #0xFFFFFF01
81 # CHECK: sub.w r0, r1, #255 @ encoding: [0xa1,0xf1,0xff,0x00]
82 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
83 # CHECK-DISABLED: ADD.W
84 AND r0, r1, #0xFFFFFF00
85 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
86 # CHECK-DISABLED: AND
87 # CHECK: bic r0, r1, #255
88 AND r0, r1, #0xFEFFFEFF
89 # CHECK: bic r0, r1, #16777472 @ encoding: [0x21,0xf0,0x01,0x20]
90 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
91 # CHECK-DISABLED: AND
92 BIC r0, r1, #0xFFFFFF00
93 # CHECK: and r0, r1, #255
94 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
95 # CHECK-DISABLED: BIC
96 BIC r0, r1, #0xFEFFFEFF
97 # CHECK: and r0, r1, #16777472 @ encoding: [0x01,0xf0,0x01,0x20]
98 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
99 # CHECK-DISABLED: BIC
100 CMP r0, #0xFFFFFF01
101 # CHECK: cmn.w r0, #255
102 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
103 # CHECK-DISABLED: CMP
104 CMN r0, #0xFFFFFF01
105 # CHECK: cmp.w r0, #255
106 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
107 # CHECK-DISABLED: CMN
108 MOV r0, #0xFFFFFF00
109 # CHECK: mvn r0, #255
110 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
111 # CHECK-DISABLED: MOV
112 MVN r0, #0xFFFFFF00
113 # CHECK: mov.w r0, #255
114 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
115 # CHECK-DISABLED: MVN
116 SBC r0, r1, #0xFFFFFF00
117 # CHECK: adc r0, r1, #255
118 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
119 # CHECK-DISABLED: SBC
120 SUBW r0, r1, #0xFFFFFF01
121 # CHECK: addw r0, r1, #255
122 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
123 # CHECK-DISABLED: SUBW
124 SUB.W r0, r1, #0xFFFFFF01
125 # CHECK: add.w r0, r1, #255
126 # CHECK-DISABLED: error: instruction requires: NegativeImmediates
127 # CHECK-DISABLED: SUB.W