case ARM::ADDri:
case ARM::t2ADDri:
case ARM::t2ADDri12:
- case ARM::t2ADDspImm:
- case ARM::t2ADDspImm12:
Offset = -MI->getOperand(2).getImm();
break;
case ARM::SUBri:
case ARM::t2SUBri:
case ARM::t2SUBri12:
- case ARM::t2SUBspImm:
- case ARM::t2SUBspImm12:
Offset = MI->getOperand(2).getImm();
break;
case ARM::tSUBspi:
}
break;
case ARM::t2ADDrr:
- case ARM::t2SUBrr: {
+ case ARM::t2SUBrr:
if (UseOpc == ARM::t2SUBrr && Commute)
return false;
// ADD/SUB are special because they're essentially the same operation, so
// we can handle a larger range of immediates.
- const bool ToSP = DefMI.getOperand(0).getReg() == ARM::SP;
- const unsigned t2ADD = ToSP ? ARM::t2ADDspImm : ARM::t2ADDri;
- const unsigned t2SUB = ToSP ? ARM::t2SUBspImm : ARM::t2SUBri;
if (ARM_AM::isT2SOImmTwoPartVal(ImmVal))
- NewUseOpc = UseOpc == ARM::t2ADDrr ? t2ADD : t2SUB;
+ NewUseOpc = UseOpc == ARM::t2ADDrr ? ARM::t2ADDri : ARM::t2SUBri;
else if (ARM_AM::isT2SOImmTwoPartVal(-ImmVal)) {
ImmVal = -ImmVal;
- NewUseOpc = UseOpc == ARM::t2ADDrr ? t2SUB : t2ADD;
+ NewUseOpc = UseOpc == ARM::t2ADDrr ? ARM::t2SUBri : ARM::t2ADDri;
} else
return false;
SOImmValV1 = (uint32_t)ARM_AM::getT2SOImmTwoPartFirst(ImmVal);
SOImmValV2 = (uint32_t)ARM_AM::getT2SOImmTwoPartSecond(ImmVal);
break;
- }
case ARM::t2ORRrr:
case ARM::t2EORrr:
if (!ARM_AM::isT2SOImmTwoPartVal(ImmVal))
// The register-immediate version is re-materializable. This is useful
// in particular for taking the address of a local.
let isReMaterializable = 1 in {
- def spImm : T2sTwoRegImm<
- (outs GPRsp:$Rd), (ins GPRsp:$Rn, t2_so_imm:$imm), IIC_iALUi,
- opc, ".w\t$Rd, $Rn, $imm",
- []>,
- Sched<[WriteALU, ReadALU]> {
- let Rn = 13;
- let Rd = 13;
-
- let Inst{31-27} = 0b11110;
- let Inst{25-24} = 0b01;
- let Inst{23-21} = op23_21;
- let Inst{15} = 0;
-
- let DecoderMethod = "DecodeT2AddSubSPImm";
- }
-
def ri : T2sTwoRegImm<
- (outs rGPR:$Rd), (ins GPRnopc:$Rn, t2_so_imm:$imm), IIC_iALUi,
+ (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, t2_so_imm:$imm), IIC_iALUi,
opc, ".w\t$Rd, $Rn, $imm",
- [(set rGPR:$Rd, (opnode GPRnopc:$Rn, t2_so_imm:$imm))]>,
+ [(set GPRnopc:$Rd, (opnode GPRnopc:$Rn, t2_so_imm:$imm))]>,
Sched<[WriteALU, ReadALU]> {
let Inst{31-27} = 0b11110;
let Inst{25} = 0;
}
// 12-bit imm
def ri12 : T2I<
- (outs rGPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi,
+ (outs GPRnopc:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi,
!strconcat(opc, "w"), "\t$Rd, $Rn, $imm",
- [(set rGPR:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]>,
+ [(set GPRnopc:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]>,
Sched<[WriteALU, ReadALU]> {
bits<4> Rd;
bits<4> Rn;
let Inst{11-8} = Rd;
let Inst{7-0} = imm{7-0};
}
- def spImm12 : T2I<
- (outs GPRsp:$Rd), (ins GPRsp:$Rn, imm0_4095:$imm), IIC_iALUi,
- !strconcat(opc, "w"), "\t$Rd, $Rn, $imm",
- []>,
- Sched<[WriteALU, ReadALU]> {
- bits<4> Rd = 13;
- bits<4> Rn = 13;
- bits<12> imm;
- let Inst{31-27} = 0b11110;
- let Inst{26} = imm{11};
- let Inst{25-24} = 0b10;
- let Inst{23-21} = op23_21;
- let Inst{20} = 0; // The S bit.
- let Inst{19-16} = Rn;
- let Inst{15} = 0;
- let Inst{14-12} = imm{10-8};
- let Inst{11-8} = Rd;
- let Inst{7-0} = imm{7-0};
- let DecoderMethod = "DecodeT2AddSubSPImm";
- }
// register
def rr : T2sThreeReg<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, rGPR:$Rm),
IIC_iALUr, opc, ".w\t$Rd, $Rn, $Rm",
(t2ADCri rGPR:$rd, rGPR:$rn, t2_so_imm_not:$imm, pred:$p, s_cc_out:$s)>;
def : t2InstSubst<"add${s}${p}.w $rd, $rn, $imm",
- (t2SUBri rGPR:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
+ (t2SUBri GPRnopc:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
+def : t2InstSubst<"addw${p} $rd, $rn, $imm",
+ (t2SUBri12 GPRnopc:$rd, GPR:$rn, t2_so_imm_neg:$imm, pred:$p)>;
def : t2InstSubst<"sub${s}${p}.w $rd, $rn, $imm",
- (t2ADDri rGPR:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
+ (t2ADDri GPRnopc:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
+def : t2InstSubst<"subw${p} $rd, $rn, $imm",
+ (t2ADDri12 GPRnopc:$rd, GPR:$rn, t2_so_imm_neg:$imm, pred:$p)>;
def : t2InstSubst<"subw${p} $Rd, $Rn, $imm",
- (t2ADDri12 rGPR:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
+ (t2ADDri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
def : t2InstSubst<"sub${s}${p} $rd, $rn, $imm",
- (t2ADDri rGPR:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
+ (t2ADDri GPRnopc:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
def : t2InstSubst<"sub${p} $rd, $rn, $imm",
- (t2ADDri12 rGPR:$rd, GPR:$rn, imm0_4095_neg:$imm, pred:$p)>;
-
-// SP to SP alike
-def : t2InstSubst<"add${s}${p}.w $rd, $rn, $imm",
- (t2SUBspImm GPRsp:$rd, GPRsp:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
-def : t2InstSubst<"sub${s}${p}.w $rd, $rn, $imm",
- (t2ADDspImm GPRsp:$rd, GPRsp:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
-def : t2InstSubst<"subw${p} $Rd, $Rn, $imm",
- (t2ADDspImm12 GPRsp:$Rd, GPRsp:$Rn, imm0_4095_neg:$imm, pred:$p)>;
-def : t2InstSubst<"sub${s}${p} $rd, $rn, $imm",
- (t2ADDspImm GPRsp:$rd, GPRsp:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
-def : t2InstSubst<"sub${p} $rd, $rn, $imm",
- (t2ADDspImm12 GPRsp:$rd, GPRsp:$rn, imm0_4095_neg:$imm, pred:$p)>;
-
-
+ (t2ADDri12 GPRnopc:$rd, GPR:$rn, t2_so_imm_neg:$imm, pred:$p)>;
// RSB
defm t2RSB : T2I_rbin_irs <0b1110, "rsb", sub>;
// The AddedComplexity preferences the first variant over the others since
// it can be shrunk to a 16-bit wide encoding, while the others cannot.
let AddedComplexity = 1 in
-def : T2Pat<(add rGPR:$src, imm1_255_neg:$imm),
- (t2SUBri rGPR:$src, imm1_255_neg:$imm)>;
-def : T2Pat<(add rGPR:$src, t2_so_imm_neg:$imm),
- (t2SUBri rGPR:$src, t2_so_imm_neg:$imm)>;
-def : T2Pat<(add rGPR:$src, imm0_4095_neg:$imm),
- (t2SUBri12 rGPR:$src, imm0_4095_neg:$imm)>;
+def : T2Pat<(add GPR:$src, imm1_255_neg:$imm),
+ (t2SUBri GPR:$src, imm1_255_neg:$imm)>;
+def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
+ (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
+def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
+ (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
def : T2Pat<(add GPR:$src, imm0_65535_neg:$imm),
(t2SUBrr GPR:$src, (t2MOVi16 (imm_neg_XFORM imm:$imm)))>;
// Thumb2SizeReduction's chances later on we select a t2ADD for an or where
// possible.
def : T2Pat<(or AddLikeOrOp:$Rn, t2_so_imm:$imm),
- (t2ADDri rGPR:$Rn, t2_so_imm:$imm)>;
+ (t2ADDri $Rn, t2_so_imm:$imm)>;
def : T2Pat<(or AddLikeOrOp:$Rn, imm0_4095:$Rm),
- (t2ADDri12 rGPR:$Rn, imm0_4095:$Rm)>;
+ (t2ADDri12 $Rn, imm0_4095:$Rm)>;
def : T2Pat<(or AddLikeOrOp:$Rn, non_imm32:$Rm),
(t2ADDrr $Rn, $Rm)>;
// Aliases for ADD without the ".w" optional width specifier.
def : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm",
- (t2ADDri rGPR:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p,
+ (t2ADDri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p,
cc_out:$s)>;
def : t2InstAlias<"add${p} $Rd, $Rn, $imm",
- (t2ADDri12 rGPR:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>;
+ (t2ADDri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>;
def : t2InstAlias<"add${s}${p} $Rd, $Rn, $Rm",
(t2ADDrr GPRnopc:$Rd, GPRnopc:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>;
def : t2InstAlias<"add${s}${p} $Rd, $Rn, $ShiftedRm",
pred:$p, cc_out:$s)>;
// ... and with the destination and source register combined.
def : t2InstAlias<"add${s}${p} $Rdn, $imm",
- (t2ADDri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
+ (t2ADDri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
def : t2InstAlias<"add${p} $Rdn, $imm",
- (t2ADDri12 rGPR:$Rdn, rGPR:$Rdn, imm0_4095:$imm, pred:$p)>;
-def : t2InstAlias<"addw${p} $Rdn, $imm",
- (t2ADDri12 rGPR:$Rdn, rGPR:$Rdn, imm0_4095:$imm, pred:$p)>;
+ (t2ADDri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095:$imm, pred:$p)>;
def : t2InstAlias<"add${s}${p} $Rdn, $Rm",
(t2ADDrr GPRnopc:$Rdn, GPRnopc:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>;
def : t2InstAlias<"add${s}${p} $Rdn, $ShiftedRm",
// add w/ negative immediates is just a sub.
def : t2InstSubst<"add${s}${p} $Rd, $Rn, $imm",
- (t2SUBri rGPR:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p,
+ (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p,
cc_out:$s)>;
def : t2InstSubst<"add${p} $Rd, $Rn, $imm",
- (t2SUBri12 rGPR:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
+ (t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
def : t2InstSubst<"add${s}${p} $Rdn, $imm",
- (t2SUBri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm_neg:$imm, pred:$p,
+ (t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm_neg:$imm, pred:$p,
cc_out:$s)>;
def : t2InstSubst<"add${p} $Rdn, $imm",
- (t2SUBri12 rGPR:$Rdn, rGPR:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
+ (t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
def : t2InstSubst<"add${s}${p}.w $Rd, $Rn, $imm",
- (t2SUBri rGPR:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p,
+ (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p,
cc_out:$s)>;
def : t2InstSubst<"addw${p} $Rd, $Rn, $imm",
- (t2SUBri12 rGPR:$Rd, rGPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
+ (t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
def : t2InstSubst<"add${s}${p}.w $Rdn, $imm",
- (t2SUBri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm_neg:$imm, pred:$p,
+ (t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm_neg:$imm, pred:$p,
cc_out:$s)>;
def : t2InstSubst<"addw${p} $Rdn, $imm",
- (t2SUBri12 rGPR:$Rdn, rGPR:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
+ (t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
// Aliases for SUB without the ".w" optional width specifier.
def : t2InstAlias<"sub${s}${p} $Rd, $Rn, $imm",
- (t2SUBri rGPR:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
+ (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
def : t2InstAlias<"sub${p} $Rd, $Rn, $imm",
- (t2SUBri12 rGPR:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>;
+ (t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>;
def : t2InstAlias<"sub${s}${p} $Rd, $Rn, $Rm",
(t2SUBrr GPRnopc:$Rd, GPRnopc:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>;
def : t2InstAlias<"sub${s}${p} $Rd, $Rn, $ShiftedRm",
pred:$p, cc_out:$s)>;
// ... and with the destination and source register combined.
def : t2InstAlias<"sub${s}${p} $Rdn, $imm",
- (t2SUBri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
+ (t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
def : t2InstAlias<"sub${p} $Rdn, $imm",
- (t2SUBri12 rGPR:$Rdn, rGPR:$Rdn, imm0_4095:$imm, pred:$p)>;
-def : t2InstAlias<"subw${p} $Rdn, $imm",
- (t2SUBri12 rGPR:$Rdn, rGPR:$Rdn, imm0_4095:$imm, pred:$p)>;
+ (t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095:$imm, pred:$p)>;
def : t2InstAlias<"sub${s}${p}.w $Rdn, $Rm",
(t2SUBrr GPRnopc:$Rdn, GPRnopc:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>;
def : t2InstAlias<"sub${s}${p} $Rdn, $Rm",
(t2SUBrs GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_reg:$ShiftedRm,
pred:$p, cc_out:$s)>;
-// SP to SP alike aliases
-// Aliases for ADD without the ".w" optional width specifier.
-def : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm",
- (t2ADDspImm GPRsp:$Rd, GPRsp:$Rn, t2_so_imm:$imm, pred:$p,
- cc_out:$s)>;
-def : t2InstAlias<"add${p} $Rd, $Rn, $imm",
- (t2ADDspImm12 GPRsp:$Rd, GPRsp:$Rn, imm0_4095:$imm, pred:$p)>;
-// ... and with the destination and source register combined.
-def : t2InstAlias<"add${s}${p} $Rdn, $imm",
- (t2ADDspImm GPRsp:$Rdn, GPRsp:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
-
-def : t2InstAlias<"add${s}${p}.w $Rdn, $imm",
- (t2ADDspImm GPRsp:$Rdn, GPRsp:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
-
-def : t2InstAlias<"add${p} $Rdn, $imm",
- (t2ADDspImm12 GPRsp:$Rdn, GPRsp:$Rdn, imm0_4095:$imm, pred:$p)>;
-
-def : t2InstAlias<"addw${p} $Rdn, $imm",
- (t2ADDspImm12 GPRsp:$Rdn, GPRsp:$Rdn, imm0_4095:$imm, pred:$p)>;
-
-// add w/ negative immediates is just a sub.
-def : t2InstSubst<"add${s}${p} $Rd, $Rn, $imm",
- (t2SUBspImm GPRsp:$Rd, GPRsp:$Rn, t2_so_imm_neg:$imm, pred:$p,
- cc_out:$s)>;
-def : t2InstSubst<"add${p} $Rd, $Rn, $imm",
- (t2SUBspImm12 GPRsp:$Rd, GPRsp:$Rn, imm0_4095_neg:$imm, pred:$p)>;
-def : t2InstSubst<"add${s}${p} $Rdn, $imm",
- (t2SUBspImm GPRsp:$Rdn, GPRsp:$Rdn, t2_so_imm_neg:$imm, pred:$p,
- cc_out:$s)>;
-def : t2InstSubst<"add${p} $Rdn, $imm",
- (t2SUBspImm12 GPRsp:$Rdn, GPRsp:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
-
-def : t2InstSubst<"add${s}${p}.w $Rd, $Rn, $imm",
- (t2SUBspImm GPRsp:$Rd, GPRsp:$Rn, t2_so_imm_neg:$imm, pred:$p,
- cc_out:$s)>;
-def : t2InstSubst<"addw${p} $Rd, $Rn, $imm",
- (t2SUBspImm12 GPRsp:$Rd, GPRsp:$Rn, imm0_4095_neg:$imm, pred:$p)>;
-def : t2InstSubst<"add${s}${p}.w $Rdn, $imm",
- (t2SUBspImm GPRsp:$Rdn, GPRsp:$Rdn, t2_so_imm_neg:$imm, pred:$p,
- cc_out:$s)>;
-def : t2InstSubst<"addw${p} $Rdn, $imm",
- (t2SUBspImm12 GPRsp:$Rdn, GPRsp:$Rdn, imm0_4095_neg:$imm, pred:$p)>;
-
-
-// Aliases for SUB without the ".w" optional width specifier.
-def : t2InstAlias<"sub${s}${p} $Rd, $Rn, $imm",
- (t2SUBspImm GPRsp:$Rd, GPRsp:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
-def : t2InstAlias<"sub${p} $Rd, $Rn, $imm",
- (t2SUBspImm12 GPRsp:$Rd, GPRsp:$Rn, imm0_4095:$imm, pred:$p)>;
-// ... and with the destination and source register combined.
-def : t2InstAlias<"sub${s}${p} $Rdn, $imm",
- (t2SUBspImm GPRsp:$Rdn, GPRsp:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
-def : t2InstAlias<"sub${s}${p}.w $Rdn, $imm",
- (t2SUBspImm GPRsp:$Rdn, GPRsp:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>;
-def : t2InstAlias<"sub${p} $Rdn, $imm",
- (t2SUBspImm12 GPRsp:$Rdn, GPRsp:$Rdn, imm0_4095:$imm, pred:$p)>;
-def : t2InstAlias<"subw${p} $Rdn, $imm",
- (t2SUBspImm12 GPRsp:$Rdn, GPRsp:$Rdn, imm0_4095:$imm, pred:$p)>;
-
// Alias for compares without the ".w" optional width specifier.
def : t2InstAlias<"cmn${p} $Rn, $Rm",
(t2CMNzrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>;
pred:$p, cc_out:$s)>;
// Likewise, "add Rd, t2_so_imm_neg" -> sub
def : t2InstSubst<"add${s}${p} $Rd, $Rn, $imm",
- (t2SUBri rGPR:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm,
- pred:$p, cc_out:$s)>;
-def : t2InstSubst<"add${s}${p} $Rd, $Rn, $imm",
- (t2SUBspImm GPRsp:$Rd, GPRsp:$Rn, t2_so_imm_neg:$imm,
- pred:$p, cc_out:$s)>;
-def : t2InstSubst<"add${s}${p} $Rd, $imm",
- (t2SUBri rGPR:$Rd, rGPR:$Rd, t2_so_imm_neg:$imm,
+ (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm,
pred:$p, cc_out:$s)>;
def : t2InstSubst<"add${s}${p} $Rd, $imm",
- (t2SUBspImm GPRsp:$Rd, GPRsp:$Rd, t2_so_imm_neg:$imm,
+ (t2SUBri GPRnopc:$Rd, GPRnopc:$Rd, t2_so_imm_neg:$imm,
pred:$p, cc_out:$s)>;
// Same for CMP <--> CMN via t2_so_imm_neg
def : t2InstSubst<"cmp${p} $Rd, $imm",
return nullptr;
}
- int BaseOpc = isThumb2 ? (BaseKill && Base == ARM::SP ? ARM::t2ADDspImm
- : ARM::t2ADDri)
- : (isThumb1 && Base == ARM::SP)
- ? ARM::tADDrSPi
- : (isThumb1 && Offset < 8)
- ? ARM::tADDi3
- : isThumb1 ? ARM::tADDi8 : ARM::ADDri;
+ int BaseOpc =
+ isThumb2 ? ARM::t2ADDri :
+ (isThumb1 && Base == ARM::SP) ? ARM::tADDrSPi :
+ (isThumb1 && Offset < 8) ? ARM::tADDi3 :
+ isThumb1 ? ARM::tADDi8 : ARM::ADDri;
if (Offset < 0) {
- // FIXME: There are no Thumb1 load/store instructions with negative
- // offsets. So the Base != ARM::SP might be unnecessary.
- Offset = -Offset;
- BaseOpc = isThumb2 ? (BaseKill && Base == ARM::SP ? ARM::t2SUBspImm
- : ARM::t2SUBri)
- : (isThumb1 && Offset < 8 && Base != ARM::SP)
- ? ARM::tSUBi3
- : isThumb1 ? ARM::tSUBi8 : ARM::SUBri;
+ Offset = - Offset;
+ BaseOpc =
+ isThumb2 ? ARM::t2SUBri :
+ (isThumb1 && Offset < 8 && Base != ARM::SP) ? ARM::tSUBi3 :
+ isThumb1 ? ARM::tSUBi8 : ARM::SUBri;
}
if (!TL->isLegalAddImmediate(Offset))
case ARM::tADDi8: Scale = 4; CheckCPSRDef = true; break;
case ARM::tSUBi8: Scale = -4; CheckCPSRDef = true; break;
case ARM::t2SUBri:
- case ARM::t2SUBspImm:
case ARM::SUBri: Scale = -1; CheckCPSRDef = true; break;
case ARM::t2ADDri:
- case ARM::t2ADDspImm:
case ARM::ADDri: Scale = 1; CheckCPSRDef = true; break;
case ARM::tADDspi: Scale = 4; CheckCPSRDef = false; break;
case ARM::tSUBspi: Scale = -4; CheckCPSRDef = false; break;
// Check against T3. If the second register is the PC, this is an
// alternate form of ADR, which uses encoding T4, so check for that too.
if (static_cast<ARMOperand &>(*Operands[4]).getReg() != ARM::PC &&
- (static_cast<ARMOperand &>(*Operands[5]).isT2SOImm() ||
- static_cast<ARMOperand &>(*Operands[5]).isT2SOImmNeg()))
+ static_cast<ARMOperand &>(*Operands[5]).isT2SOImm())
return false;
// Otherwise, we use encoding T4, which does not have a cc_out
static_cast<ARMOperand &>(*Operands[1]).getReg() == 0 &&
(static_cast<ARMOperand &>(*Operands[4]).isImm() ||
(Operands.size() == 6 &&
- static_cast<ARMOperand &>(*Operands[5]).isImm()))) {
- // Thumb2 (add|sub){s}{p}.w GPRnopc, sp, #{T2SOImm} has cc_out
- return (!(isThumbTwo() &&
- (static_cast<ARMOperand &>(*Operands[4]).isT2SOImm() ||
- static_cast<ARMOperand &>(*Operands[4]).isT2SOImmNeg())));
- }
- // Fixme: Should join all the thumb+thumb2 (add|sub) in a single if case
- // Thumb2 ADD r0, #4095 -> ADDW r0, r0, #4095 (T4)
- // Thumb2 SUB r0, #4095 -> SUBW r0, r0, #4095
- if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") &&
- (Operands.size() == 5) &&
- static_cast<ARMOperand &>(*Operands[3]).isReg() &&
- static_cast<ARMOperand &>(*Operands[3]).getReg() != ARM::SP &&
- static_cast<ARMOperand &>(*Operands[3]).getReg() != ARM::PC &&
- static_cast<ARMOperand &>(*Operands[1]).getReg() == 0 &&
- static_cast<ARMOperand &>(*Operands[4]).isImm()) {
- const ARMOperand &IMM = static_cast<ARMOperand &>(*Operands[4]);
- if (IMM.isT2SOImm() || IMM.isT2SOImmNeg())
- return false; // add.w / sub.w
- if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(IMM.getImm())) {
- const int64_t Value = CE->getValue();
- // Thumb1 imm8 sub / add
- if ((Value < ((1 << 7) - 1) << 2) && inITBlock() && (!(Value & 3)) &&
- isARMLowRegister(static_cast<ARMOperand &>(*Operands[3]).getReg()))
- return false;
- return true; // Thumb2 T4 addw / subw
- }
- }
+ static_cast<ARMOperand &>(*Operands[5]).isImm())))
+ return true;
+
return false;
}
}
break;
+ case ARM::t2ADDri:
+ case ARM::t2ADDri12:
case ARM::t2ADDrr:
case ARM::t2ADDrs:
+ case ARM::t2SUBri:
+ case ARM::t2SUBri12:
case ARM::t2SUBrr:
case ARM::t2SUBrs:
if (Inst.getOperand(0).getReg() == ARM::SP &&
}
break;
case ARM::t2ADDri12:
- case ARM::t2SUBri12:
- case ARM::t2ADDspImm12:
- case ARM::t2SUBspImm12: {
- // If the immediate fits for encoding T3 and the generic
- // mnemonic was used, encoding T3 is preferred.
- const StringRef Token = static_cast<ARMOperand &>(*Operands[0]).getToken();
- if ((Token != "add" && Token != "sub") ||
+ // If the immediate fits for encoding T3 (t2ADDri) and the generic "add"
+ // mnemonic was used (not "addw"), encoding T3 is preferred.
+ if (static_cast<ARMOperand &>(*Operands[0]).getToken() != "add" ||
ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
break;
- switch (Inst.getOpcode()) {
- case ARM::t2ADDri12:
- Inst.setOpcode(ARM::t2ADDri);
- break;
- case ARM::t2SUBri12:
- Inst.setOpcode(ARM::t2SUBri);
- break;
- case ARM::t2ADDspImm12:
- Inst.setOpcode(ARM::t2ADDspImm);
- break;
- case ARM::t2SUBspImm12:
- Inst.setOpcode(ARM::t2SUBspImm);
+ Inst.setOpcode(ARM::t2ADDri);
+ Inst.addOperand(MCOperand::createReg(0)); // cc_out
+ break;
+ case ARM::t2SUBri12:
+ // If the immediate fits for encoding T3 (t2SUBri) and the generic "sub"
+ // mnemonic was used (not "subw"), encoding T3 is preferred.
+ if (static_cast<ARMOperand &>(*Operands[0]).getToken() != "sub" ||
+ ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
break;
- }
-
+ Inst.setOpcode(ARM::t2SUBri);
Inst.addOperand(MCOperand::createReg(0)); // cc_out
- return true;
- }
+ break;
case ARM::tADDi8:
// If the immediate is in the range 0-7, we want tADDi3 iff Rd was
// explicitly specified. From the ARM ARM: "Encoding T1 is preferred
Inst = TmpInst;
return true;
}
- case ARM::t2ADDspImm:
- case ARM::t2SUBspImm: {
- // Prefer T1 encoding if possible
- if (Inst.getOperand(5).getReg() != 0 || HasWideQualifier)
- break;
- unsigned V = Inst.getOperand(2).getImm();
- if (V & 3 || V > ((1 << 7) - 1) << 2)
- break;
- MCInst TmpInst;
- TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDspImm ? ARM::tADDspi
- : ARM::tSUBspi);
- TmpInst.addOperand(MCOperand::createReg(ARM::SP)); // destination reg
- TmpInst.addOperand(MCOperand::createReg(ARM::SP)); // source reg
- TmpInst.addOperand(MCOperand::createImm(V / 4)); // immediate
- TmpInst.addOperand(Inst.getOperand(3)); // pred
- Inst = TmpInst;
- return true;
- }
case ARM::t2ADDrr: {
// If the destination and first source operand are the same, and
// there's no setting of the flags, use encoding T2 instead of T3.
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address, const void *Decoder);
-static DecodeStatus DecodeGPRspRegisterClass(MCInst &Inst, unsigned RegNo,
- uint64_t Address,
- const void *Decoder);
static DecodeStatus DecodeHPRRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
static DecodeStatus DecodeMVEOverlappingLongShift(MCInst &Inst, unsigned Insn,
uint64_t Address,
const void *Decoder);
-static DecodeStatus DecodeT2AddSubSPImm(MCInst &Inst, unsigned Insn,
- uint64_t Address, const void *Decoder);
-
#include "ARMGenDisassemblerTables.inc"
static MCDisassembler *createARMDisassembler(const Target &T,
return S;
}
-static DecodeStatus DecodeGPRspRegisterClass(MCInst &Inst, unsigned RegNo,
- uint64_t Address,
- const void *Decoder) {
- if (RegNo != 13)
- return MCDisassembler::Fail;
-
- unsigned Register = GPRDecoderTable[RegNo];
- Inst.addOperand(MCOperand::createReg(Register));
- return MCDisassembler::Success;
-}
-
static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address, const void *Decoder) {
unsigned Register = 0;
unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
if (sign1 != sign2) return MCDisassembler::Fail;
- const unsigned Rd = fieldFromInstruction(Insn, 8, 4);
- assert(Inst.getNumOperands() == 0 && "We should receive an empty Inst");
- DecodeStatus S = DecoderGPRRegisterClass(Inst, Rd, Address, Decoder);
unsigned Val = fieldFromInstruction(Insn, 0, 8);
Val |= fieldFromInstruction(Insn, 12, 3) << 8;
Val |= fieldFromInstruction(Insn, 26, 1) << 11;
- // If sign, then it is decreasing the address.
- if (sign1) {
- // Following ARMv7 Architecture Manual, when the offset
- // is zero, it is decoded as a subw, not as a adr.w
- if (!Val) {
- Inst.setOpcode(ARM::t2SUBri12);
- Inst.addOperand(MCOperand::createReg(ARM::PC));
- } else
- Val = -Val;
- }
- Inst.addOperand(MCOperand::createImm(Val));
- return S;
+ Val |= sign1 << 12;
+ Inst.addOperand(MCOperand::createImm(SignExtend32<13>(Val)));
+
+ return MCDisassembler::Success;
}
static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val,
Inst.addOperand(MCOperand::createReg(ARM::VPR));
return S;
}
-
-static DecodeStatus DecodeT2AddSubSPImm(MCInst &Inst, unsigned Insn,
- uint64_t Address, const void *Decoder) {
- const unsigned Rd = fieldFromInstruction(Insn, 8, 4);
- const unsigned Rn = fieldFromInstruction(Insn, 16, 4);
- const unsigned Imm12 = fieldFromInstruction(Insn, 26, 1) << 11 |
- fieldFromInstruction(Insn, 12, 3) << 8 |
- fieldFromInstruction(Insn, 0, 8);
- const unsigned TypeT3 = fieldFromInstruction(Insn, 25, 1);
- unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
- unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
- unsigned S = fieldFromInstruction(Insn, 20, 1);
- if (sign1 != sign2)
- return MCDisassembler::Fail;
-
- // T3 does a zext of imm12, where T2 does a ThumbExpandImm (T2SOImm)
- DecodeStatus DS = MCDisassembler::Success;
- if ((!Check(DS,
- DecodeGPRspRegisterClass(Inst, Rd, Address, Decoder))) || // dst
- (!Check(DS, DecodeGPRspRegisterClass(Inst, Rn, Address, Decoder))))
- return MCDisassembler::Fail;
- if (TypeT3) {
- Inst.setOpcode(sign1 ? ARM::t2SUBspImm12 : ARM::t2ADDspImm12);
- S = 0;
- Inst.addOperand(MCOperand::createImm(Imm12)); // zext imm12
- } else {
- Inst.setOpcode(sign1 ? ARM::t2SUBspImm : ARM::t2ADDspImm);
- if (!Check(DS, DecodeT2SOImm(Inst, Imm12, Address, Decoder))) // imm12
- return MCDisassembler::Fail;
- }
- if (!Check(DS, DecodeCCOutOperand(Inst, S, Address, Decoder))) // cc_out
- return MCDisassembler::Fail;
-
- Inst.addOperand(MCOperand::createReg(0)); // pred
-
- return DS;
-}
}
bool HasCCOut = true;
int ImmIsT2SO = ARM_AM::getT2SOImmVal(ThisVal);
- bool ToSP = DestReg == ARM::SP;
- unsigned t2SUB = ToSP ? ARM::t2SUBspImm : ARM::t2SUBri;
- unsigned t2ADD = ToSP ? ARM::t2ADDspImm : ARM::t2ADDri;
- unsigned t2SUBi12 = ToSP ? ARM::t2SUBspImm12 : ARM::t2SUBri12;
- unsigned t2ADDi12 = ToSP ? ARM::t2ADDspImm12 : ARM::t2ADDri12;
- Opc = isSub ? t2SUB : t2ADD;
+
+ Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
// Prefer T2: sub rd, rn, so_imm | sub sp, sp, so_imm
if (ImmIsT2SO != -1) {
NumBytes = 0;
} else if (ThisVal < 4096) {
// Prefer T3 if can make it in a single go: subw rd, rn, imm12 | subw sp,
// sp, imm12
- Opc = isSub ? t2SUBi12 : t2ADDi12;
+ Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
HasCCOut = false;
NumBytes = 0;
} else {
if (Opcode == ARM::INLINEASM || Opcode == ARM::INLINEASM_BR)
AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2?
- const bool IsSP = Opcode == ARM::t2ADDspImm12 || Opcode == ARM::t2ADDspImm;
- if (IsSP || Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
+ if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
Offset += MI.getOperand(FrameRegIdx+1).getImm();
unsigned PredReg;
return true;
}
- bool HasCCOut = (Opcode != ARM::t2ADDspImm12 && Opcode != ARM::t2ADDri12);
+ bool HasCCOut = Opcode != ARM::t2ADDri12;
if (Offset < 0) {
Offset = -Offset;
isSub = true;
- MI.setDesc(IsSP ? TII.get(ARM::t2SUBspImm) : TII.get(ARM::t2SUBri));
+ MI.setDesc(TII.get(ARM::t2SUBri));
} else {
- MI.setDesc(IsSP ? TII.get(ARM::t2ADDspImm) : TII.get(ARM::t2ADDri));
+ MI.setDesc(TII.get(ARM::t2ADDri));
}
// Common case: small offset, fits into instruction.
// Another common case: imm12.
if (Offset < 4096 &&
(!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) {
- unsigned NewOpc = isSub ? IsSP ? ARM::t2SUBspImm12 : ARM::t2SUBri12
- : IsSP ? ARM::t2ADDspImm12 : ARM::t2ADDri12;
+ unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
MI.setDesc(TII.get(NewOpc));
MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
%1(s32) = G_CONSTANT i32 786444 ; 0x000c000c
%2(s32) = G_ADD %0, %1
- ; CHECK: [[VREGRES:%[0-9]+]]:rgpr = t2ADDri [[VREGX]], 786444, 14, $noreg, $noreg
+ ; CHECK: [[VREGRES:%[0-9]+]]:gprnopc = t2ADDri [[VREGX]], 786444, 14, $noreg, $noreg
$r0 = COPY %2(s32)
; CHECK: $r0 = COPY [[VREGRES]]
%1(s32) = G_CONSTANT i32 4093
%2(s32) = G_ADD %0, %1
- ; CHECK: [[VREGRES:%[0-9]+]]:rgpr = t2ADDri12 [[VREGX]], 4093, 14, $noreg
+ ; CHECK: [[VREGRES:%[0-9]+]]:gprnopc = t2ADDri12 [[VREGX]], 4093, 14, $noreg
$r0 = COPY %2(s32)
; CHECK: $r0 = COPY [[VREGRES]]
%1(s32) = G_CONSTANT i32 786444 ; 0x000c000c
%2(s32) = G_SUB %0, %1
- ; CHECK: [[VREGRES:%[0-9]+]]:rgpr = t2SUBri [[VREGX]], 786444, 14, $noreg, $noreg
+ ; CHECK: [[VREGRES:%[0-9]+]]:gprnopc = t2SUBri [[VREGX]], 786444, 14, $noreg, $noreg
$r0 = COPY %2(s32)
; CHECK: $r0 = COPY [[VREGRES]]
liveins: $r0, $r1, $r2, $r3
%0(p0) = G_FRAME_INDEX %fixed-stack.2
- ; CHECK: [[FI32VREG:%[0-9]+]]:rgpr = t2ADDri %fixed-stack.[[FI32]], 0, 14, $noreg, $noreg
+ ; CHECK: [[FI32VREG:%[0-9]+]]:gprnopc = t2ADDri %fixed-stack.[[FI32]], 0, 14, $noreg, $noreg
%1(s32) = G_LOAD %0(p0) :: (load 4)
; CHECK: [[LD32VREG:%[0-9]+]]:gpr = t2LDRi12 [[FI32VREG]], 0, 14, $noreg
; CHECK: $r0 = COPY [[LD32VREG]]
%2(p0) = G_FRAME_INDEX %fixed-stack.0
- ; CHECK: [[FI1VREG:%[0-9]+]]:rgpr = t2ADDri %fixed-stack.[[FI1]], 0, 14, $noreg, $noreg
+ ; CHECK: [[FI1VREG:%[0-9]+]]:gprnopc = t2ADDri %fixed-stack.[[FI1]], 0, 14, $noreg, $noreg
%3(s1) = G_LOAD %2(p0) :: (load 1)
; CHECK: [[LD1VREG:%[0-9]+]]:gprnopc = t2LDRBi12 [[FI1VREG]], 0, 14, $noreg
--- |
; RUN: llc --run-pass=prologepilog -o - %s | FileCheck %s
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_register $r7
- ; CHECK-NEXT: $sp = frame-setup t2SUBspImm12 killed $sp, 4008, 14, $noreg
+ ; CHECK-NEXT: $sp = frame-setup t2SUBri12 killed $sp, 4008, 14, $noreg
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "thumbv7-none-none-eabi"
+++ /dev/null
-; pr23772 - [ARM] r226200 can emit illegal thumb2 instruction: "sub sp, r12, #80"
-; RUN: llc -march=thumb -mcpu=cortex-m3 -O3 -filetype=asm -o - %s | FileCheck %s
-; CHECK-NOT: sub{{.*}} sp, r{{.*}}, #
-; CHECK: .fnend
-; TODO: Missed optimization. The three instructions generated to subtract SP can be converged to a single one
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32"
-target triple = "thumbv7m-unknown-unknown"
-%B = type {%B*}
-%R = type {i32}
-%U = type {%U*, i8, i8}
-%E = type {%B*, %U*}
-%X = type {i32, i8, i8}
-declare external [0 x i8]* @memalloc(i32, i32, i32)
-declare external void @memfree([0 x i8]*, i32, i32)
-define void @foo(%B* %pb$, %R* %pr$) nounwind {
-L.0:
- %pb = alloca %B*
- %pr = alloca %R*
- store %B* %pb$, %B** %pb
- store %R* %pr$, %R** %pr
- %pe = alloca %E*
- %0 = load %B*, %B** %pb
- %1 = bitcast %B* %0 to %E*
- store %E* %1, %E** %pe
- %2 = load %R*, %R** %pr
- %3 = getelementptr %R, %R* %2, i32 0, i32 0
- %4 = load i32, i32* %3
- switch i32 %4, label %L.1 [
- i32 1, label %L.3
- ]
-L.3:
- %px = alloca %X*
- %5 = load %R*, %R** %pr
- %6 = bitcast %R* %5 to %X*
- store %X* %6, %X** %px
- %7 = load %X*, %X** %px
- %8 = getelementptr %X, %X* %7, i32 0, i32 0
- %9 = load i32, i32* %8
- %10 = icmp ne i32 %9, 0
- br i1 %10, label %L.5, label %L.4
-L.5:
- %pu = alloca %U*
- %11 = call [0 x i8]* @memalloc(i32 8, i32 4, i32 0)
- %12 = bitcast [0 x i8]* %11 to %U*
- store %U* %12, %U** %pu
- %13 = load %X*, %X** %px
- %14 = getelementptr %X, %X* %13, i32 0, i32 1
- %15 = load i8, i8* %14
- %16 = load %U*, %U** %pu
- %17 = getelementptr %U, %U* %16, i32 0, i32 1
- store i8 %15, i8* %17
- %18 = load %E*, %E** %pe
- %19 = getelementptr %E, %E* %18, i32 0, i32 1
- %20 = load %U*, %U** %19
- %21 = load %U*, %U** %pu
- %22 = getelementptr %U, %U* %21, i32 0, i32 0
- store %U* %20, %U** %22
- %23 = load %U*, %U** %pu
- %24 = load %E*, %E** %pe
- %25 = getelementptr %E, %E* %24, i32 0, i32 1
- store %U* %23, %U** %25
- br label %L.4
-L.4:
- %26 = load %X*, %X** %px
- %27 = bitcast %X* %26 to [0 x i8]*
- call void @memfree([0 x i8]* %27, i32 8, i32 0)
- br label %L.2
-L.1:
- br label %L.2
-L.2:
- br label %return
-return:
- ret void
-}
; CHECK: frame-setup CFI_INSTRUCTION offset $r6, -28
; CHECK: frame-setup CFI_INSTRUCTION offset $r5, -32
; CHECK: frame-setup CFI_INSTRUCTION offset $r4, -36
- ; CHECK: $sp = frame-setup t2SUBspImm killed $sp, 1208, 14, $noreg, $noreg
+ ; CHECK: $sp = frame-setup t2SUBri killed $sp, 1208, 14, $noreg, $noreg
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 1244
; CHECK: $r0 = IMPLICIT_DEF
; CHECK: $r1 = IMPLICIT_DEF
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r6, -28
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r5, -32
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r4, -36
- ; CHECK-NEXT: $sp = frame-setup t2SUBspImm12 killed $sp, 1220, 14, $noreg
+ ; CHECK-NEXT: $sp = frame-setup t2SUBri12 killed $sp, 1220, 14, $noreg
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 1256
; CHECK-NEXT: $r0 = IMPLICIT_DEF
; CHECK-NEXT: $r1 = IMPLICIT_DEF
%0:rgpr = COPY $r0
%2:rgpr = t2MOVi 1, 14, $noreg, $noreg
%3:gprnopc = t2ADDrr %0, %1, 14, $noreg, $noreg
- %4:rgpr = t2SUBri %3, 0, 14, $noreg, def dead $cpsr
+ %4:gprnopc = t2SUBri %3, 0, 14, $noreg, def dead $cpsr
t2CMPri killed %3, 0, 14, $noreg, implicit-def $cpsr
%5:rgpr = t2MOVCCi %2, 0, 7, $cpsr
$r0 = COPY %5
# CHECK-LABEL: name: test
# CHECK: %3:gprnopc = t2ADDrr %0, %1, 14, $noreg, $noreg
-# CHECK-NEXT: %4:rgpr = t2SUBri %3, 0, 14, $noreg, def $cpsr
+# CHECK-NEXT: %4:gprnopc = t2SUBri %3, 0, 14, $noreg, def $cpsr
# CHECK-NEXT: %5:rgpr = t2MOVCCi %2, 0, 7, $cpsr
...
liveins: $r0
%0:rgpr = COPY $r0
- %1:rgpr = t2ADDri %stack.0.f, 0, 14, $noreg, $noreg
+ %1:gprnopc = t2ADDri %stack.0.f, 0, 14, $noreg, $noreg
t2CMPrr %1, %0, 14, $noreg, implicit-def $cpsr
t2Bcc %bb.2, 3, $cpsr
t2B %bb.1, 14, $noreg
tBX_RET 14, $noreg
# CHECK-LABEL: name: test_addir_frameindex
-# CHECK: %1:rgpr = t2ADDri %stack.0.f, 0, 14, $noreg, $noreg
+# CHECK: %1:gprnopc = t2ADDri %stack.0.f, 0, 14, $noreg, $noreg
# CHECK-NEXT: t2CMPrr %1, %0, 14, $noreg, implicit-def $cpsr
# CHECK-NEXT: t2Bcc %bb.2, 3, $cpsr
...
adds r2, r2, #56
adds r2, #56
add r1, r7, #0xcbcbcbcb
+ add sp, sp, #0x1fe0000
adds.w r2, #-16
adds.w r2, r2, #-16
@ CHECK: adds r2, #56 @ encoding: [0x38,0x32]
@ CHECK: adds r2, #56 @ encoding: [0x38,0x32]
@ CHECK: add.w r1, r7, #3419130827 @ encoding: [0x07,0xf1,0xcb,0x31]
+@ CHECK: add.w sp, sp, #33423360 @ encoding: [0x0d,0xf1,0xff,0x7d]
@ CHECK: subs.w r2, r2, #16 @ encoding: [0xb2,0xf1,0x10,0x02]
@ CHECK: subs.w r2, r2, #16 @ encoding: [0xb2,0xf1,0x10,0x02]
@ CHECK: addw r6, sp, #1020 @ encoding: [0x0d,0xf2,0xfc,0x36]
add r6, sp, #1019 // T4
@ CHECK: addw r6, sp, #1019 @ encoding: [0x0d,0xf2,0xfb,0x36]
- addw r0, r0, #4095
- addw r0, #4095
- add r0, r0, #4095
- add r0, #4095
-@ CHECK-NEXT: addw r0, r0, #4095 @ encoding: [0x00,0xf6,0xff,0x70]
-@ CHECK-NEXT: addw r0, r0, #4095 @ encoding: [0x00,0xf6,0xff,0x70]
-@ CHECK-NEXT: addw r0, r0, #4095 @ encoding: [0x00,0xf6,0xff,0x70]
-@ CHECK-NEXT: addw r0, r0, #4095 @ encoding: [0x00,0xf6,0xff,0x70]
-add.w r0, r0, #-4096
-add r0, r0, #-4096
-add.w r0, #-4096
-add r0, #-4096
-@ CHECK-NEXT: sub.w r0, r0, #4096 @ encoding: [0xa0,0xf5,0x80,0x50]
-@ CHECK-NEXT: sub.w r0, r0, #4096 @ encoding: [0xa0,0xf5,0x80,0x50]
-@ CHECK-NEXT: sub.w r0, r0, #4096 @ encoding: [0xa0,0xf5,0x80,0x50]
-@ CHECK-NEXT: sub.w r0, r0, #4096 @ encoding: [0xa0,0xf5,0x80,0x50]
-adds.w r0, r0, #-4096
-adds r0, r0, #-4096
-adds.w r0, #-4096
-adds r0, #-4096
-@ CHECK-NEXT: subs.w r0, r0, #4096 @ encoding: [0xb0,0xf5,0x80,0x50]
-@ CHECK-NEXT: subs.w r0, r0, #4096 @ encoding: [0xb0,0xf5,0x80,0x50]
-@ CHECK-NEXT: subs.w r0, r0, #4096 @ encoding: [0xb0,0xf5,0x80,0x50]
-@ CHECK-NEXT: subs.w r0, r0, #4096 @ encoding: [0xb0,0xf5,0x80,0x50]
-@------------------------------------------------------------------------------
-@ ADD (SP plus immediate, writing to SP)
-@------------------------------------------------------------------------------
- add.w sp, sp, #0x1fe0000 //T3
- add.w sp, #0x1fe0000
- add sp, sp, #0x1fe0000
- add sp, #0x1fe0000
-@ CHECK-NEXT: add.w sp, sp, #33423360 @ encoding: [0x0d,0xf1,0xff,0x7d]
-@ CHECK-NEXT: add.w sp, sp, #33423360 @ encoding: [0x0d,0xf1,0xff,0x7d]
-@ CHECK-NEXT: add.w sp, sp, #33423360 @ encoding: [0x0d,0xf1,0xff,0x7d]
-@ CHECK-NEXT: add.w sp, sp, #33423360 @ encoding: [0x0d,0xf1,0xff,0x7d]
- adds.w sp, sp, #0x1fe0000 //T3
- adds.w sp, #0x1fe0000
- adds sp, sp, #0x1fe0000
- adds sp, #0x1fe0000
-@ CHECK-NEXT: adds.w sp, sp, #33423360 @ encoding: [0x1d,0xf1,0xff,0x7d]
-@ CHECK-NEXT: adds.w sp, sp, #33423360 @ encoding: [0x1d,0xf1,0xff,0x7d]
-@ CHECK-NEXT: adds.w sp, sp, #33423360 @ encoding: [0x1d,0xf1,0xff,0x7d]
-@ CHECK-NEXT: adds.w sp, sp, #33423360 @ encoding: [0x1d,0xf1,0xff,0x7d]
- addw sp, sp, #4095 //T4
- add sp, sp, #4095
- addw sp, #4095
- add sp, #4095
-@ CHECK-NEXT: addw sp, sp, #4095 @ encoding: [0x0d,0xf6,0xff,0x7d]
-@ CHECK-NEXT: addw sp, sp, #4095 @ encoding: [0x0d,0xf6,0xff,0x7d]
-@ CHECK-NEXT: addw sp, sp, #4095 @ encoding: [0x0d,0xf6,0xff,0x7d]
-@ CHECK-NEXT: addw sp, sp, #4095 @ encoding: [0x0d,0xf6,0xff,0x7d]
- add sp, sp, #128 //T2
- add sp, #128
-@ CHECK-NEXT: add sp, #128 @ encoding: [0x20,0xb0]
-@ CHECK-NEXT: add sp, #128 @ encoding: [0x20,0xb0]
- adds sp, sp, #128 //T3
- adds sp, #128
-@ CHECK-NEXT: adds.w sp, sp, #128 @ encoding: [0x1d,0xf1,0x80,0x0d]
-@ CHECK-NEXT: adds.w sp, sp, #128 @ encoding: [0x1d,0xf1,0x80,0x0d]
- add r0, sp, #128 //T1
-@ CHECK-NEXT: add r0, sp, #128 @ encoding: [0x20,0xa8]
- adds r0, sp, #128 //T3
-@ CHECK-NEXT: adds.w r0, sp, #128 @ encoding: [0x1d,0xf1,0x80,0x00]
- addw r0, sp, #128
-@ CHECK-NEXT: addw r0, sp, #128 @ encoding: [0x0d,0xf2,0x80,0x00]
-@------------------------------------------------------------------------------
-@ ADD (SP plus negative immediate, writing to SP)
-@------------------------------------------------------------------------------
-add sp, sp, #-508
-add sp, #-508
-@ CHECK-NEXT: sub sp, #508 @ encoding: [0xff,0xb0]
-@ CHECK-NEXT: sub sp, #508 @ encoding: [0xff,0xb0]
-addw sp, sp, #-4095
-add sp, sp, #-4095
-addw sp, #-4095
-add sp, #-4095
-@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d]
-@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d]
-@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d]
-@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d]
-add.w sp, sp, #-4096
-add sp, sp, #-4096
-add.w sp, #-4096
-add sp, #-4096
-@ CHECK-NEXT: sub.w sp, sp, #4096 @ encoding: [0xad,0xf5,0x80,0x5d]
-@ CHECK-NEXT: sub.w sp, sp, #4096 @ encoding: [0xad,0xf5,0x80,0x5d]
-@ CHECK-NEXT: sub.w sp, sp, #4096 @ encoding: [0xad,0xf5,0x80,0x5d]
-@ CHECK-NEXT: sub.w sp, sp, #4096 @ encoding: [0xad,0xf5,0x80,0x5d]
-adds.w sp, sp, #-4096
-adds sp, sp, #-4096
-adds.w sp, #-4096
-adds sp, #-4096
-@ CHECK-NEXT: subs.w sp, sp, #4096 @ encoding: [0xbd,0xf5,0x80,0x5d]
-@ CHECK-NEXT: subs.w sp, sp, #4096 @ encoding: [0xbd,0xf5,0x80,0x5d]
-@ CHECK-NEXT: subs.w sp, sp, #4096 @ encoding: [0xbd,0xf5,0x80,0x5d]
-@ CHECK-NEXT: subs.w sp, sp, #4096 @ encoding: [0xbd,0xf5,0x80,0x5d]
+
@------------------------------------------------------------------------------
@ ADD (SP plus register) A8.8.10
@------------------------------------------------------------------------------
@ CHECK: it eq @ encoding: [0x08,0xbf]
addeq r2, sp, ip // T3
@ CHECK: addeq.w r2, sp, r12 @ encoding: [0x0d,0xeb,0x0c,0x02]
- add.w r0, sp, r0, ror #2
- add r0, sp, r0, ror #2
- add sp, r1, lsl #15
- adds.w r0, sp, r0, ror #2
- adds r0, sp, r0, ror #2
- adds.w sp, sp, r0, ror #31
- adds sp, sp, r0, ror #31
- adds sp, r0, ror #31
-@ CHECK-NEXT: add.w r0, sp, r0, ror #2 @ encoding: [0x0d,0xeb,0xb0,0x00]
-@ CHECK-NEXT: add.w r0, sp, r0, ror #2 @ encoding: [0x0d,0xeb,0xb0,0x00]
-@ CHECK-NEXT: add.w sp, sp, r1, lsl #15 @ encoding: [0x0d,0xeb,0xc1,0x3d]
-@ CHECK-NEXT: adds.w r0, sp, r0, ror #2 @ encoding: [0x1d,0xeb,0xb0,0x00]
-@ CHECK-NEXT: adds.w r0, sp, r0, ror #2 @ encoding: [0x1d,0xeb,0xb0,0x00]
-@ CHECK-NEXT: adds.w sp, sp, r0, ror #31 @ encoding: [0x1d,0xeb,0xf0,0x7d]
-@ CHECK-NEXT: adds.w sp, sp, r0, ror #31 @ encoding: [0x1d,0xeb,0xf0,0x7d]
-@ CHECK-NEXT: adds.w sp, sp, r0, ror #31 @ encoding: [0x1d,0xeb,0xf0,0x7d]
+
+
@------------------------------------------------------------------------------
@ FIXME: ADR
@------------------------------------------------------------------------------
sub r0, r0, #32
subs r2, r2, #56
subs r2, #56
- subw r0, r0, #4095
- subw r0, #4095
- sub r0, r0, #4095
- sub r0, #4095
+
@ CHECK: itet eq @ encoding: [0x0a,0xbf]
@ CHECK: subeq r1, r2, #4 @ encoding: [0x11,0x1f]
@ CHECK: subwne r5, r3, #1023 @ encoding: [0xa3,0xf2,0xff,0x35]
@ CHECK: sub.w r0, r0, #32 @ encoding: [0xa0,0xf1,0x20,0x00]
@ CHECK: subs r2, #56 @ encoding: [0x38,0x3a]
@ CHECK: subs r2, #56 @ encoding: [0x38,0x3a]
-@ CHECK-NEXT: subw r0, r0, #4095 @ encoding: [0xa0,0xf6,0xff,0x70]
-@ CHECK-NEXT: subw r0, r0, #4095 @ encoding: [0xa0,0xf6,0xff,0x70]
-@ CHECK-NEXT: subw r0, r0, #4095 @ encoding: [0xa0,0xf6,0xff,0x70]
-@ CHECK-NEXT: subw r0, r0, #4095 @ encoding: [0xa0,0xf6,0xff,0x70]
-@------------------------------------------------------------------------------
-@ SUB (immediate, writting to SP)
-@------------------------------------------------------------------------------
- sub.w sp, sp, #0x1fe0000 //T2
- sub sp, sp, #0x1fe0000
- sub.w sp, #0x1fe0000
- sub sp, #0x1fe0000
-@ CHECK-NEXT: sub.w sp, sp, #33423360 @ encoding: [0xad,0xf1,0xff,0x7d]
-@ CHECK-NEXT: sub.w sp, sp, #33423360 @ encoding: [0xad,0xf1,0xff,0x7d]
-@ CHECK-NEXT: sub.w sp, sp, #33423360 @ encoding: [0xad,0xf1,0xff,0x7d]
-@ CHECK-NEXT: sub.w sp, sp, #33423360 @ encoding: [0xad,0xf1,0xff,0x7d]
- subs.w sp, sp, #0x1fe0000 //T2
- subs sp, sp, #0x1fe0000
- subs.w sp, #0x1fe0000
- subs sp, #0x1fe0000
-@ CHECK-NEXT: subs.w sp, sp, #33423360 @ encoding: [0xbd,0xf1,0xff,0x7d]
-@ CHECK-NEXT: subs.w sp, sp, #33423360 @ encoding: [0xbd,0xf1,0xff,0x7d]
-@ CHECK-NEXT: subs.w sp, sp, #33423360 @ encoding: [0xbd,0xf1,0xff,0x7d]
-@ CHECK-NEXT: subs.w sp, sp, #33423360 @ encoding: [0xbd,0xf1,0xff,0x7d]
- subw sp, sp, #4095 //T3
- sub sp, sp, #4095
- subw sp, #4095
- sub sp, #4095
-@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d]
-@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d]
-@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d]
-@ CHECK-NEXT: subw sp, sp, #4095 @ encoding: [0xad,0xf6,0xff,0x7d]
- sub sp, #128 //T1
-@ CHECK-NEXT: sub sp, #128 @ encoding: [0xa0,0xb0]
- subs.w sp, #128 //T2
- subs sp, #128 //T2
-@ CHECK-NEXT: subs.w sp, sp, #128 @ encoding: [0xbd,0xf1,0x80,0x0d]
-@ CHECK-NEXT: subs.w sp, sp, #128 @ encoding: [0xbd,0xf1,0x80,0x0d]
- sub.w sp, #128 //T2
-@ CHECK-NEXT: sub.w sp, sp, #128 @ encoding: [0xad,0xf1,0x80,0x0d]
- subw sp, #128 //T4
-@ CHECK-NEXT: subw sp, sp, #128 @ encoding: [0xad,0xf2,0x80,0x0d]
+
+
@------------------------------------------------------------------------------
@ SUB (register)
@------------------------------------------------------------------------------
-@ RUN: not llvm-mc -triple thumbv7-apple-ios %s -o /dev/null 2>&1 | FileCheck %s
+@ RUN: not llvm-mc -triple thumbv7-apple-ios %s -o - 2>&1 | FileCheck %s
+
+@ CHECK: error: source register must be sp if destination is sp
+@ CHECK: error: source register must be sp if destination is sp
+@ CHECK: error: source register must be sp if destination is sp
+@ CHECK: error: source register must be sp if destination is sp
add sp, r5, #1
addw sp, r7, #4
add sp, r3, r2
add sp, r3, r5, lsl #3
+
+
+@ CHECK: error: source register must be sp if destination is sp
+@ CHECK: error: source register must be sp if destination is sp
+@ CHECK: error: source register must be sp if destination is sp
+@ CHECK: error: source register must be sp if destination is sp
sub sp, r5, #1
subw sp, r7, #4
sub sp, r3, r2
sub sp, r3, r5, lsl #3
-@CHECK: error: invalid instruction, any one of the following would fix this:
-@CHECK-NEXT: add sp, r5, #1
-@CHECK-NEXT: ^
-@CHECK-NEXT: note: invalid operand for instruction
-@CHECK-NEXT: add sp, r5, #1
-@CHECK-NEXT: ^
-@CHECK-NEXT: note: operand must be a register in range [r0, r12] or r14
-@CHECK-NEXT: add sp, r5, #1
-@CHECK-NEXT: ^
-@CHECK-NEXT: note: operand must be a register in range [r0, r12] or r14
-@CHECK-NEXT: add sp, r5, #1
-@CHECK-NEXT: ^
-@CHECK-NEXT: note: operand must be a register sp
-@CHECK-NEXT: add sp, r5, #1
-@CHECK-NEXT: ^
-@CHECK-NEXT: error: invalid instruction, any one of the following would fix this:
-@CHECK-NEXT: addw sp, r7, #4
-@CHECK-NEXT: ^
-@CHECK-NEXT: note: operand must be a register in range [r0, r12] or r14
-@CHECK-NEXT: addw sp, r7, #4
-@CHECK-NEXT: ^
-@CHECK-NEXT: note: operand must be a register sp
-@CHECK-NEXT: addw sp, r7, #4
-@CHECK-NEXT: ^
-@CHECK-NEXT: error: source register must be sp if destination is sp
-@CHECK-NEXT: add sp, r3, r2
-@CHECK-NEXT: ^
-@CHECK-NEXT: error: source register must be sp if destination is sp
-@CHECK-NEXT: add sp, r3, r5, lsl #3
-@CHECK-NEXT: ^
-@CHECK-NEXT: error: invalid instruction, any one of the following would fix this:
-@CHECK-NEXT: sub sp, r5, #1
-@CHECK-NEXT: ^
-@CHECK-NEXT: note: invalid operand for instruction
-@CHECK-NEXT: sub sp, r5, #1
-@CHECK-NEXT: ^
-@CHECK-NEXT: note: operand must be a register in range [r0, r12] or r14
-@CHECK-NEXT: sub sp, r5, #1
-@CHECK-NEXT: ^
-@CHECK-NEXT: note: operand must be a register in range [r0, r12] or r14
-@CHECK-NEXT: sub sp, r5, #1
-@CHECK-NEXT: ^
-@CHECK-NEXT: note: operand must be a register sp
-@CHECK-NEXT: sub sp, r5, #1
-@CHECK-NEXT: ^
-@CHECK-NEXT: error: invalid instruction, any one of the following would fix this:
-@CHECK-NEXT: subw sp, r7, #4
-@CHECK-NEXT: ^
-@CHECK-NEXT: note: operand must be a register in range [r0, r12] or r14
-@CHECK-NEXT: subw sp, r7, #4
-@CHECK-NEXT: ^
-@CHECK-NEXT: note: operand must be a register sp
-@CHECK-NEXT: subw sp, r7, #4
-@CHECK-NEXT: ^
-@CHECK-NEXT: error: source register must be sp if destination is sp
-@CHECK-NEXT: sub sp, r3, r2
-@CHECK-NEXT: ^
-@CHECK-NEXT: error: source register must be sp if destination is sp
-@CHECK-NEXT: sub sp, r3, r5, lsl #3
.thumb
ADD r0, r1, #0xFFFFFF00
-# CHECK: sub.w r0, r1, #256
+# CHECK: subw r0, r1, #256
# CHECK-DISABLED: note: instruction requires: NegativeImmediates
# CHECK-DISABLED: ADD
ADDS r0, r1, #0xFFFFFF00
# CHECK-DISABLED: note: instruction requires: NegativeImmediates
# CHECK-DISABLED: SUB.W
SUB r0, r1, #0xFFFFFF00
-# CHECK: add.w r0, r1, #256
+# CHECK: addw r0, r1, #256
# CHECK-DISABLED: note: instruction requires: NegativeImmediates
# CHECK-DISABLED: SUB
SUBS r0, r1, #0xFFFFFF00
# CHECK-DISABLED: SUBS.W
ADD r0, r1, #-13
-# CHECK: sub.w r0, r1, #13
+# CHECK: subw r0, r1, #13
# CHECK-DISABLED: note: instruction requires: NegativeImmediates
# CHECK-DISABLED: ADD
// RUN: not llvm-mc -triple armv6m--none-eabi < %s 2>&1 | FileCheck %s
+
+// Some of these CHECK lines need to uses regexes to that the amount of
+// whitespace between the start of the line and the caret is significant.
+
add sp, r0, #4
-// CHECK: error: invalid instruction, any one of the following would fix this:
-// CHECK-NEXT: add sp, r0, #4
-// CHECK-NEXT: ^
-// CHECK-NEXT: note: operand must be a register sp
-// CHECK-NEXT: add sp, r0, #4
-// CHECK-NEXT: ^
-// CHECK-NEXT: note: too many operands for instruction
-// CHECK-NEXT: add sp, r0, #4
-// CHECK-NEXT: ^
+// CHECK: error: invalid instruction, any one of the following would fix this:
+// CHECK: note: instruction requires: thumb2
+// CHECK: note: operand must be a register sp
+// CHECK-NEXT: {{^ add sp, r0, #4}}
+// CHECK-NEXT: {{^ \^}}
+// CHECK: note: too many operands for instruction
add sp, sp, #512
add r2, sp, #1024
@ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
-@ CHECK-ERRORS: add sp, #-1
-@ CHECK-ERRORS: ^
+@ CHECK-ERRORS: add sp, #-1
+@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: operand must be a register in range [r0, r15]
-@ CHECK-ERRORS: add sp, #-1
-@ CHECK-ERRORS: ^
-@ CHECK-ERRORS: note: invalid operand for instruction
-@ CHECK-ERRORS: add sp, #-1
-@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: instruction requires: thumb2
-@ CHECK-ERRORS: add sp, #-1
-@ CHECK-ERRORS: ^
@ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
-@ CHECK-ERRORS: add sp, #3
-@ CHECK-ERRORS: ^
+@ CHECK-ERRORS: add sp, #3
+@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: operand must be a register in range [r0, r15]
-@ CHECK-ERRORS: add sp, #3
-@ CHECK-ERRORS: ^
-@ CHECK-ERRORS: note: invalid operand for instruction
-@ CHECK-ERRORS: add sp, #3
-@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: instruction requires: thumb2
-@ CHECK-ERRORS: add sp, #3
-@ CHECK-ERRORS: ^
@ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
-@ CHECK-ERRORS: add sp, sp, #512
-@ CHECK-ERRORS: ^
+@ CHECK-ERRORS: add sp, sp, #512
+@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: operand must be a register in range [r0, r15]
-@ CHECK-ERRORS: add sp, sp, #512
-@ CHECK-ERRORS: ^
-@ CHECK-ERRORS: note: invalid operand for instruction
-@ CHECK-ERRORS: add sp, sp, #512
-@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: instruction requires: thumb2
-@ CHECK-ERRORS: add sp, sp, #512
-@ CHECK-ERRORS: ^
@ CHECK-ERRORS: error: instruction requires: thumb2
-@ CHECK-ERRORS: add r2, sp, #1024
-@ CHECK-ERRORS: ^
+@ CHECK-ERRORS: add r2, sp, #1024
+@ CHECK-ERRORS: ^
+
add r2, sp, ip
@ CHECK-ERRORS: error: source register must be the same as destination
@ CHECK-ERRORS: add r2, sp, ip
# CHECK-V7-NEXT: [0xa3,0xeb,0x02,0x0d]
# CHECK-V7: warning: potentially undefined instruction encoding
# CHECK-V7-NEXT: [0xa3,0xeb,0xc5,0x0d]
-# CHECK-V7-NEXT: ^
-[0x0f,0xf2,0x00,0x4d]
-# CHECK-V7-NEXT: warning: potentially undefined instruction encoding
-# CHECK-V7-NEXT: [0x0f,0xf2,0x00,0x4d]
-# CHECK-V7-NEXT: ^
-# RUN: llvm-mc --disassemble --show-encoding %s -triple=thumbv7-apple-darwin9 -mcpu=cortex-a9 | FileCheck %s
+# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 -mcpu=cortex-a9 | FileCheck %s
# CHECK: add r5, sp, #68
0x11 0xad
# CHECK: sub sp, #60
0x8f 0xb0
-# CHECK: adr.w r0, #-1
+# CHECK: subw r0, pc, #1
0xaf 0xf2 0x01 0x00
-# CHECK: subw r0, pc, #0
-0xaf 0xf2 0x00 0x00
-
# CHECK: subw r0, sp, #835
0xad 0xf2 0x43 0x30
# CHECK: ldm r5!, {r0, r1, r2, r3, r4}
0x1f 0xcd
-# CHECK: adr.w r0, #1050
+# CHECK: addw r0, pc, #1050
0x0f 0xf2 0x1a 0x40
# CHECK: ldrd r3, r8, [r11, #-60]
0x90 0xec 0x00 0x0e
# CHECK: ldc p14
-[0x0f,0xf2,0x00,0x4d]
-# CHECK: adr.w sp, #1024
#------------------------------------------------------------------------------
# ADR
#------------------------------------------------------------------------------
-# CHECK: adr.w r11, #-3270
-# CHECK-NEXT: adr.w r11, #-826
-# CHECK-NEXT: subw r1, pc, #0
-# CHECK-NEXT: adr.w r0, #1024
+# CHECK: subw r11, pc, #3270
+# CHECK: subw r11, pc, #826
+# CHECK: subw r1, pc, #0
+
0xaf 0xf6 0xc6 0x4b
0xaf 0xf2 0x3a 0x3b
0xaf 0xf2 0x00 0x01
-0x0f,0xf2,0x00,0x40
+
#------------------------------------------------------------------------------
# AND (immediate)
#------------------------------------------------------------------------------