//
//===----------------------------------------------------------------------===//
-#include "ARMFPUName.h"
#include "ARMFeatures.h"
#include "MCTargetDesc/ARMAddressingModes.h"
-#include "MCTargetDesc/ARMArchName.h"
#include "MCTargetDesc/ARMBaseInfo.h"
#include "MCTargetDesc/ARMMCExpr.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCParser/MCAsmParserUtils.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/ARMEHABI.h"
+#include "llvm/Support/TargetParser.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
class ARMAsmParser : public MCTargetAsmParser {
MCSubtargetInfo &STI;
- MCAsmParser &Parser;
const MCInstrInfo &MII;
const MCRegisterInfo *MRI;
UnwindContext UC;
// according to count of instructions in block.
// ~0U if no active IT block.
} ITState;
- bool inITBlock() { return ITState.CurPosition != ~0U;}
+ bool inITBlock() { return ITState.CurPosition != ~0U; }
+ bool lastInITBlock() {
+ return ITState.CurPosition == 4 - countTrailingZeros(ITState.Mask);
+ }
void forwardITPosition() {
if (!inITBlock()) return;
// Move to the next instruction in the IT block, if there is one. If not,
ITState.CurPosition = ~0U; // Done with the IT block after this.
}
-
- MCAsmParser &getParser() const { return Parser; }
- MCAsmLexer &getLexer() const { return Parser.getLexer(); }
-
void Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges = None) {
- return Parser.Note(L, Msg, Ranges);
+ return getParser().Note(L, Msg, Ranges);
}
bool Warning(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = None) {
- return Parser.Warning(L, Msg, Ranges);
+ return getParser().Warning(L, Msg, Ranges);
}
bool Error(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = None) {
- return Parser.Error(L, Msg, Ranges);
+ return getParser().Error(L, Msg, Ranges);
}
+ bool validatetLDMRegList(const MCInst &Inst, const OperandVector &Operands,
+ unsigned ListNo, bool IsARPop = false);
+ bool validatetSTMRegList(const MCInst &Inst, const OperandVector &Operands,
+ unsigned ListNo);
+
int tryParseRegister();
bool tryParseRegisterWithWriteBack(OperandVector &);
int tryParseShiftRegister(OperandVector &);
bool &CanAcceptCarrySet,
bool &CanAcceptPredicationCode);
+ void tryConvertingToTwoOperandForm(StringRef Mnemonic, bool CarrySetting,
+ OperandVector &Operands);
bool isThumb() const {
// FIXME: Can tablegen auto-generate this?
- return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
+ return STI.getFeatureBits()[ARM::ModeThumb];
}
bool isThumbOne() const {
- return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
+ return isThumb() && !STI.getFeatureBits()[ARM::FeatureThumb2];
}
bool isThumbTwo() const {
- return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
+ return isThumb() && STI.getFeatureBits()[ARM::FeatureThumb2];
}
bool hasThumb() const {
- return STI.getFeatureBits() & ARM::HasV4TOps;
+ return STI.getFeatureBits()[ARM::HasV4TOps];
}
bool hasV6Ops() const {
- return STI.getFeatureBits() & ARM::HasV6Ops;
+ return STI.getFeatureBits()[ARM::HasV6Ops];
}
bool hasV6MOps() const {
- return STI.getFeatureBits() & ARM::HasV6MOps;
+ return STI.getFeatureBits()[ARM::HasV6MOps];
}
bool hasV7Ops() const {
- return STI.getFeatureBits() & ARM::HasV7Ops;
+ return STI.getFeatureBits()[ARM::HasV7Ops];
}
bool hasV8Ops() const {
- return STI.getFeatureBits() & ARM::HasV8Ops;
+ return STI.getFeatureBits()[ARM::HasV8Ops];
}
bool hasARM() const {
- return !(STI.getFeatureBits() & ARM::FeatureNoARM);
+ return !STI.getFeatureBits()[ARM::FeatureNoARM];
}
- bool hasThumb2DSP() const {
- return STI.getFeatureBits() & ARM::FeatureDSPThumb2;
+ bool hasDSP() const {
+ return STI.getFeatureBits()[ARM::FeatureDSP];
+ }
+ bool hasD16() const {
+ return STI.getFeatureBits()[ARM::FeatureD16];
+ }
+ bool hasV8_1aOps() const {
+ return STI.getFeatureBits()[ARM::HasV8_1aOps];
}
void SwitchMode() {
setAvailableFeatures(FB);
}
bool isMClass() const {
- return STI.getFeatureBits() & ARM::FeatureMClass;
+ return STI.getFeatureBits()[ARM::FeatureMClass];
}
/// @name Auto-generated Match Functions
OperandMatchResultTy parseSetEndImm(OperandVector &);
OperandMatchResultTy parseShifterImm(OperandVector &);
OperandMatchResultTy parseRotImm(OperandVector &);
+ OperandMatchResultTy parseModImm(OperandVector &);
OperandMatchResultTy parseBitfield(OperandVector &);
OperandMatchResultTy parsePostIdxReg(OperandVector &);
OperandMatchResultTy parseAM3Offset(OperandVector &);
void cvtThumbBranches(MCInst &Inst, const OperandVector &);
bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
- bool processInstruction(MCInst &Inst, const OperandVector &Ops);
+ bool processInstruction(MCInst &Inst, const OperandVector &Ops, MCStreamer &Out);
bool shouldOmitCCOutOperand(StringRef Mnemonic, OperandVector &Operands);
bool shouldOmitPredicateOperand(StringRef Mnemonic, OperandVector &Operands);
};
- ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser,
- const MCInstrInfo &MII,
- const MCTargetOptions &Options)
- : MCTargetAsmParser(), STI(_STI), Parser(_Parser), MII(MII), UC(_Parser) {
- MCAsmParserExtension::Initialize(_Parser);
+ ARMAsmParser(MCSubtargetInfo &STI, MCAsmParser &Parser,
+ const MCInstrInfo &MII, const MCTargetOptions &Options)
+ : MCTargetAsmParser(Options), STI(STI), MII(MII), UC(Parser) {
+ MCAsmParserExtension::Initialize(Parser);
// Cache the MCRegisterInfo.
MRI = getContext().getRegisterInfo();
k_ShiftedImmediate,
k_ShifterImmediate,
k_RotateImmediate,
+ k_ModifiedImmediate,
k_BitfieldDescriptor,
k_Token
} Kind;
unsigned Imm;
};
+ struct ModImmOp {
+ unsigned Bits;
+ unsigned Rot;
+ };
+
struct BitfieldOp {
unsigned LSB;
unsigned Width;
struct RegShiftedRegOp RegShiftedReg;
struct RegShiftedImmOp RegShiftedImm;
struct RotImmOp RotImm;
+ struct ModImmOp ModImm;
struct BitfieldOp Bitfield;
};
public:
ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
- ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
- Kind = o.Kind;
- StartLoc = o.StartLoc;
- EndLoc = o.EndLoc;
- switch (Kind) {
- case k_CondCode:
- CC = o.CC;
- break;
- case k_ITCondMask:
- ITMask = o.ITMask;
- break;
- case k_Token:
- Tok = o.Tok;
- break;
- case k_CCOut:
- case k_Register:
- Reg = o.Reg;
- break;
- case k_RegisterList:
- case k_DPRRegisterList:
- case k_SPRRegisterList:
- Registers = o.Registers;
- break;
- case k_VectorList:
- case k_VectorListAllLanes:
- case k_VectorListIndexed:
- VectorList = o.VectorList;
- break;
- case k_CoprocNum:
- case k_CoprocReg:
- Cop = o.Cop;
- break;
- case k_CoprocOption:
- CoprocOption = o.CoprocOption;
- break;
- case k_Immediate:
- Imm = o.Imm;
- break;
- case k_MemBarrierOpt:
- MBOpt = o.MBOpt;
- break;
- case k_InstSyncBarrierOpt:
- ISBOpt = o.ISBOpt;
- case k_Memory:
- Memory = o.Memory;
- break;
- case k_PostIndexRegister:
- PostIdxReg = o.PostIdxReg;
- break;
- case k_MSRMask:
- MMask = o.MMask;
- break;
- case k_BankedReg:
- BankedReg = o.BankedReg;
- break;
- case k_ProcIFlags:
- IFlags = o.IFlags;
- break;
- case k_ShifterImmediate:
- ShifterImm = o.ShifterImm;
- break;
- case k_ShiftedRegister:
- RegShiftedReg = o.RegShiftedReg;
- break;
- case k_ShiftedImmediate:
- RegShiftedImm = o.RegShiftedImm;
- break;
- case k_RotateImmediate:
- RotImm = o.RotImm;
- break;
- case k_BitfieldDescriptor:
- Bitfield = o.Bitfield;
- break;
- case k_VectorIndex:
- VectorIndex = o.VectorIndex;
- break;
- }
- }
/// getStartLoc - Get the location of the first token of this operand.
SMLoc getStartLoc() const override { return StartLoc; }
}
bool isAdrLabel() const {
// If we have an immediate that's not a constant, treat it as a label
- // reference needing a fixup. If it is a constant, but it can't fit
- // into shift immediate encoding, we reject it.
- if (isImm() && !isa<MCConstantExpr>(getImm())) return true;
- else return (isARMSOImm() || isARMSOImmNeg());
- }
- bool isARMSOImm() const {
- if (!isImm()) return false;
- const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- if (!CE) return false;
- int64_t Value = CE->getValue();
- return ARM_AM::getSOImmVal(Value) != -1;
- }
- bool isARMSOImmNot() const {
- if (!isImm()) return false;
- const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- if (!CE) return false;
- int64_t Value = CE->getValue();
- return ARM_AM::getSOImmVal(~Value) != -1;
- }
- bool isARMSOImmNeg() const {
+ // reference needing a fixup.
+ if (isImm() && !isa<MCConstantExpr>(getImm()))
+ return true;
+
+ // If it is a constant, it must fit into a modified immediate encoding.
if (!isImm()) return false;
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
if (!CE) return false;
int64_t Value = CE->getValue();
- // Only use this when not representable as a plain so_imm.
- return ARM_AM::getSOImmVal(Value) == -1 &&
- ARM_AM::getSOImmVal(-Value) != -1;
+ return (ARM_AM::getSOImmVal(Value) != -1 ||
+ ARM_AM::getSOImmVal(-Value) != -1);
}
bool isT2SOImm() const {
if (!isImm()) return false;
bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; }
bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; }
bool isRotImm() const { return Kind == k_RotateImmediate; }
+ bool isModImm() const { return Kind == k_ModifiedImmediate; }
+ bool isModImmNot() const {
+ if (!isImm()) return false;
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+ if (!CE) return false;
+ int64_t Value = CE->getValue();
+ return ARM_AM::getSOImmVal(~Value) != -1;
+ }
+ bool isModImmNeg() const {
+ if (!isImm()) return false;
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+ if (!CE) return false;
+ int64_t Value = CE->getValue();
+ return ARM_AM::getSOImmVal(Value) == -1 &&
+ ARM_AM::getSOImmVal(-Value) != -1;
+ }
bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
bool isPostIdxReg() const {
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
// Add as immediates when possible. Null MCExpr = 0.
if (!Expr)
- Inst.addOperand(MCOperand::CreateImm(0));
+ Inst.addOperand(MCOperand::createImm(0));
else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
- Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
+ Inst.addOperand(MCOperand::createImm(CE->getValue()));
else
- Inst.addOperand(MCOperand::CreateExpr(Expr));
+ Inst.addOperand(MCOperand::createExpr(Expr));
}
void addCondCodeOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
+ Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
- Inst.addOperand(MCOperand::CreateReg(RegNum));
+ Inst.addOperand(MCOperand::createReg(RegNum));
}
void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm(getCoproc()));
+ Inst.addOperand(MCOperand::createImm(getCoproc()));
}
void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm(getCoproc()));
+ Inst.addOperand(MCOperand::createImm(getCoproc()));
}
void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val));
+ Inst.addOperand(MCOperand::createImm(CoprocOption.Val));
}
void addITMaskOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm(ITMask.Mask));
+ Inst.addOperand(MCOperand::createImm(ITMask.Mask));
}
void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
+ Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
}
void addCCOutOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(getReg()));
+ Inst.addOperand(MCOperand::createReg(getReg()));
}
void addRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(getReg()));
+ Inst.addOperand(MCOperand::createReg(getReg()));
}
void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 3 && "Invalid number of operands!");
assert(isRegShiftedReg() &&
"addRegShiftedRegOperands() on non-RegShiftedReg!");
- Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
- Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
- Inst.addOperand(MCOperand::CreateImm(
+ Inst.addOperand(MCOperand::createReg(RegShiftedReg.SrcReg));
+ Inst.addOperand(MCOperand::createReg(RegShiftedReg.ShiftReg));
+ Inst.addOperand(MCOperand::createImm(
ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
}
assert(N == 2 && "Invalid number of operands!");
assert(isRegShiftedImm() &&
"addRegShiftedImmOperands() on non-RegShiftedImm!");
- Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
+ Inst.addOperand(MCOperand::createReg(RegShiftedImm.SrcReg));
// Shift of #32 is encoded as 0 where permitted
unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
- Inst.addOperand(MCOperand::CreateImm(
+ Inst.addOperand(MCOperand::createImm(
ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm)));
}
void addShifterImmOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
+ Inst.addOperand(MCOperand::createImm((ShifterImm.isASR << 5) |
ShifterImm.Imm));
}
const SmallVectorImpl<unsigned> &RegList = getRegList();
for (SmallVectorImpl<unsigned>::const_iterator
I = RegList.begin(), E = RegList.end(); I != E; ++I)
- Inst.addOperand(MCOperand::CreateReg(*I));
+ Inst.addOperand(MCOperand::createReg(*I));
}
void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
void addRotImmOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
// Encoded as val>>3. The printer handles display as 8, 16, 24.
- Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
+ Inst.addOperand(MCOperand::createImm(RotImm.Imm >> 3));
+ }
+
+ void addModImmOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+
+ // Support for fixups (MCFixup)
+ if (isImm())
+ return addImmOperands(Inst, N);
+
+ Inst.addOperand(MCOperand::createImm(ModImm.Bits | (ModImm.Rot << 7)));
+ }
+
+ void addModImmNotOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+ uint32_t Enc = ARM_AM::getSOImmVal(~CE->getValue());
+ Inst.addOperand(MCOperand::createImm(Enc));
+ }
+
+ void addModImmNegOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+ uint32_t Enc = ARM_AM::getSOImmVal(-CE->getValue());
+ Inst.addOperand(MCOperand::createImm(Enc));
}
void addBitfieldOperands(MCInst &Inst, unsigned N) const {
// Make a 32-bit mask w/ the referenced bits clear and all other bits set.
uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
(32 - (lsb + width)));
- Inst.addOperand(MCOperand::CreateImm(Mask));
+ Inst.addOperand(MCOperand::createImm(Mask));
}
void addImmOperands(MCInst &Inst, unsigned N) const {
void addFBits16Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::CreateImm(16 - CE->getValue()));
+ Inst.addOperand(MCOperand::createImm(16 - CE->getValue()));
}
void addFBits32Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::CreateImm(32 - CE->getValue()));
+ Inst.addOperand(MCOperand::createImm(32 - CE->getValue()));
}
void addFPImmOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addImm8s4Operands(MCInst &Inst, unsigned N) const {
// FIXME: We really want to scale the value here, but the LDRD/STRD
// instruction don't encode operands that way yet.
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
+ Inst.addOperand(MCOperand::createImm(CE->getValue()));
}
void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
// The immediate is scaled by four in the encoding and is stored
// in the MCInst as such. Lop off the low two bits here.
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
+ Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
}
void addImm0_508s4NegOperands(MCInst &Inst, unsigned N) const {
// The immediate is scaled by four in the encoding and is stored
// in the MCInst as such. Lop off the low two bits here.
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::CreateImm(-(CE->getValue() / 4)));
+ Inst.addOperand(MCOperand::createImm(-(CE->getValue() / 4)));
}
void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
// The immediate is scaled by four in the encoding and is stored
// in the MCInst as such. Lop off the low two bits here.
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
+ Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
}
void addImm1_16Operands(MCInst &Inst, unsigned N) const {
// The constant encodes as the immediate-1, and we store in the instruction
// the bits as encoded, so subtract off one here.
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
+ Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
}
void addImm1_32Operands(MCInst &Inst, unsigned N) const {
// The constant encodes as the immediate-1, and we store in the instruction
// the bits as encoded, so subtract off one here.
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
+ Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
}
void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
// zero.
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
unsigned Imm = CE->getValue();
- Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
+ Inst.addOperand(MCOperand::createImm((Imm == 32 ? 0 : Imm)));
}
void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
// the instruction as well.
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
int Val = CE->getValue();
- Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
+ Inst.addOperand(MCOperand::createImm(Val == 32 ? 0 : Val));
}
void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
// The operand is actually a t2_so_imm, but we have its bitwise
// negation in the assembly source, so twiddle it here.
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
+ Inst.addOperand(MCOperand::createImm(~CE->getValue()));
}
void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
// The operand is actually a t2_so_imm, but we have its
// negation in the assembly source, so twiddle it here.
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
+ Inst.addOperand(MCOperand::createImm(-CE->getValue()));
}
void addImm0_4095NegOperands(MCInst &Inst, unsigned N) const {
// The operand is actually an imm0_4095, but we have its
// negation in the assembly source, so twiddle it here.
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
+ Inst.addOperand(MCOperand::createImm(-CE->getValue()));
}
void addUnsignedOffset_b8s2Operands(MCInst &Inst, unsigned N) const {
if(const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
- Inst.addOperand(MCOperand::CreateImm(CE->getValue() >> 2));
+ Inst.addOperand(MCOperand::createImm(CE->getValue() >> 2));
return;
}
const MCSymbolRefExpr *SR = dyn_cast<MCSymbolRefExpr>(Imm.Val);
assert(SR && "Unknown value type!");
- Inst.addOperand(MCOperand::CreateExpr(SR));
+ Inst.addOperand(MCOperand::createExpr(SR));
}
void addThumbMemPCOperands(MCInst &Inst, unsigned N) const {
if (isImm()) {
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
if (CE) {
- Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
+ Inst.addOperand(MCOperand::createImm(CE->getValue()));
return;
}
const MCSymbolRefExpr *SR = dyn_cast<MCSymbolRefExpr>(Imm.Val);
assert(SR && "Unknown value type!");
- Inst.addOperand(MCOperand::CreateExpr(SR));
+ Inst.addOperand(MCOperand::createExpr(SR));
return;
}
assert(isMem() && "Unknown value type!");
assert(isa<MCConstantExpr>(Memory.OffsetImm) && "Unknown value type!");
- Inst.addOperand(MCOperand::CreateImm(Memory.OffsetImm->getValue()));
- }
-
- void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- // The operand is actually a so_imm, but we have its bitwise
- // negation in the assembly source, so twiddle it here.
- const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
- }
-
- void addARMSOImmNegOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands!");
- // The operand is actually a so_imm, but we have its
- // negation in the assembly source, so twiddle it here.
- const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
+ Inst.addOperand(MCOperand::createImm(Memory.OffsetImm->getValue()));
}
void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
+ Inst.addOperand(MCOperand::createImm(unsigned(getMemBarrierOpt())));
}
void addInstSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm(unsigned(getInstSyncBarrierOpt())));
+ Inst.addOperand(MCOperand::createImm(unsigned(getInstSyncBarrierOpt())));
}
void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
}
void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
int32_t Imm = Memory.OffsetImm->getValue();
- Inst.addOperand(MCOperand::CreateImm(Imm));
+ Inst.addOperand(MCOperand::createImm(Imm));
}
void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
// If we have an immediate that's not a constant, treat it as a label
// reference needing a fixup.
if (!isa<MCConstantExpr>(getImm())) {
- Inst.addOperand(MCOperand::CreateExpr(getImm()));
+ Inst.addOperand(MCOperand::createExpr(getImm()));
return;
}
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
int Val = CE->getValue();
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateImm(Memory.Alignment));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createImm(Memory.Alignment));
}
void addDupAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
Memory.ShiftImm, Memory.ShiftType);
}
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
if (Val == INT32_MIN) Val = 0;
if (Val < 0) Val = -Val;
Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
- Inst.addOperand(MCOperand::CreateReg(0));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(0));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
// reference needing a fixup. If it is a constant, it's something else
// and we reject it.
if (isImm()) {
- Inst.addOperand(MCOperand::CreateExpr(getImm()));
- Inst.addOperand(MCOperand::CreateReg(0));
- Inst.addOperand(MCOperand::CreateImm(0));
+ Inst.addOperand(MCOperand::createExpr(getImm()));
+ Inst.addOperand(MCOperand::createReg(0));
+ Inst.addOperand(MCOperand::createImm(0));
return;
}
// here.
Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
}
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
if (Kind == k_PostIndexRegister) {
int32_t Val =
ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
- Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
+ Inst.addOperand(MCOperand::createImm(Val));
return;
}
if (Val == INT32_MIN) Val = 0;
if (Val < 0) Val = -Val;
Val = ARM_AM::getAM3Opc(AddSub, Val);
- Inst.addOperand(MCOperand::CreateReg(0));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(0));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
// reference needing a fixup. If it is a constant, it's something else
// and we reject it.
if (isImm()) {
- Inst.addOperand(MCOperand::CreateExpr(getImm()));
- Inst.addOperand(MCOperand::CreateImm(0));
+ Inst.addOperand(MCOperand::createExpr(getImm()));
+ Inst.addOperand(MCOperand::createImm(0));
return;
}
if (Val == INT32_MIN) Val = 0;
if (Val < 0) Val = -Val;
Val = ARM_AM::getAM5Opc(AddSub, Val);
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
// reference needing a fixup. If it is a constant, it's something else
// and we reject it.
if (isImm()) {
- Inst.addOperand(MCOperand::CreateExpr(getImm()));
- Inst.addOperand(MCOperand::CreateImm(0));
+ Inst.addOperand(MCOperand::createExpr(getImm()));
+ Inst.addOperand(MCOperand::createImm(0));
return;
}
int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
// The lower two bits are always zero and as such are not encoded.
int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
// If this is an immediate, it's a label reference.
if (isImm()) {
addExpr(Inst, getImm());
- Inst.addOperand(MCOperand::CreateImm(0));
+ Inst.addOperand(MCOperand::createImm(0));
return;
}
// Otherwise, it's a normal memory reg+offset.
int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
// If this is an immediate, it's a label reference.
if (isImm()) {
addExpr(Inst, getImm());
- Inst.addOperand(MCOperand::CreateImm(0));
+ Inst.addOperand(MCOperand::createImm(0));
return;
}
// Otherwise, it's a normal memory reg+offset.
int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addMemTBBOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
}
void addMemTBHOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
}
void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
unsigned Val =
ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
Memory.ShiftImm, Memory.ShiftType);
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
assert(N == 3 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
- Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
+ Inst.addOperand(MCOperand::createImm(Memory.ShiftImm));
}
void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
}
void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0;
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0;
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
- Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
- Inst.addOperand(MCOperand::CreateImm(Val));
+ Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
+ Inst.addOperand(MCOperand::createImm(Val));
}
void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
bool isAdd = Imm >= 0;
if (Imm == INT32_MIN) Imm = 0;
Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
- Inst.addOperand(MCOperand::CreateImm(Imm));
+ Inst.addOperand(MCOperand::createImm(Imm));
}
void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
if (Imm == INT32_MIN) Imm = 0;
// Immediate is scaled by 4.
Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
- Inst.addOperand(MCOperand::CreateImm(Imm));
+ Inst.addOperand(MCOperand::createImm(Imm));
}
void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
- Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
+ Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
+ Inst.addOperand(MCOperand::createImm(PostIdxReg.isAdd));
}
void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
+ Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
// The sign, shift type, and shift amount are encoded in a single operand
// using the AM2 encoding helpers.
ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
PostIdxReg.ShiftTy);
- Inst.addOperand(MCOperand::CreateImm(Imm));
+ Inst.addOperand(MCOperand::createImm(Imm));
}
void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
+ Inst.addOperand(MCOperand::createImm(unsigned(getMSRMask())));
}
void addBankedRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm(unsigned(getBankedReg())));
+ Inst.addOperand(MCOperand::createImm(unsigned(getBankedReg())));
}
void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
+ Inst.addOperand(MCOperand::createImm(unsigned(getProcIFlags())));
}
void addVecListOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
+ Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
}
void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
- Inst.addOperand(MCOperand::CreateImm(VectorList.LaneIndex));
+ Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
+ Inst.addOperand(MCOperand::createImm(VectorList.LaneIndex));
}
void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
+ Inst.addOperand(MCOperand::createImm(getVectorIndex()));
}
void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
+ Inst.addOperand(MCOperand::createImm(getVectorIndex()));
}
void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
- Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
+ Inst.addOperand(MCOperand::createImm(getVectorIndex()));
}
void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
// The immediate encodes the type of constant as well as the value.
// Mask in that this is an i8 splat.
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00));
+ Inst.addOperand(MCOperand::createImm(CE->getValue() | 0xe00));
}
void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
unsigned Value = CE->getValue();
Value = ARM_AM::encodeNEONi16splat(Value);
- Inst.addOperand(MCOperand::CreateImm(Value));
+ Inst.addOperand(MCOperand::createImm(Value));
}
void addNEONi16splatNotOperands(MCInst &Inst, unsigned N) const {
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
unsigned Value = CE->getValue();
Value = ARM_AM::encodeNEONi16splat(~Value & 0xffff);
- Inst.addOperand(MCOperand::CreateImm(Value));
+ Inst.addOperand(MCOperand::createImm(Value));
}
void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
unsigned Value = CE->getValue();
Value = ARM_AM::encodeNEONi32splat(Value);
- Inst.addOperand(MCOperand::CreateImm(Value));
+ Inst.addOperand(MCOperand::createImm(Value));
}
void addNEONi32splatNotOperands(MCInst &Inst, unsigned N) const {
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
unsigned Value = CE->getValue();
Value = ARM_AM::encodeNEONi32splat(~Value);
- Inst.addOperand(MCOperand::CreateImm(Value));
+ Inst.addOperand(MCOperand::createImm(Value));
}
void addNEONinvByteReplicateOperands(MCInst &Inst, unsigned N) const {
"always must be replaced with VMOVv8i8 or VMOVv16i8.");
unsigned B = ((~Value) & 0xff);
B |= 0xe00; // cmode = 0b1110
- Inst.addOperand(MCOperand::CreateImm(B));
+ Inst.addOperand(MCOperand::createImm(B));
}
void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
else if (Value > 0xffffff)
Value = (Value >> 24) | 0x600;
- Inst.addOperand(MCOperand::CreateImm(Value));
+ Inst.addOperand(MCOperand::createImm(Value));
}
void addNEONvmovByteReplicateOperands(MCInst &Inst, unsigned N) const {
"always must be replaced with VMOVv8i8 or VMOVv16i8.");
unsigned B = Value & 0xff;
B |= 0xe00; // cmode = 0b1110
- Inst.addOperand(MCOperand::CreateImm(B));
+ Inst.addOperand(MCOperand::createImm(B));
}
void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
else if (Value > 0xffffff)
Value = (Value >> 24) | 0x600;
- Inst.addOperand(MCOperand::CreateImm(Value));
+ Inst.addOperand(MCOperand::createImm(Value));
}
void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
Imm |= (Value & 1) << i;
}
- Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00));
+ Inst.addOperand(MCOperand::createImm(Imm | 0x1e00));
}
void print(raw_ostream &OS) const override;
return Op;
}
+ static std::unique_ptr<ARMOperand> CreateModImm(unsigned Bits, unsigned Rot,
+ SMLoc S, SMLoc E) {
+ auto Op = make_unique<ARMOperand>(k_ModifiedImmediate);
+ Op->ModImm.Bits = Bits;
+ Op->ModImm.Rot = Rot;
+ Op->StartLoc = S;
+ Op->EndLoc = E;
+ return Op;
+ }
+
static std::unique_ptr<ARMOperand>
CreateBitfield(unsigned LSB, unsigned Width, SMLoc S, SMLoc E) {
auto Op = make_unique<ARMOperand>(k_BitfieldDescriptor);
OS << "<banked reg: " << getBankedReg() << ">";
break;
case k_Immediate:
- getImm()->print(OS);
+ OS << *getImm();
break;
case k_MemBarrierOpt:
OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt(), false) << ">";
case k_RotateImmediate:
OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
break;
+ case k_ModifiedImmediate:
+ OS << "<mod_imm #" << ModImm.Bits << ", #"
+ << ModImm.Rot << ")>";
+ break;
case k_BitfieldDescriptor:
OS << "<bitfield " << "lsb: " << Bitfield.LSB
<< ", width: " << Bitfield.Width << ">";
bool ARMAsmParser::ParseRegister(unsigned &RegNo,
SMLoc &StartLoc, SMLoc &EndLoc) {
- StartLoc = Parser.getTok().getLoc();
- EndLoc = Parser.getTok().getEndLoc();
+ const AsmToken &Tok = getParser().getTok();
+ StartLoc = Tok.getLoc();
+ EndLoc = Tok.getEndLoc();
RegNo = tryParseRegister();
return (RegNo == (unsigned)-1);
/// returned. Otherwise return -1.
///
int ARMAsmParser::tryParseRegister() {
+ MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier)) return -1;
return Entry->getValue();
}
+ // Some FPUs only have 16 D registers, so D16-D31 are invalid
+ if (hasD16() && RegNum >= ARM::D16 && RegNum <= ARM::D31)
+ return -1;
+
Parser.Lex(); // Eat identifier token.
return RegNum;
// consumed in the process of trying to parse the shifter (i.e., when it is
// indeed a shifter operand, but malformed).
int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
SMLoc S = Parser.getTok().getLoc();
const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier))
/// TODO this is likely to change to allow different register types and or to
/// parse for a specific register type.
bool ARMAsmParser::tryParseRegisterWithWriteBack(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
const AsmToken &RegTok = Parser.getTok();
int RegNo = tryParseRegister();
if (RegNo == -1)
/// parseITCondCode - Try to parse a condition code for an IT instruction.
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseITCondCode(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
SMLoc S = Parser.getTok().getLoc();
const AsmToken &Tok = Parser.getTok();
if (!Tok.is(AsmToken::Identifier))
/// number, the token is eaten and the operand is added to the operand list.
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseCoprocNumOperand(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
SMLoc S = Parser.getTok().getLoc();
const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier))
/// number, the token is eaten and the operand is added to the operand list.
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseCoprocRegOperand(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
SMLoc S = Parser.getTok().getLoc();
const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier))
/// coproc_option : '{' imm0_255 '}'
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseCoprocOptionOperand(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
SMLoc S = Parser.getTok().getLoc();
// If this isn't a '{', this isn't a coprocessor immediate operand.
/// Parse a register list.
bool ARMAsmParser::parseRegisterList(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
assert(Parser.getTok().is(AsmToken::LCurly) &&
"Token is not a Left Curly Brace");
SMLoc S = Parser.getTok().getLoc();
// Helper function to parse the lane index for vector lists.
ARMAsmParser::OperandMatchResultTy ARMAsmParser::
parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index, SMLoc &EndLoc) {
+ MCAsmParser &Parser = getParser();
Index = 0; // Always return a defined index value.
if (Parser.getTok().is(AsmToken::LBrac)) {
Parser.Lex(); // Eat the '['.
// parse a vector register list
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseVectorList(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
VectorLaneTy LaneKind;
unsigned LaneIndex;
SMLoc S = Parser.getTok().getLoc();
/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseMemBarrierOptOperand(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
SMLoc S = Parser.getTok().getLoc();
const AsmToken &Tok = Parser.getTok();
unsigned Opt;
/// parseInstSyncBarrierOptOperand - Try to parse ISB inst sync barrier options.
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseInstSyncBarrierOptOperand(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
SMLoc S = Parser.getTok().getLoc();
const AsmToken &Tok = Parser.getTok();
unsigned Opt;
/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseProcIFlagsOperand(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
SMLoc S = Parser.getTok().getLoc();
const AsmToken &Tok = Parser.getTok();
if (!Tok.is(AsmToken::Identifier))
/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
SMLoc S = Parser.getTok().getLoc();
const AsmToken &Tok = Parser.getTok();
if (!Tok.is(AsmToken::Identifier))
if (FlagsVal == ~0U)
return MatchOperand_NoMatch;
- if (!hasThumb2DSP() && (FlagsVal & 0x400))
+ if (!hasDSP() && (FlagsVal & 0x400))
// The _g and _nzcvqg versions are only valid if the DSP extension is
// available.
return MatchOperand_NoMatch;
/// use in the MRS/MSR instructions added to support virtualization.
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseBankedRegOperand(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
SMLoc S = Parser.getTok().getLoc();
const AsmToken &Tok = Parser.getTok();
if (!Tok.is(AsmToken::Identifier))
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parsePKHImm(OperandVector &Operands, StringRef Op, int Low,
int High) {
+ MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier)) {
Error(Parser.getTok().getLoc(), Op + " operand expected.");
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseSetEndImm(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
SMLoc S = Tok.getLoc();
if (Tok.isNot(AsmToken::Identifier)) {
Error(S, "'be' or 'le' operand expected");
return MatchOperand_ParseFail;
}
- Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
+ Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::create(Val,
getContext()),
S, Tok.getEndLoc()));
return MatchOperand_Success;
/// n == 32 encoded as n == 0.
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseShifterImm(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
SMLoc S = Tok.getLoc();
if (Tok.isNot(AsmToken::Identifier)) {
/// ror #n 'n' in {0, 8, 16, 24}
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseRotImm(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
SMLoc S = Tok.getLoc();
if (Tok.isNot(AsmToken::Identifier))
return MatchOperand_Success;
}
+ARMAsmParser::OperandMatchResultTy
+ARMAsmParser::parseModImm(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
+ MCAsmLexer &Lexer = getLexer();
+ int64_t Imm1, Imm2;
+
+ SMLoc S = Parser.getTok().getLoc();
+
+ // 1) A mod_imm operand can appear in the place of a register name:
+ // add r0, #mod_imm
+ // add r0, r0, #mod_imm
+ // to correctly handle the latter, we bail out as soon as we see an
+ // identifier.
+ //
+ // 2) Similarly, we do not want to parse into complex operands:
+ // mov r0, #mod_imm
+ // mov r0, :lower16:(_foo)
+ if (Parser.getTok().is(AsmToken::Identifier) ||
+ Parser.getTok().is(AsmToken::Colon))
+ return MatchOperand_NoMatch;
+
+ // Hash (dollar) is optional as per the ARMARM
+ if (Parser.getTok().is(AsmToken::Hash) ||
+ Parser.getTok().is(AsmToken::Dollar)) {
+ // Avoid parsing into complex operands (#:)
+ if (Lexer.peekTok().is(AsmToken::Colon))
+ return MatchOperand_NoMatch;
+
+ // Eat the hash (dollar)
+ Parser.Lex();
+ }
+
+ SMLoc Sx1, Ex1;
+ Sx1 = Parser.getTok().getLoc();
+ const MCExpr *Imm1Exp;
+ if (getParser().parseExpression(Imm1Exp, Ex1)) {
+ Error(Sx1, "malformed expression");
+ return MatchOperand_ParseFail;
+ }
+
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm1Exp);
+
+ if (CE) {
+ // Immediate must fit within 32-bits
+ Imm1 = CE->getValue();
+ int Enc = ARM_AM::getSOImmVal(Imm1);
+ if (Enc != -1 && Parser.getTok().is(AsmToken::EndOfStatement)) {
+ // We have a match!
+ Operands.push_back(ARMOperand::CreateModImm((Enc & 0xFF),
+ (Enc & 0xF00) >> 7,
+ Sx1, Ex1));
+ return MatchOperand_Success;
+ }
+
+ // We have parsed an immediate which is not for us, fallback to a plain
+ // immediate. This can happen for instruction aliases. For an example,
+ // ARMInstrInfo.td defines the alias [mov <-> mvn] which can transform
+ // a mov (mvn) with a mod_imm_neg/mod_imm_not operand into the opposite
+ // instruction with a mod_imm operand. The alias is defined such that the
+ // parser method is shared, that's why we have to do this here.
+ if (Parser.getTok().is(AsmToken::EndOfStatement)) {
+ Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
+ return MatchOperand_Success;
+ }
+ } else {
+ // Operands like #(l1 - l2) can only be evaluated at a later stage (via an
+ // MCFixup). Fallback to a plain immediate.
+ Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
+ return MatchOperand_Success;
+ }
+
+ // From this point onward, we expect the input to be a (#bits, #rot) pair
+ if (Parser.getTok().isNot(AsmToken::Comma)) {
+ Error(Sx1, "expected modified immediate operand: #[0, 255], #even[0-30]");
+ return MatchOperand_ParseFail;
+ }
+
+ if (Imm1 & ~0xFF) {
+ Error(Sx1, "immediate operand must a number in the range [0, 255]");
+ return MatchOperand_ParseFail;
+ }
+
+ // Eat the comma
+ Parser.Lex();
+
+ // Repeat for #rot
+ SMLoc Sx2, Ex2;
+ Sx2 = Parser.getTok().getLoc();
+
+ // Eat the optional hash (dollar)
+ if (Parser.getTok().is(AsmToken::Hash) ||
+ Parser.getTok().is(AsmToken::Dollar))
+ Parser.Lex();
+
+ const MCExpr *Imm2Exp;
+ if (getParser().parseExpression(Imm2Exp, Ex2)) {
+ Error(Sx2, "malformed expression");
+ return MatchOperand_ParseFail;
+ }
+
+ CE = dyn_cast<MCConstantExpr>(Imm2Exp);
+
+ if (CE) {
+ Imm2 = CE->getValue();
+ if (!(Imm2 & ~0x1E)) {
+ // We have a match!
+ Operands.push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2));
+ return MatchOperand_Success;
+ }
+ Error(Sx2, "immediate operand must an even number in the range [0, 30]");
+ return MatchOperand_ParseFail;
+ } else {
+ Error(Sx2, "constant expression expected");
+ return MatchOperand_ParseFail;
+ }
+}
+
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseBitfield(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
SMLoc S = Parser.getTok().getLoc();
// The bitfield descriptor is really two operands, the LSB and the width.
if (Parser.getTok().isNot(AsmToken::Hash) &&
// This method must return MatchOperand_NoMatch without consuming any tokens
// in the case where there is no match, as other alternatives take other
// parse methods.
+ MCAsmParser &Parser = getParser();
AsmToken Tok = Parser.getTok();
SMLoc S = Tok.getLoc();
bool haveEaten = false;
// This method must return MatchOperand_NoMatch without consuming any tokens
// in the case where there is no match, as other alternatives take other
// parse methods.
+ MCAsmParser &Parser = getParser();
AsmToken Tok = Parser.getTok();
SMLoc S = Tok.getLoc();
Val = INT32_MIN;
Operands.push_back(
- ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
+ ARMOperand::CreateImm(MCConstantExpr::create(Val, getContext()), S, E));
return MatchOperand_Success;
}
/// Parse an ARM memory expression, return false if successful else return true
/// or an error. The first token must be a '[' when called.
bool ARMAsmParser::parseMemory(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
SMLoc S, E;
assert(Parser.getTok().is(AsmToken::LBrac) &&
"Token is not a Left Bracket");
// If the constant was #-0, represent it as INT32_MIN.
int32_t Val = CE->getValue();
if (isNegative && Val == 0)
- CE = MCConstantExpr::Create(INT32_MIN, getContext());
+ CE = MCConstantExpr::create(INT32_MIN, getContext());
// Now we should have the closing ']'
if (Parser.getTok().isNot(AsmToken::RBrac))
/// return true if it parses a shift otherwise it returns false.
bool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
unsigned &Amount) {
+ MCAsmParser &Parser = getParser();
SMLoc Loc = Parser.getTok().getLoc();
const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier))
/// parseFPImm - A floating point immediate expression operand.
ARMAsmParser::OperandMatchResultTy
ARMAsmParser::parseFPImm(OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
// Anything that can accept a floating point constant as an operand
// needs to go through here, as the regular parseExpression is
// integer only.
IntVal ^= (uint64_t)isNegative << 31;
Parser.Lex(); // Eat the token.
Operands.push_back(ARMOperand::CreateImm(
- MCConstantExpr::Create(IntVal, getContext()),
+ MCConstantExpr::create(IntVal, getContext()),
S, Parser.getTok().getLoc()));
return MatchOperand_Success;
}
Val = APFloat(RealVal).bitcastToAPInt().getZExtValue();
Operands.push_back(ARMOperand::CreateImm(
- MCConstantExpr::Create(Val, getContext()), S,
+ MCConstantExpr::create(Val, getContext()), S,
Parser.getTok().getLoc()));
return MatchOperand_Success;
}
/// Parse a arm instruction operand. For now this parses the operand regardless
/// of the mnemonic.
bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
+ MCAsmParser &Parser = getParser();
SMLoc S, E;
// Check if the current operand has a custom associated parser, if so, try to
if (CE) {
int32_t Val = CE->getValue();
if (isNegative && Val == 0)
- ImmVal = MCConstantExpr::Create(INT32_MIN, getContext());
+ ImmVal = MCConstantExpr::create(INT32_MIN, getContext());
}
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
if (getParser().parseExpression(SubExprVal))
return true;
- const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
+ const MCExpr *ExprVal = ARMMCExpr::create(RefKind, SubExprVal,
getContext());
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
// :lower16: and :upper16:.
bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
+ MCAsmParser &Parser = getParser();
RefKind = ARMMCExpr::VK_ARM_None;
// consume an optional '#' (GNU compatibility)
return true;
}
+ enum {
+ COFF = (1 << MCObjectFileInfo::IsCOFF),
+ ELF = (1 << MCObjectFileInfo::IsELF),
+ MACHO = (1 << MCObjectFileInfo::IsMachO)
+ };
+ static const struct PrefixEntry {
+ const char *Spelling;
+ ARMMCExpr::VariantKind VariantKind;
+ uint8_t SupportedFormats;
+ } PrefixEntries[] = {
+ { "lower16", ARMMCExpr::VK_ARM_LO16, COFF | ELF | MACHO },
+ { "upper16", ARMMCExpr::VK_ARM_HI16, COFF | ELF | MACHO },
+ };
+
StringRef IDVal = Parser.getTok().getIdentifier();
- if (IDVal == "lower16") {
- RefKind = ARMMCExpr::VK_ARM_LO16;
- } else if (IDVal == "upper16") {
- RefKind = ARMMCExpr::VK_ARM_HI16;
- } else {
+
+ const auto &Prefix =
+ std::find_if(std::begin(PrefixEntries), std::end(PrefixEntries),
+ [&IDVal](const PrefixEntry &PE) {
+ return PE.Spelling == IDVal;
+ });
+ if (Prefix == std::end(PrefixEntries)) {
Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
return true;
}
+
+ uint8_t CurrentFormat;
+ switch (getContext().getObjectFileInfo()->getObjectFileType()) {
+ case MCObjectFileInfo::IsMachO:
+ CurrentFormat = MACHO;
+ break;
+ case MCObjectFileInfo::IsELF:
+ CurrentFormat = ELF;
+ break;
+ case MCObjectFileInfo::IsCOFF:
+ CurrentFormat = COFF;
+ break;
+ }
+
+ if (~Prefix->SupportedFormats & CurrentFormat) {
+ Error(Parser.getTok().getLoc(),
+ "cannot represent relocation in the current file format");
+ return true;
+ }
+
+ RefKind = Prefix->VariantKind;
Parser.Lex();
if (getLexer().isNot(AsmToken::Colon)) {
return true;
}
Parser.Lex(); // Eat the last ':'
+
return false;
}
Mnemonic == "fmuls" || Mnemonic == "vmaxnm" || Mnemonic == "vminnm" ||
Mnemonic == "vcvta" || Mnemonic == "vcvtn" || Mnemonic == "vcvtp" ||
Mnemonic == "vcvtm" || Mnemonic == "vrinta" || Mnemonic == "vrintn" ||
- Mnemonic == "vrintp" || Mnemonic == "vrintm" || Mnemonic.startswith("vsel"))
+ Mnemonic == "vrintp" || Mnemonic == "vrintm" || Mnemonic == "hvc" ||
+ Mnemonic.startswith("vsel"))
return Mnemonic;
// First, split out any predication code. Ignore mnemonics we know aren't
/// inclusion of carry set or predication code operands.
//
// FIXME: It would be nice to autogen this.
-void ARMAsmParser::
-getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst,
- bool &CanAcceptCarrySet, bool &CanAcceptPredicationCode) {
- if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
+void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst,
+ bool &CanAcceptCarrySet,
+ bool &CanAcceptPredicationCode) {
+ CanAcceptCarrySet =
+ Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
- Mnemonic == "add" || Mnemonic == "adc" ||
- Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
- Mnemonic == "orr" || Mnemonic == "mvn" ||
- Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
- Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" ||
- Mnemonic == "vfm" || Mnemonic == "vfnm" ||
- (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" ||
- Mnemonic == "mla" || Mnemonic == "smlal" ||
- Mnemonic == "umlal" || Mnemonic == "umull"))) {
- CanAcceptCarrySet = true;
- } else
- CanAcceptCarrySet = false;
+ Mnemonic == "add" || Mnemonic == "adc" || Mnemonic == "mul" ||
+ Mnemonic == "bic" || Mnemonic == "asr" || Mnemonic == "orr" ||
+ Mnemonic == "mvn" || Mnemonic == "rsb" || Mnemonic == "rsc" ||
+ Mnemonic == "orn" || Mnemonic == "sbc" || Mnemonic == "eor" ||
+ Mnemonic == "neg" || Mnemonic == "vfm" || Mnemonic == "vfnm" ||
+ (!isThumb() &&
+ (Mnemonic == "smull" || Mnemonic == "mov" || Mnemonic == "mla" ||
+ Mnemonic == "smlal" || Mnemonic == "umlal" || Mnemonic == "umull"));
if (Mnemonic == "bkpt" || Mnemonic == "cbnz" || Mnemonic == "setend" ||
- Mnemonic == "cps" || Mnemonic == "it" || Mnemonic == "cbz" ||
+ Mnemonic == "cps" || Mnemonic == "it" || Mnemonic == "cbz" ||
Mnemonic == "trap" || Mnemonic == "hlt" || Mnemonic == "udf" ||
Mnemonic.startswith("crc32") || Mnemonic.startswith("cps") ||
- Mnemonic.startswith("vsel") ||
- Mnemonic == "vmaxnm" || Mnemonic == "vminnm" || Mnemonic == "vcvta" ||
- Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || Mnemonic == "vcvtm" ||
- Mnemonic == "vrinta" || Mnemonic == "vrintn" || Mnemonic == "vrintp" ||
- Mnemonic == "vrintm" || Mnemonic.startswith("aes") ||
+ Mnemonic.startswith("vsel") || Mnemonic == "vmaxnm" ||
+ Mnemonic == "vminnm" || Mnemonic == "vcvta" || Mnemonic == "vcvtn" ||
+ Mnemonic == "vcvtp" || Mnemonic == "vcvtm" || Mnemonic == "vrinta" ||
+ Mnemonic == "vrintn" || Mnemonic == "vrintp" || Mnemonic == "vrintm" ||
+ Mnemonic.startswith("aes") || Mnemonic == "hvc" || Mnemonic == "setpan" ||
Mnemonic.startswith("sha1") || Mnemonic.startswith("sha256") ||
(FullInst.startswith("vmull") && FullInst.endswith(".p64"))) {
// These mnemonics are never predicable
CanAcceptPredicationCode = false;
} else if (!isThumb()) {
// Some instructions are only predicable in Thumb mode
- CanAcceptPredicationCode
- = Mnemonic != "cdp2" && Mnemonic != "clrex" && Mnemonic != "mcr2" &&
+ CanAcceptPredicationCode =
+ Mnemonic != "cdp2" && Mnemonic != "clrex" && Mnemonic != "mcr2" &&
Mnemonic != "mcrr2" && Mnemonic != "mrc2" && Mnemonic != "mrrc2" &&
Mnemonic != "dmb" && Mnemonic != "dsb" && Mnemonic != "isb" &&
Mnemonic != "pld" && Mnemonic != "pli" && Mnemonic != "pldw" &&
- Mnemonic != "ldc2" && Mnemonic != "ldc2l" &&
- Mnemonic != "stc2" && Mnemonic != "stc2l" &&
- !Mnemonic.startswith("rfe") && !Mnemonic.startswith("srs");
+ Mnemonic != "ldc2" && Mnemonic != "ldc2l" && Mnemonic != "stc2" &&
+ Mnemonic != "stc2l" && !Mnemonic.startswith("rfe") &&
+ !Mnemonic.startswith("srs");
} else if (isThumbOne()) {
if (hasV6MOps())
CanAcceptPredicationCode = Mnemonic != "movs";
CanAcceptPredicationCode = true;
}
+// \brief Some Thumb instructions have two operand forms that are not
+// available as three operand, convert to two operand form if possible.
+//
+// FIXME: We would really like to be able to tablegen'erate this.
+void ARMAsmParser::tryConvertingToTwoOperandForm(StringRef Mnemonic,
+ bool CarrySetting,
+ OperandVector &Operands) {
+ if (Operands.size() != 6)
+ return;
+
+ const auto &Op3 = static_cast<ARMOperand &>(*Operands[3]);
+ auto &Op4 = static_cast<ARMOperand &>(*Operands[4]);
+ if (!Op3.isReg() || !Op4.isReg())
+ return;
+
+ auto Op3Reg = Op3.getReg();
+ auto Op4Reg = Op4.getReg();
+
+ // For most Thumb2 cases we just generate the 3 operand form and reduce
+ // it in processInstruction(), but the 3 operand form of ADD (t2ADDrr)
+ // won't accept SP or PC so we do the transformation here taking care
+ // with immediate range in the 'add sp, sp #imm' case.
+ auto &Op5 = static_cast<ARMOperand &>(*Operands[5]);
+ if (isThumbTwo()) {
+ if (Mnemonic != "add")
+ return;
+ bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC ||
+ (Op5.isReg() && Op5.getReg() == ARM::PC);
+ if (!TryTransform) {
+ TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP ||
+ (Op5.isReg() && Op5.getReg() == ARM::SP)) &&
+ !(Op3Reg == ARM::SP && Op4Reg == ARM::SP &&
+ Op5.isImm() && !Op5.isImm0_508s4());
+ }
+ if (!TryTransform)
+ return;
+ } else if (!isThumbOne())
+ return;
+
+ if (!(Mnemonic == "add" || Mnemonic == "sub" || Mnemonic == "and" ||
+ Mnemonic == "eor" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
+ Mnemonic == "asr" || Mnemonic == "adc" || Mnemonic == "sbc" ||
+ Mnemonic == "ror" || Mnemonic == "orr" || Mnemonic == "bic"))
+ return;
+
+ // If first 2 operands of a 3 operand instruction are the same
+ // then transform to 2 operand version of the same instruction
+ // e.g. 'adds r0, r0, #1' transforms to 'adds r0, #1'
+ bool Transform = Op3Reg == Op4Reg;
+
+ // For communtative operations, we might be able to transform if we swap
+ // Op4 and Op5. The 'ADD Rdm, SP, Rdm' form is already handled specially
+ // as tADDrsp.
+ const ARMOperand *LastOp = &Op5;
+ bool Swap = false;
+ if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() &&
+ ((Mnemonic == "add" && Op4Reg != ARM::SP) ||
+ Mnemonic == "and" || Mnemonic == "eor" ||
+ Mnemonic == "adc" || Mnemonic == "orr")) {
+ Swap = true;
+ LastOp = &Op4;
+ Transform = true;
+ }
+
+ // If both registers are the same then remove one of them from
+ // the operand list, with certain exceptions.
+ if (Transform) {
+ // Don't transform 'adds Rd, Rd, Rm' or 'sub{s} Rd, Rd, Rm' because the
+ // 2 operand forms don't exist.
+ if (((Mnemonic == "add" && CarrySetting) || Mnemonic == "sub") &&
+ LastOp->isReg())
+ Transform = false;
+
+ // Don't transform 'add/sub{s} Rd, Rd, #imm' if the immediate fits into
+ // 3-bits because the ARMARM says not to.
+ if ((Mnemonic == "add" || Mnemonic == "sub") && LastOp->isImm0_7())
+ Transform = false;
+ }
+
+ if (Transform) {
+ if (Swap)
+ std::swap(Op4, Op5);
+ Operands.erase(Operands.begin() + 3);
+ }
+}
+
bool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
OperandVector &Operands) {
// FIXME: This is all horribly hacky. We really need a better way to deal
// conditionally adding the cc_out in the first place because we need
// to check the type of the parsed immediate operand.
if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() &&
- !static_cast<ARMOperand &>(*Operands[4]).isARMSOImm() &&
+ !static_cast<ARMOperand &>(*Operands[4]).isModImm() &&
static_cast<ARMOperand &>(*Operands[4]).isImm0_65535Expr() &&
static_cast<ARMOperand &>(*Operands[1]).getReg() == 0)
return true;
/// Parse an arm instruction mnemonic followed by its operands.
bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc, OperandVector &Operands) {
+ MCAsmParser &Parser = getParser();
// FIXME: Can this be done via tablegen in some fashion?
bool RequireVFPRegisterListCheck;
bool AcceptSinglePrecisionOnly;
// Add the processor imod operand, if necessary.
if (ProcessorIMod) {
Operands.push_back(ARMOperand::CreateImm(
- MCConstantExpr::Create(ProcessorIMod, getContext()),
+ MCConstantExpr::create(ProcessorIMod, getContext()),
NameLoc, NameLoc));
} else if (Mnemonic == "cps" && isMClass()) {
return Error(NameLoc, "instruction 'cps' requires effect for M-class");
"VFP/Neon double precision register expected");
}
+ tryConvertingToTwoOperandForm(Mnemonic, CarrySetting, Operands);
+
// Some instructions, mostly Thumb, have forms for the same mnemonic that
// do and don't have a cc_out optional-def operand. With some spot-checks
// of the operand list, we can figure out which variant we're trying to
// parse and adjust accordingly before actually matching. We shouldn't ever
- // try to remove a cc_out operand that was explicitly set on the the
+ // try to remove a cc_out operand that was explicitly set on the
// mnemonic, of course (CarrySetting == true). Reason number #317 the
// table driven matcher doesn't fit well with the ARM instruction set.
if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands))
}
}
- // If first 2 operands of a 3 operand instruction are the same
- // then transform to 2 operand version of the same instruction
- // e.g. 'adds r0, r0, #1' transforms to 'adds r0, #1'
- // FIXME: We would really like to be able to tablegen'erate this.
- if (isThumbOne() && Operands.size() == 6 &&
- (Mnemonic == "add" || Mnemonic == "sub" || Mnemonic == "and" ||
- Mnemonic == "eor" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
- Mnemonic == "asr" || Mnemonic == "adc" || Mnemonic == "sbc" ||
- Mnemonic == "ror" || Mnemonic == "orr" || Mnemonic == "bic")) {
- ARMOperand &Op3 = static_cast<ARMOperand &>(*Operands[3]);
- ARMOperand &Op4 = static_cast<ARMOperand &>(*Operands[4]);
- ARMOperand &Op5 = static_cast<ARMOperand &>(*Operands[5]);
-
- // If both registers are the same then remove one of them from
- // the operand list.
- if (Op3.isReg() && Op4.isReg() && Op3.getReg() == Op4.getReg()) {
- // If 3rd operand (variable Op5) is a register and the instruction is adds/sub
- // then do not transform as the backend already handles this instruction
- // correctly.
- if (!Op5.isReg() || !((Mnemonic == "add" && CarrySetting) || Mnemonic == "sub")) {
- Operands.erase(Operands.begin() + 3);
- if (Mnemonic == "add" && !CarrySetting) {
- // Special case for 'add' (not 'adds') instruction must
- // remove the CCOut operand as well.
- Operands.erase(Operands.begin() + 1);
- }
- }
- }
- }
-
- // If instruction is 'add' and first two register operands
- // use SP register, then remove one of the SP registers from
- // the instruction.
- // FIXME: We would really like to be able to tablegen'erate this.
- if (isThumbOne() && Operands.size() == 5 && Mnemonic == "add" && !CarrySetting) {
- ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[2]);
- ARMOperand &Op3 = static_cast<ARMOperand &>(*Operands[3]);
- if (Op2.isReg() && Op3.isReg() && Op2.getReg() == ARM::SP && Op3.getReg() == ARM::SP) {
- Operands.erase(Operands.begin() + 2);
- }
- }
-
// GNU Assembler extension (compatibility)
if ((Mnemonic == "ldrd" || Mnemonic == "strd")) {
ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[2]);
// return 'true' if register list contains non-low GPR registers,
// 'false' otherwise. If Reg is in the register list or is HiReg, set
// 'containsReg' to true.
-static bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
- unsigned HiReg, bool &containsReg) {
+static bool checkLowRegisterList(const MCInst &Inst, unsigned OpNo,
+ unsigned Reg, unsigned HiReg,
+ bool &containsReg) {
containsReg = false;
for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
unsigned OpReg = Inst.getOperand(i).getReg();
// Check if the specified regisgter is in the register list of the inst,
// starting at the indicated operand number.
-static bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
- for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
+static bool listContainsReg(const MCInst &Inst, unsigned OpNo, unsigned Reg) {
+ for (unsigned i = OpNo, e = Inst.getNumOperands(); i < e; ++i) {
unsigned OpReg = Inst.getOperand(i).getReg();
if (OpReg == Reg)
return true;
}
+bool ARMAsmParser::validatetLDMRegList(const MCInst &Inst,
+ const OperandVector &Operands,
+ unsigned ListNo, bool IsARPop) {
+ const ARMOperand &Op = static_cast<const ARMOperand &>(*Operands[ListNo]);
+ bool HasWritebackToken = Op.isToken() && Op.getToken() == "!";
+
+ bool ListContainsSP = listContainsReg(Inst, ListNo, ARM::SP);
+ bool ListContainsLR = listContainsReg(Inst, ListNo, ARM::LR);
+ bool ListContainsPC = listContainsReg(Inst, ListNo, ARM::PC);
+
+ if (!IsARPop && ListContainsSP)
+ return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
+ "SP may not be in the register list");
+ else if (ListContainsPC && ListContainsLR)
+ return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
+ "PC and LR may not be in the register list simultaneously");
+ else if (inITBlock() && !lastInITBlock() && ListContainsPC)
+ return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
+ "instruction must be outside of IT block or the last "
+ "instruction in an IT block");
+ return false;
+}
+
+bool ARMAsmParser::validatetSTMRegList(const MCInst &Inst,
+ const OperandVector &Operands,
+ unsigned ListNo) {
+ const ARMOperand &Op = static_cast<const ARMOperand &>(*Operands[ListNo]);
+ bool HasWritebackToken = Op.isToken() && Op.getToken() == "!";
+
+ bool ListContainsSP = listContainsReg(Inst, ListNo, ARM::SP);
+ bool ListContainsPC = listContainsReg(Inst, ListNo, ARM::PC);
+
+ if (ListContainsSP && ListContainsPC)
+ return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
+ "SP and PC may not be in the register list");
+ else if (ListContainsSP)
+ return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
+ "SP may not be in the register list");
+ else if (ListContainsPC)
+ return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
+ "PC may not be in the register list");
+ return false;
+}
+
// FIXME: We would really like to be able to tablegen'erate this.
bool ARMAsmParser::validateInstruction(MCInst &Inst,
const OperandVector &Operands) {
"destination operands can't be identical");
return false;
}
+ case ARM::t2BXJ: {
+ const unsigned RmReg = Inst.getOperand(0).getReg();
+ // Rm = SP is no longer unpredictable in v8-A
+ if (RmReg == ARM::SP && !hasV8Ops())
+ return Error(Operands[2]->getStartLoc(),
+ "r13 (SP) is an unpredictable operand to BXJ");
+ return false;
+ }
case ARM::STRD: {
// Rt2 must be Rt + 1.
unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
"writeback operator '!' not allowed when base register "
"in register list");
+ if (validatetLDMRegList(Inst, Operands, 3))
+ return true;
break;
}
case ARM::LDMIA_UPD:
// UNPREDICTABLE on v7 upwards. Goodness knows what they did before.
if (!hasV7Ops())
break;
- // Fallthrough
+ if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
+ return Error(Operands.back()->getStartLoc(),
+ "writeback register not allowed in register list");
+ break;
+ case ARM::t2LDMIA:
+ case ARM::t2LDMDB:
+ if (validatetLDMRegList(Inst, Operands, 3))
+ return true;
+ break;
+ case ARM::t2STMIA:
+ case ARM::t2STMDB:
+ if (validatetSTMRegList(Inst, Operands, 3))
+ return true;
+ break;
case ARM::t2LDMIA_UPD:
case ARM::t2LDMDB_UPD:
case ARM::t2STMIA_UPD:
if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
return Error(Operands.back()->getStartLoc(),
"writeback register not allowed in register list");
+
+ if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
+ if (validatetLDMRegList(Inst, Operands, 3))
+ return true;
+ } else {
+ if (validatetSTMRegList(Inst, Operands, 3))
+ return true;
+ }
break;
}
case ARM::sysLDMIA_UPD:
!isThumbTwo())
return Error(Operands[2]->getStartLoc(),
"registers must be in range r0-r7 or pc");
+ if (validatetLDMRegList(Inst, Operands, 2, !isMClass()))
+ return true;
break;
}
case ARM::tPUSH: {
!isThumbTwo())
return Error(Operands[2]->getStartLoc(),
"registers must be in range r0-r7 or lr");
+ if (validatetSTMRegList(Inst, Operands, 2))
+ return true;
break;
}
case ARM::tSTMIA_UPD: {
return Error(Operands[4]->getStartLoc(),
"writeback operator '!' not allowed when base register "
"in register list");
+
+ if (validatetSTMRegList(Inst, Operands, 4))
+ return true;
break;
}
case ARM::tADDrSP: {
}
bool ARMAsmParser::processInstruction(MCInst &Inst,
- const OperandVector &Operands) {
+ const OperandVector &Operands,
+ MCStreamer &Out) {
switch (Inst.getOpcode()) {
// Alias for alternate form of 'ldr{,b}t Rt, [Rn], #imm' instruction.
case ARM::LDRT_POST:
TmpInst.addOperand(Inst.getOperand(0));
TmpInst.addOperand(Inst.getOperand(1));
TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::CreateReg(0));
- TmpInst.addOperand(MCOperand::CreateImm(0));
+ TmpInst.addOperand(MCOperand::createReg(0));
+ TmpInst.addOperand(MCOperand::createImm(0));
TmpInst.addOperand(Inst.getOperand(2));
TmpInst.addOperand(Inst.getOperand(3));
Inst = TmpInst;
TmpInst.addOperand(Inst.getOperand(1));
TmpInst.addOperand(Inst.getOperand(0));
TmpInst.addOperand(Inst.getOperand(1));
- TmpInst.addOperand(MCOperand::CreateReg(0));
- TmpInst.addOperand(MCOperand::CreateImm(0));
+ TmpInst.addOperand(MCOperand::createReg(0));
+ TmpInst.addOperand(MCOperand::createImm(0));
TmpInst.addOperand(Inst.getOperand(2));
TmpInst.addOperand(Inst.getOperand(3));
Inst = TmpInst;
// Alias for alternate form of 'ADR Rd, #imm' instruction.
case ARM::ADDri: {
if (Inst.getOperand(1).getReg() != ARM::PC ||
- Inst.getOperand(5).getReg() != 0)
+ Inst.getOperand(5).getReg() != 0 ||
+ !(Inst.getOperand(2).isExpr() || Inst.getOperand(2).isImm()))
return false;
MCInst TmpInst;
TmpInst.setOpcode(ARM::ADR);
TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(2));
+ if (Inst.getOperand(2).isImm()) {
+ // Immediate (mod_imm) will be in its encoded form, we must unencode it
+ // before passing it to the ADR instruction.
+ unsigned Enc = Inst.getOperand(2).getImm();
+ TmpInst.addOperand(MCOperand::createImm(
+ ARM_AM::rotr32(Enc & 0xFF, (Enc & 0xF00) >> 7)));
+ } else {
+ // Turn PC-relative expression into absolute expression.
+ // Reading PC provides the start of the current instruction + 8 and
+ // the transform to adr is biased by that.
+ MCSymbol *Dot = getContext().createTempSymbol();
+ Out.EmitLabel(Dot);
+ const MCExpr *OpExpr = Inst.getOperand(2).getExpr();
+ const MCExpr *InstPC = MCSymbolRefExpr::create(Dot,
+ MCSymbolRefExpr::VK_None,
+ getContext());
+ const MCExpr *Const8 = MCConstantExpr::create(8, getContext());
+ const MCExpr *ReadPC = MCBinaryExpr::createAdd(InstPC, Const8,
+ getContext());
+ const MCExpr *FixupAddr = MCBinaryExpr::createAdd(ReadPC, OpExpr,
+ getContext());
+ TmpInst.addOperand(MCOperand::createExpr(FixupAddr));
+ }
TmpInst.addOperand(Inst.getOperand(3));
TmpInst.addOperand(Inst.getOperand(4));
Inst = TmpInst;
TmpInst.addOperand(Inst.getOperand(3)); // alignment
TmpInst.addOperand(Inst.getOperand(4)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(5)); // CondCode
TmpInst.addOperand(Inst.getOperand(3)); // alignment
TmpInst.addOperand(Inst.getOperand(4)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(5)); // CondCode
TmpInst.addOperand(Inst.getOperand(3)); // alignment
TmpInst.addOperand(Inst.getOperand(4)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(5)); // CondCode
TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
- TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(MCOperand::createReg(0)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Vd
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
- TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(MCOperand::createReg(0)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
- TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(MCOperand::createReg(0)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
- TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(MCOperand::createReg(0)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
TmpInst.addOperand(Inst.getOperand(4)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(5)); // CondCode
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
TmpInst.addOperand(Inst.getOperand(4)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(5)); // CondCode
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
TmpInst.addOperand(Inst.getOperand(4)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(5)); // CondCode
TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
- TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(MCOperand::createReg(0)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
- TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(MCOperand::createReg(0)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
- TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(MCOperand::createReg(0)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
- TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(MCOperand::createReg(0)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(2)); // Rn
TmpInst.addOperand(Inst.getOperand(3)); // alignment
TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(1)); // lane
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(2)); // alignment
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
TmpInst.addOperand(Inst.getOperand(2)); // alignment
- TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(MCOperand::createReg(0)); // Rm
TmpInst.addOperand(Inst.getOperand(3)); // CondCode
TmpInst.addOperand(Inst.getOperand(4));
Inst = TmpInst;
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(2)); // alignment
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
TmpInst.addOperand(Inst.getOperand(2)); // alignment
- TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(MCOperand::createReg(0)); // Rm
TmpInst.addOperand(Inst.getOperand(3)); // CondCode
TmpInst.addOperand(Inst.getOperand(4));
Inst = TmpInst;
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(2)); // alignment
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
TmpInst.addOperand(Inst.getOperand(2)); // alignment
- TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(MCOperand::createReg(0)); // Rm
TmpInst.addOperand(Inst.getOperand(3)); // CondCode
TmpInst.addOperand(Inst.getOperand(4));
Inst = TmpInst;
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(2)); // alignment
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
TmpInst.addOperand(Inst.getOperand(2)); // alignment
- TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(MCOperand::createReg(0)); // Rm
TmpInst.addOperand(Inst.getOperand(3)); // CondCode
TmpInst.addOperand(Inst.getOperand(4));
Inst = TmpInst;
unsigned Spacing;
TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(2)); // alignment
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(3)); // CondCode
TmpInst.addOperand(Inst.getOperand(4));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
TmpInst.addOperand(Inst.getOperand(2)); // alignment
- TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(MCOperand::createReg(0)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(3)); // CondCode
TmpInst.addOperand(Inst.getOperand(4));
TmpInst.addOperand(Inst.getOperand(2)); // alignment
TmpInst.addOperand(Inst.getOperand(3)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
TmpInst.addOperand(Inst.getOperand(5));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(2)); // alignment
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(3)); // CondCode
TmpInst.addOperand(Inst.getOperand(4));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
TmpInst.addOperand(Inst.getOperand(2)); // alignment
- TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(MCOperand::createReg(0)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(3)); // CondCode
TmpInst.addOperand(Inst.getOperand(4));
TmpInst.addOperand(Inst.getOperand(2)); // alignment
TmpInst.addOperand(Inst.getOperand(3)); // Rm
TmpInst.addOperand(Inst.getOperand(0)); // Vd
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 2));
- TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
+ TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
Spacing * 3));
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
TmpInst.addOperand(Inst.getOperand(5));
TmpInst.setOpcode(newOpc);
TmpInst.addOperand(Inst.getOperand(0)); // Rd
if (isNarrow)
- TmpInst.addOperand(MCOperand::CreateReg(
+ TmpInst.addOperand(MCOperand::createReg(
Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(2)); // Rm
TmpInst.addOperand(Inst.getOperand(4)); // CondCode
TmpInst.addOperand(Inst.getOperand(5));
if (!isNarrow)
- TmpInst.addOperand(MCOperand::CreateReg(
+ TmpInst.addOperand(MCOperand::createReg(
Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
Inst = TmpInst;
return true;
TmpInst.setOpcode(newOpc);
TmpInst.addOperand(Inst.getOperand(0)); // Rd
if (isNarrow)
- TmpInst.addOperand(MCOperand::CreateReg(
+ TmpInst.addOperand(MCOperand::createReg(
Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
if (newOpc != ARM::t2RRX)
- TmpInst.addOperand(MCOperand::CreateImm(Amount));
+ TmpInst.addOperand(MCOperand::createImm(Amount));
TmpInst.addOperand(Inst.getOperand(3)); // CondCode
TmpInst.addOperand(Inst.getOperand(4));
if (!isNarrow)
- TmpInst.addOperand(MCOperand::CreateReg(
+ TmpInst.addOperand(MCOperand::createReg(
Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
Inst = TmpInst;
return true;
TmpInst.addOperand(Inst.getOperand(0)); // Rd
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(Inst.getOperand(2)); // Rm
- TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
+ TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
TmpInst.addOperand(Inst.getOperand(3)); // CondCode
TmpInst.addOperand(Inst.getOperand(4));
TmpInst.addOperand(Inst.getOperand(5)); // cc_out
TmpInst.addOperand(Inst.getOperand(0)); // Rd
TmpInst.addOperand(Inst.getOperand(1)); // Rn
if (Opc == ARM::MOVsi)
- TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
+ TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
TmpInst.addOperand(Inst.getOperand(3)); // CondCode
TmpInst.addOperand(Inst.getOperand(4));
TmpInst.addOperand(Inst.getOperand(5)); // cc_out
TmpInst.setOpcode(ARM::MOVsi);
TmpInst.addOperand(Inst.getOperand(0)); // Rd
TmpInst.addOperand(Inst.getOperand(1)); // Rn
- TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
+ TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
TmpInst.addOperand(Inst.getOperand(2)); // CondCode
TmpInst.addOperand(Inst.getOperand(3));
TmpInst.addOperand(Inst.getOperand(4)); // cc_out
TmpInst.addOperand(Inst.getOperand(4)); // Rt
TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(1)); // Rn
- TmpInst.addOperand(MCOperand::CreateImm(4));
+ TmpInst.addOperand(MCOperand::createImm(4));
TmpInst.addOperand(Inst.getOperand(2)); // CondCode
TmpInst.addOperand(Inst.getOperand(3));
Inst = TmpInst;
TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(4)); // Rt
TmpInst.addOperand(Inst.getOperand(1)); // Rn
- TmpInst.addOperand(MCOperand::CreateImm(-4));
+ TmpInst.addOperand(MCOperand::createImm(-4));
TmpInst.addOperand(Inst.getOperand(2)); // CondCode
TmpInst.addOperand(Inst.getOperand(3));
Inst = TmpInst;
TmpInst.addOperand(Inst.getOperand(4)); // Rt
TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(1)); // Rn
- TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset
- TmpInst.addOperand(MCOperand::CreateImm(4));
+ TmpInst.addOperand(MCOperand::createReg(0)); // am2offset
+ TmpInst.addOperand(MCOperand::createImm(4));
TmpInst.addOperand(Inst.getOperand(2)); // CondCode
TmpInst.addOperand(Inst.getOperand(3));
Inst = TmpInst;
TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
TmpInst.addOperand(Inst.getOperand(4)); // Rt
TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
- TmpInst.addOperand(MCOperand::CreateImm(-4));
+ TmpInst.addOperand(MCOperand::createImm(-4));
TmpInst.addOperand(Inst.getOperand(2)); // CondCode
TmpInst.addOperand(Inst.getOperand(3));
Inst = TmpInst;
ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
break;
Inst.setOpcode(ARM::t2ADDri);
- Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
+ Inst.addOperand(MCOperand::createReg(0)); // cc_out
break;
case ARM::t2SUBri12:
// If the immediate fits for encoding T3 (t2SUBri) and the generic "sub"
ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
break;
Inst.setOpcode(ARM::t2SUBri);
- Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
+ Inst.addOperand(MCOperand::createReg(0)); // cc_out
break;
case ARM::tADDi8:
// If the immediate is in the range 0-7, we want tADDi3 iff Rd was
// If the destination and first source operand are the same, and
// there's no setting of the flags, use encoding T2 instead of T3.
// Note that this is only for ADD, not SUB. This mirrors the system
- // 'as' behaviour. Make sure the wide encoding wasn't explicit.
- if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() ||
+ // 'as' behaviour. Also take advantage of ADD being commutative.
+ // Make sure the wide encoding wasn't explicit.
+ bool Swap = false;
+ auto DestReg = Inst.getOperand(0).getReg();
+ bool Transform = DestReg == Inst.getOperand(1).getReg();
+ if (!Transform && DestReg == Inst.getOperand(2).getReg()) {
+ Transform = true;
+ Swap = true;
+ }
+ if (!Transform ||
Inst.getOperand(5).getReg() != 0 ||
(static_cast<ARMOperand &>(*Operands[3]).isToken() &&
static_cast<ARMOperand &>(*Operands[3]).getToken() == ".w"))
TmpInst.setOpcode(ARM::tADDhirr);
TmpInst.addOperand(Inst.getOperand(0));
TmpInst.addOperand(Inst.getOperand(0));
- TmpInst.addOperand(Inst.getOperand(2));
+ TmpInst.addOperand(Inst.getOperand(Swap ? 1 : 2));
TmpInst.addOperand(Inst.getOperand(3));
TmpInst.addOperand(Inst.getOperand(4));
Inst = TmpInst;
// same, we need to use the 32-bit encoding if it's available.
if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
Inst.setOpcode(ARM::t2ADDrr);
- Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
+ Inst.addOperand(MCOperand::createReg(0)); // cc_out
return true;
}
break;
// the writeback tied operand.
if (hasWritebackToken)
Inst.insert(Inst.begin(),
- MCOperand::CreateReg(Inst.getOperand(0).getReg()));
+ MCOperand::createReg(Inst.getOperand(0).getReg()));
return true;
}
break;
assert (isThumbTwo());
Inst.setOpcode(ARM::t2LDMIA_UPD);
// Add the base register and writeback operands.
- Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
- Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
+ Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
+ Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
return true;
}
case ARM::tPUSH: {
assert (isThumbTwo());
Inst.setOpcode(ARM::t2STMDB_UPD);
// Add the base register and writeback operands.
- Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
- Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
+ Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
+ Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
return true;
}
case ARM::t2MOVi: {
MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
MatchingInlineAsm);
switch (MatchResult) {
- default: break;
case Match_Success:
// Context sensitive operand constraints aren't handled by the matcher,
// so check them here.
// encoding is selected. Loop on it while changes happen so the
// individual transformations can chain off each other. E.g.,
// tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
- while (processInstruction(Inst, Operands))
+ while (processInstruction(Inst, Operands, Out))
;
// Only after the instruction is fully processed, we can validate it
/// ::= .short expression [, expression]*
/// ::= .word expression [, expression]*
bool ARMAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {
+ MCAsmParser &Parser = getParser();
if (getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) {
const MCExpr *Value;
/// parseDirectiveThumb
/// ::= .thumb
bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
+ MCAsmParser &Parser = getParser();
if (getLexer().isNot(AsmToken::EndOfStatement)) {
Error(L, "unexpected token in directive");
return false;
/// parseDirectiveARM
/// ::= .arm
bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
+ MCAsmParser &Parser = getParser();
if (getLexer().isNot(AsmToken::EndOfStatement)) {
Error(L, "unexpected token in directive");
return false;
/// parseDirectiveThumbFunc
/// ::= .thumbfunc symbol_name
bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
+ MCAsmParser &Parser = getParser();
const auto Format = getContext().getObjectFileInfo()->getObjectFileType();
bool IsMachO = Format == MCObjectFileInfo::IsMachO;
}
MCSymbol *Func =
- getParser().getContext().GetOrCreateSymbol(Tok.getIdentifier());
+ getParser().getContext().getOrCreateSymbol(Tok.getIdentifier());
getParser().getStreamer().EmitThumbFunc(Func);
Parser.Lex(); // Consume the identifier token.
return false;
/// parseDirectiveSyntax
/// ::= .syntax unified | divided
bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
+ MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier)) {
Error(L, "unexpected token in .syntax directive");
/// parseDirectiveCode
/// ::= .code 16 | 32
bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
+ MCAsmParser &Parser = getParser();
const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Integer)) {
Error(L, "unexpected token in .code directive");
/// parseDirectiveReq
/// ::= name .req registername
bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
+ MCAsmParser &Parser = getParser();
Parser.Lex(); // Eat the '.req' token.
unsigned Reg;
SMLoc SRegLoc, ERegLoc;
Parser.Lex(); // Consume the EndOfStatement
- if (RegisterReqs.GetOrCreateValue(Name, Reg).getValue() != Reg) {
+ if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second != Reg) {
Error(SRegLoc, "redefinition of '" + Name + "' does not match original.");
return false;
}
/// parseDirectiveUneq
/// ::= .unreq registername
bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
+ MCAsmParser &Parser = getParser();
if (Parser.getTok().isNot(AsmToken::Identifier)) {
Parser.eatToEndOfStatement();
Error(L, "unexpected input in .unreq directive.");
bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
StringRef Arch = getParser().parseStringToEndOfStatement().trim();
- unsigned ID = StringSwitch<unsigned>(Arch)
-#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \
- .Case(NAME, ARM::ID)
-#define ARM_ARCH_ALIAS(NAME, ID) \
- .Case(NAME, ARM::ID)
-#include "MCTargetDesc/ARMArchName.def"
- .Default(ARM::INVALID_ARCH);
+ unsigned ID = ARM::parseArch(Arch);
- if (ID == ARM::INVALID_ARCH) {
+ if (ID == ARM::AK_INVALID) {
Error(L, "Unknown arch name");
return false;
}
/// ::= .eabi_attribute int, int [, "str"]
/// ::= .eabi_attribute Tag_name, int [, "str"]
bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
+ MCAsmParser &Parser = getParser();
int64_t Tag;
SMLoc TagLoc;
TagLoc = Parser.getTok().getLoc();
if (Tag == ARMBuildAttrs::compatibility) {
if (Parser.getTok().isNot(AsmToken::Comma))
IsStringValue = false;
- else
- Parser.Lex();
+ if (Parser.getTok().isNot(AsmToken::Comma)) {
+ Error(Parser.getTok().getLoc(), "comma expected");
+ Parser.eatToEndOfStatement();
+ return false;
+ } else {
+ Parser.Lex();
+ }
}
if (IsStringValue) {
bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
StringRef CPU = getParser().parseStringToEndOfStatement().trim();
getTargetStreamer().emitTextAttribute(ARMBuildAttrs::CPU_name, CPU);
- return false;
-}
-// FIXME: This is duplicated in getARMFPUFeatures() in
-// tools/clang/lib/Driver/Tools.cpp
-static const struct {
- const unsigned Fpu;
- const uint64_t Enabled;
- const uint64_t Disabled;
-} Fpus[] = {
- {ARM::VFP, ARM::FeatureVFP2, ARM::FeatureNEON},
- {ARM::VFPV2, ARM::FeatureVFP2, ARM::FeatureNEON},
- {ARM::VFPV3, ARM::FeatureVFP3, ARM::FeatureNEON},
- {ARM::VFPV3_D16, ARM::FeatureVFP3 | ARM::FeatureD16, ARM::FeatureNEON},
- {ARM::VFPV4, ARM::FeatureVFP4, ARM::FeatureNEON},
- {ARM::VFPV4_D16, ARM::FeatureVFP4 | ARM::FeatureD16, ARM::FeatureNEON},
- {ARM::FP_ARMV8, ARM::FeatureFPARMv8,
- ARM::FeatureNEON | ARM::FeatureCrypto},
- {ARM::NEON, ARM::FeatureNEON, 0},
- {ARM::NEON_VFPV4, ARM::FeatureVFP4 | ARM::FeatureNEON, 0},
- {ARM::NEON_FP_ARMV8, ARM::FeatureFPARMv8 | ARM::FeatureNEON,
- ARM::FeatureCrypto},
- {ARM::CRYPTO_NEON_FP_ARMV8,
- ARM::FeatureFPARMv8 | ARM::FeatureNEON | ARM::FeatureCrypto, 0},
- {ARM::SOFTVFP, 0, 0},
-};
+ // FIXME: This is using table-gen data, but should be moved to
+ // ARMTargetParser once that is table-gen'd.
+ if (!STI.isCPUStringValid(CPU)) {
+ Error(L, "Unknown CPU name");
+ return false;
+ }
+
+ STI.setDefaultFeatures(CPU);
+ setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
+ return false;
+}
/// parseDirectiveFPU
/// ::= .fpu str
bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
+ SMLoc FPUNameLoc = getTok().getLoc();
StringRef FPU = getParser().parseStringToEndOfStatement().trim();
- unsigned ID = StringSwitch<unsigned>(FPU)
-#define ARM_FPU_NAME(NAME, ID) .Case(NAME, ARM::ID)
-#include "ARMFPUName.def"
- .Default(ARM::INVALID_FPU);
-
- if (ID == ARM::INVALID_FPU) {
- Error(L, "Unknown FPU name");
+ unsigned ID = ARM::parseFPU(FPU);
+ std::vector<const char *> Features;
+ if (!ARM::getFPUFeatures(ID, Features)) {
+ Error(FPUNameLoc, "Unknown FPU name");
return false;
}
- for (const auto &Fpu : Fpus) {
- if (Fpu.Fpu != ID)
- continue;
-
- // Need to toggle features that should be on but are off and that
- // should off but are on.
- uint64_t Toggle = (Fpu.Enabled & ~STI.getFeatureBits()) |
- (Fpu.Disabled & STI.getFeatureBits());
- setAvailableFeatures(ComputeAvailableFeatures(STI.ToggleFeature(Toggle)));
- break;
- }
+ for (auto Feature : Features)
+ STI.ApplyFeatureFlag(Feature);
+ setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
getTargetStreamer().emitFPU(ID);
return false;
/// parseDirectivePersonality
/// ::= .personality name
bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
+ MCAsmParser &Parser = getParser();
bool HasExistingPersonality = UC.hasPersonality();
UC.recordPersonality(L);
StringRef Name(Parser.getTok().getIdentifier());
Parser.Lex();
- MCSymbol *PR = getParser().getContext().GetOrCreateSymbol(Name);
+ MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
getTargetStreamer().emitPersonality(PR);
return false;
}
/// parseDirectiveSetFP
/// ::= .setfp fpreg, spreg [, offset]
bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) {
+ MCAsmParser &Parser = getParser();
// Check the ordering of unwind directives
if (!UC.hasFnStart()) {
Error(L, ".fnstart must precede .setfp directive");
/// parseDirective
/// ::= .pad offset
bool ARMAsmParser::parseDirectivePad(SMLoc L) {
+ MCAsmParser &Parser = getParser();
// Check the ordering of unwind directives
if (!UC.hasFnStart()) {
Error(L, ".fnstart must precede .pad directive");
/// ::= .inst.n opcode [, ...]
/// ::= .inst.w opcode [, ...]
bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {
+ MCAsmParser &Parser = getParser();
int Width;
if (isThumb()) {
}
if (!Section) {
- getStreamer().InitSections();
+ getStreamer().InitSections(false);
Section = getStreamer().getCurrentSection().first;
}
/// parseDirectivePersonalityIndex
/// ::= .personalityindex index
bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) {
+ MCAsmParser &Parser = getParser();
bool HasExistingPersonality = UC.hasPersonality();
UC.recordPersonalityIndex(L);
/// parseDirectiveUnwindRaw
/// ::= .unwind_raw offset, opcode [, opcode...]
bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
+ MCAsmParser &Parser = getParser();
if (!UC.hasFnStart()) {
Parser.eatToEndOfStatement();
Error(L, ".fnstart must precede .unwind_raw directives");
/// parseDirectiveTLSDescSeq
/// ::= .tlsdescseq tls-variable
bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
+ MCAsmParser &Parser = getParser();
+
if (getLexer().isNot(AsmToken::Identifier)) {
TokError("expected variable after '.tlsdescseq' directive");
Parser.eatToEndOfStatement();
}
const MCSymbolRefExpr *SRE =
- MCSymbolRefExpr::Create(Parser.getTok().getIdentifier(),
+ MCSymbolRefExpr::create(Parser.getTok().getIdentifier(),
MCSymbolRefExpr::VK_ARM_TLSDESCSEQ, getContext());
Lex();
/// parseDirectiveMovSP
/// ::= .movsp reg [, #offset]
bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
+ MCAsmParser &Parser = getParser();
if (!UC.hasFnStart()) {
Parser.eatToEndOfStatement();
Error(L, ".fnstart must precede .movsp directives");
/// parseDirectiveObjectArch
/// ::= .object_arch name
bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
+ MCAsmParser &Parser = getParser();
if (getLexer().isNot(AsmToken::Identifier)) {
Error(getLexer().getLoc(), "unexpected token");
Parser.eatToEndOfStatement();
SMLoc ArchLoc = Parser.getTok().getLoc();
getLexer().Lex();
- unsigned ID = StringSwitch<unsigned>(Arch)
-#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \
- .Case(NAME, ARM::ID)
-#define ARM_ARCH_ALIAS(NAME, ID) \
- .Case(NAME, ARM::ID)
-#include "MCTargetDesc/ARMArchName.def"
-#undef ARM_ARCH_NAME
-#undef ARM_ARCH_ALIAS
- .Default(ARM::INVALID_ARCH);
-
- if (ID == ARM::INVALID_ARCH) {
+ unsigned ID = ARM::parseArch(Arch);
+
+ if (ID == ARM::AK_INVALID) {
Error(ArchLoc, "unknown architecture '" + Arch + "'");
Parser.eatToEndOfStatement();
return false;
/// parseDirectiveThumbSet
/// ::= .thumb_set name, value
bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
+ MCAsmParser &Parser = getParser();
+
StringRef Name;
if (Parser.parseIdentifier(Name)) {
TokError("expected identifier after '.thumb_set'");
}
Lex();
+ MCSymbol *Sym;
const MCExpr *Value;
- if (Parser.parseExpression(Value)) {
- TokError("missing expression");
- Parser.eatToEndOfStatement();
- return false;
- }
-
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- TokError("unexpected token");
- Parser.eatToEndOfStatement();
- return false;
- }
- Lex();
+ if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
+ Parser, Sym, Value))
+ return true;
- MCSymbol *Alias = getContext().GetOrCreateSymbol(Name);
- getTargetStreamer().emitThumbSet(Alias, Value);
+ getTargetStreamer().emitThumbSet(Sym, Value);
return false;
}
#define GET_MATCHER_IMPLEMENTATION
#include "ARMGenAsmMatcher.inc"
+// FIXME: This structure should be moved inside ARMTargetParser
+// when we start to table-generate them, and we can use the ARM
+// flags below, that were generated by table-gen.
static const struct {
- const char *Name;
+ const unsigned Kind;
const unsigned ArchCheck;
- const uint64_t Features;
+ const FeatureBitset Features;
} Extensions[] = {
- { "crc", Feature_HasV8, ARM::FeatureCRC },
- { "crypto", Feature_HasV8,
- ARM::FeatureCrypto | ARM::FeatureNEON | ARM::FeatureFPARMv8 },
- { "fp", Feature_HasV8, ARM::FeatureFPARMv8 },
- { "idiv", Feature_HasV7 | Feature_IsNotMClass,
- ARM::FeatureHWDiv | ARM::FeatureHWDivARM },
- // FIXME: iWMMXT not supported
- { "iwmmxt", Feature_None, 0 },
- // FIXME: iWMMXT2 not supported
- { "iwmmxt2", Feature_None, 0 },
- // FIXME: Maverick not supported
- { "maverick", Feature_None, 0 },
- { "mp", Feature_HasV7 | Feature_IsNotMClass, ARM::FeatureMP },
- // FIXME: ARMv6-m OS Extensions feature not checked
- { "os", Feature_None, 0 },
- // FIXME: Also available in ARMv6-K
- { "sec", Feature_HasV7, ARM::FeatureTrustZone },
- { "simd", Feature_HasV8, ARM::FeatureNEON | ARM::FeatureFPARMv8 },
+ { ARM::AEK_CRC, Feature_HasV8, {ARM::FeatureCRC} },
+ { ARM::AEK_CRYPTO, Feature_HasV8,
+ {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8} },
+ { ARM::AEK_FP, Feature_HasV8, {ARM::FeatureFPARMv8} },
+ { (ARM::AEK_HWDIV | ARM::AEK_HWDIVARM), Feature_HasV7 | Feature_IsNotMClass,
+ {ARM::FeatureHWDiv, ARM::FeatureHWDivARM} },
+ { ARM::AEK_MP, Feature_HasV7 | Feature_IsNotMClass, {ARM::FeatureMP} },
+ { ARM::AEK_SIMD, Feature_HasV8, {ARM::FeatureNEON, ARM::FeatureFPARMv8} },
+ { ARM::AEK_SEC, Feature_HasV6K, {ARM::FeatureTrustZone} },
// FIXME: Only available in A-class, isel not predicated
- { "virt", Feature_HasV7, ARM::FeatureVirtualization },
- // FIXME: xscale not supported
- { "xscale", Feature_None, 0 },
+ { ARM::AEK_VIRT, Feature_HasV7, {ARM::FeatureVirtualization} },
+ // FIXME: Unsupported extensions.
+ { ARM::AEK_OS, Feature_None, {} },
+ { ARM::AEK_IWMMXT, Feature_None, {} },
+ { ARM::AEK_IWMMXT2, Feature_None, {} },
+ { ARM::AEK_MAVERICK, Feature_None, {} },
+ { ARM::AEK_XSCALE, Feature_None, {} },
};
/// parseDirectiveArchExtension
/// ::= .arch_extension [no]feature
bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
+ MCAsmParser &Parser = getParser();
+
if (getLexer().isNot(AsmToken::Identifier)) {
Error(getLexer().getLoc(), "unexpected token");
Parser.eatToEndOfStatement();
EnableFeature = false;
Name = Name.substr(2);
}
+ unsigned FeatureKind = ARM::parseArchExt(Name);
+ if (FeatureKind == ARM::AEK_INVALID)
+ Error(ExtLoc, "unknown architectural extension: " + Name);
for (const auto &Extension : Extensions) {
- if (Extension.Name != Name)
+ if (Extension.Kind != FeatureKind)
continue;
- if (!Extension.Features)
+ if (Extension.Features.none())
report_fatal_error("unsupported architectural extension: " + Name);
if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck) {
return false;
}
- uint64_t ToggleFeatures = EnableFeature
- ? (~STI.getFeatureBits() & Extension.Features)
- : ( STI.getFeatureBits() & Extension.Features);
+ FeatureBitset ToggleFeatures = EnableFeature
+ ? (~STI.getFeatureBits() & Extension.Features)
+ : ( STI.getFeatureBits() & Extension.Features);
+
uint64_t Features =
ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
setAvailableFeatures(Features);
if (CE->getValue() == 0)
return Match_Success;
break;
- case MCK_ARMSOImm:
+ case MCK_ModImm:
if (Op.isImm()) {
const MCExpr *SOExpr = Op.getImm();
int64_t Value;
- if (!SOExpr->EvaluateAsAbsolute(Value))
+ if (!SOExpr->evaluateAsAbsolute(Value))
return Match_Success;
assert((Value >= INT32_MIN && Value <= UINT32_MAX) &&
"expression value must be representable in 32 bits");