ARMAsmParser.cpp revision 623a454b0f5c300e69a19984d7855a1e976c3d09
1c74663799493f2b1e6123c18def94295d0afab7Kenny Root//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===// 2c74663799493f2b1e6123c18def94295d0afab7Kenny Root// 3c74663799493f2b1e6123c18def94295d0afab7Kenny Root// The LLVM Compiler Infrastructure 4c74663799493f2b1e6123c18def94295d0afab7Kenny Root// 5c74663799493f2b1e6123c18def94295d0afab7Kenny Root// This file is distributed under the University of Illinois Open Source 6c74663799493f2b1e6123c18def94295d0afab7Kenny Root// License. See LICENSE.TXT for details. 7c74663799493f2b1e6123c18def94295d0afab7Kenny Root// 8c74663799493f2b1e6123c18def94295d0afab7Kenny Root//===----------------------------------------------------------------------===// 9c74663799493f2b1e6123c18def94295d0afab7Kenny Root 10c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "MCTargetDesc/ARMBaseInfo.h" 11c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "MCTargetDesc/ARMAddressingModes.h" 12c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "MCTargetDesc/ARMMCExpr.h" 13c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/MC/MCParser/MCAsmLexer.h" 14c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/MC/MCParser/MCAsmParser.h" 15c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 16c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/MC/MCAsmInfo.h" 17c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/MC/MCContext.h" 18c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/MC/MCStreamer.h" 19c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/MC/MCExpr.h" 20c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/MC/MCInst.h" 21c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/MC/MCRegisterInfo.h" 22c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/MC/MCSubtargetInfo.h" 23c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/MC/MCTargetAsmParser.h" 24c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/Target/TargetRegistry.h" 25c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/Support/SourceMgr.h" 26c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/Support/raw_ostream.h" 27c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/ADT/OwningPtr.h" 28c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/ADT/STLExtras.h" 29c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/ADT/SmallVector.h" 30c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/ADT/StringExtras.h" 31c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/ADT/StringSwitch.h" 32c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "llvm/ADT/Twine.h" 33c74663799493f2b1e6123c18def94295d0afab7Kenny Root 34c74663799493f2b1e6123c18def94295d0afab7Kenny Rootusing namespace llvm; 35c74663799493f2b1e6123c18def94295d0afab7Kenny Root 36c74663799493f2b1e6123c18def94295d0afab7Kenny Rootnamespace { 37c74663799493f2b1e6123c18def94295d0afab7Kenny Root 38c74663799493f2b1e6123c18def94295d0afab7Kenny Rootclass ARMOperand; 39c74663799493f2b1e6123c18def94295d0afab7Kenny Root 40c74663799493f2b1e6123c18def94295d0afab7Kenny Rootclass ARMAsmParser : public MCTargetAsmParser { 41c74663799493f2b1e6123c18def94295d0afab7Kenny Root MCSubtargetInfo &STI; 42c74663799493f2b1e6123c18def94295d0afab7Kenny Root MCAsmParser &Parser; 43c74663799493f2b1e6123c18def94295d0afab7Kenny Root 44c74663799493f2b1e6123c18def94295d0afab7Kenny Root MCAsmParser &getParser() const { return Parser; } 45c74663799493f2b1e6123c18def94295d0afab7Kenny Root MCAsmLexer &getLexer() const { return Parser.getLexer(); } 46c74663799493f2b1e6123c18def94295d0afab7Kenny Root 47c74663799493f2b1e6123c18def94295d0afab7Kenny Root void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 48c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 49c74663799493f2b1e6123c18def94295d0afab7Kenny Root 50c74663799493f2b1e6123c18def94295d0afab7Kenny Root int tryParseRegister(); 51c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 52c74663799493f2b1e6123c18def94295d0afab7Kenny Root int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 53c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 54c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 55c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 56c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 57c74663799493f2b1e6123c18def94295d0afab7Kenny Root const MCExpr *applyPrefixToExpr(const MCExpr *E, 58c74663799493f2b1e6123c18def94295d0afab7Kenny Root MCSymbolRefExpr::VariantKind Variant); 59c74663799493f2b1e6123c18def94295d0afab7Kenny Root 60c74663799493f2b1e6123c18def94295d0afab7Kenny Root 61c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 62c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned &ShiftAmount); 63c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool parseDirectiveWord(unsigned Size, SMLoc L); 64c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool parseDirectiveThumb(SMLoc L); 65c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool parseDirectiveThumbFunc(SMLoc L); 66c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool parseDirectiveCode(SMLoc L); 67c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool parseDirectiveSyntax(SMLoc L); 68c74663799493f2b1e6123c18def94295d0afab7Kenny Root 69c74663799493f2b1e6123c18def94295d0afab7Kenny Root StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 70c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool &CarrySetting, unsigned &ProcessorIMod); 71c74663799493f2b1e6123c18def94295d0afab7Kenny Root void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 72c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool &CanAcceptPredicationCode); 73c74663799493f2b1e6123c18def94295d0afab7Kenny Root 74c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool isThumb() const { 75c74663799493f2b1e6123c18def94295d0afab7Kenny Root // FIXME: Can tablegen auto-generate this? 76c74663799493f2b1e6123c18def94295d0afab7Kenny Root return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 77c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 78c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool isThumbOne() const { 79c74663799493f2b1e6123c18def94295d0afab7Kenny Root return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 80c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 81c74663799493f2b1e6123c18def94295d0afab7Kenny Root void SwitchMode() { 82c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 83c74663799493f2b1e6123c18def94295d0afab7Kenny Root setAvailableFeatures(FB); 84c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 85c74663799493f2b1e6123c18def94295d0afab7Kenny Root 86c74663799493f2b1e6123c18def94295d0afab7Kenny Root /// @name Auto-generated Match Functions 87c74663799493f2b1e6123c18def94295d0afab7Kenny Root /// { 88c74663799493f2b1e6123c18def94295d0afab7Kenny Root 89c74663799493f2b1e6123c18def94295d0afab7Kenny Root#define GET_ASSEMBLER_HEADER 90c74663799493f2b1e6123c18def94295d0afab7Kenny Root#include "ARMGenAsmMatcher.inc" 91c74663799493f2b1e6123c18def94295d0afab7Kenny Root 92c74663799493f2b1e6123c18def94295d0afab7Kenny Root /// } 93c74663799493f2b1e6123c18def94295d0afab7Kenny Root 94c74663799493f2b1e6123c18def94295d0afab7Kenny Root OperandMatchResultTy parseCoprocNumOperand( 95c74663799493f2b1e6123c18def94295d0afab7Kenny Root SmallVectorImpl<MCParsedAsmOperand*>&); 96c74663799493f2b1e6123c18def94295d0afab7Kenny Root OperandMatchResultTy parseCoprocRegOperand( 97c74663799493f2b1e6123c18def94295d0afab7Kenny Root SmallVectorImpl<MCParsedAsmOperand*>&); 98c74663799493f2b1e6123c18def94295d0afab7Kenny Root OperandMatchResultTy parseMemBarrierOptOperand( 99c74663799493f2b1e6123c18def94295d0afab7Kenny Root SmallVectorImpl<MCParsedAsmOperand*>&); 100c74663799493f2b1e6123c18def94295d0afab7Kenny Root OperandMatchResultTy parseProcIFlagsOperand( 101c74663799493f2b1e6123c18def94295d0afab7Kenny Root SmallVectorImpl<MCParsedAsmOperand*>&); 102c74663799493f2b1e6123c18def94295d0afab7Kenny Root OperandMatchResultTy parseMSRMaskOperand( 103c74663799493f2b1e6123c18def94295d0afab7Kenny Root SmallVectorImpl<MCParsedAsmOperand*>&); 104c74663799493f2b1e6123c18def94295d0afab7Kenny Root OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 105c74663799493f2b1e6123c18def94295d0afab7Kenny Root StringRef Op, int Low, int High); 106c74663799493f2b1e6123c18def94295d0afab7Kenny Root OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 107c74663799493f2b1e6123c18def94295d0afab7Kenny Root return parsePKHImm(O, "lsl", 0, 31); 108c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 109c74663799493f2b1e6123c18def94295d0afab7Kenny Root OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 110c74663799493f2b1e6123c18def94295d0afab7Kenny Root return parsePKHImm(O, "asr", 1, 32); 111c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 112c74663799493f2b1e6123c18def94295d0afab7Kenny Root OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 113c74663799493f2b1e6123c18def94295d0afab7Kenny Root OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 114c74663799493f2b1e6123c18def94295d0afab7Kenny Root OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 115c74663799493f2b1e6123c18def94295d0afab7Kenny Root OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 116c74663799493f2b1e6123c18def94295d0afab7Kenny Root OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 117c74663799493f2b1e6123c18def94295d0afab7Kenny Root OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 118c74663799493f2b1e6123c18def94295d0afab7Kenny Root 119c74663799493f2b1e6123c18def94295d0afab7Kenny Root // Asm Match Converter Methods 120c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 121c74663799493f2b1e6123c18def94295d0afab7Kenny Root const SmallVectorImpl<MCParsedAsmOperand*> &); 122c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 123c74663799493f2b1e6123c18def94295d0afab7Kenny Root const SmallVectorImpl<MCParsedAsmOperand*> &); 124c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 125c74663799493f2b1e6123c18def94295d0afab7Kenny Root const SmallVectorImpl<MCParsedAsmOperand*> &); 126c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 127c74663799493f2b1e6123c18def94295d0afab7Kenny Root const SmallVectorImpl<MCParsedAsmOperand*> &); 128c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 129c74663799493f2b1e6123c18def94295d0afab7Kenny Root const SmallVectorImpl<MCParsedAsmOperand*> &); 130c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 131c74663799493f2b1e6123c18def94295d0afab7Kenny Root const SmallVectorImpl<MCParsedAsmOperand*> &); 132c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, 133c74663799493f2b1e6123c18def94295d0afab7Kenny Root const SmallVectorImpl<MCParsedAsmOperand*> &); 134c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 135c74663799493f2b1e6123c18def94295d0afab7Kenny Root const SmallVectorImpl<MCParsedAsmOperand*> &); 136c74663799493f2b1e6123c18def94295d0afab7Kenny Root 137c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool validateInstruction(MCInst &Inst, 138c74663799493f2b1e6123c18def94295d0afab7Kenny Root const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 139c74663799493f2b1e6123c18def94295d0afab7Kenny Root 140c74663799493f2b1e6123c18def94295d0afab7Kenny Rootpublic: 141c74663799493f2b1e6123c18def94295d0afab7Kenny Root ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 142c74663799493f2b1e6123c18def94295d0afab7Kenny Root : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 143c74663799493f2b1e6123c18def94295d0afab7Kenny Root MCAsmParserExtension::Initialize(_Parser); 144c74663799493f2b1e6123c18def94295d0afab7Kenny Root 145c74663799493f2b1e6123c18def94295d0afab7Kenny Root // Initialize the set of available features. 146c74663799493f2b1e6123c18def94295d0afab7Kenny Root setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 147c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 148c74663799493f2b1e6123c18def94295d0afab7Kenny Root 149c74663799493f2b1e6123c18def94295d0afab7Kenny Root // Implementation of the MCTargetAsmParser interface: 150c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 151c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool ParseInstruction(StringRef Name, SMLoc NameLoc, 152c74663799493f2b1e6123c18def94295d0afab7Kenny Root SmallVectorImpl<MCParsedAsmOperand*> &Operands); 153c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool ParseDirective(AsmToken DirectiveID); 154c74663799493f2b1e6123c18def94295d0afab7Kenny Root 155c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool MatchAndEmitInstruction(SMLoc IDLoc, 156c74663799493f2b1e6123c18def94295d0afab7Kenny Root SmallVectorImpl<MCParsedAsmOperand*> &Operands, 157c74663799493f2b1e6123c18def94295d0afab7Kenny Root MCStreamer &Out); 158c74663799493f2b1e6123c18def94295d0afab7Kenny Root}; 159c74663799493f2b1e6123c18def94295d0afab7Kenny Root} // end anonymous namespace 160c74663799493f2b1e6123c18def94295d0afab7Kenny Root 161c74663799493f2b1e6123c18def94295d0afab7Kenny Rootnamespace { 162c74663799493f2b1e6123c18def94295d0afab7Kenny Root 163c74663799493f2b1e6123c18def94295d0afab7Kenny Root/// ARMOperand - Instances of this class represent a parsed ARM machine 164c74663799493f2b1e6123c18def94295d0afab7Kenny Root/// instruction. 165c74663799493f2b1e6123c18def94295d0afab7Kenny Rootclass ARMOperand : public MCParsedAsmOperand { 166c74663799493f2b1e6123c18def94295d0afab7Kenny Root enum KindTy { 167c74663799493f2b1e6123c18def94295d0afab7Kenny Root CondCode, 168c74663799493f2b1e6123c18def94295d0afab7Kenny Root CCOut, 169c74663799493f2b1e6123c18def94295d0afab7Kenny Root CoprocNum, 170c74663799493f2b1e6123c18def94295d0afab7Kenny Root CoprocReg, 171c74663799493f2b1e6123c18def94295d0afab7Kenny Root Immediate, 172c74663799493f2b1e6123c18def94295d0afab7Kenny Root MemBarrierOpt, 173c74663799493f2b1e6123c18def94295d0afab7Kenny Root Memory, 174c74663799493f2b1e6123c18def94295d0afab7Kenny Root PostIndexRegister, 175c74663799493f2b1e6123c18def94295d0afab7Kenny Root MSRMask, 176c74663799493f2b1e6123c18def94295d0afab7Kenny Root ProcIFlags, 177c74663799493f2b1e6123c18def94295d0afab7Kenny Root Register, 178c74663799493f2b1e6123c18def94295d0afab7Kenny Root RegisterList, 179c74663799493f2b1e6123c18def94295d0afab7Kenny Root DPRRegisterList, 180c74663799493f2b1e6123c18def94295d0afab7Kenny Root SPRRegisterList, 181c74663799493f2b1e6123c18def94295d0afab7Kenny Root ShiftedRegister, 182c74663799493f2b1e6123c18def94295d0afab7Kenny Root ShiftedImmediate, 183c74663799493f2b1e6123c18def94295d0afab7Kenny Root ShifterImmediate, 184c74663799493f2b1e6123c18def94295d0afab7Kenny Root RotateImmediate, 185c74663799493f2b1e6123c18def94295d0afab7Kenny Root BitfieldDescriptor, 186c74663799493f2b1e6123c18def94295d0afab7Kenny Root Token 187c74663799493f2b1e6123c18def94295d0afab7Kenny Root } Kind; 188c74663799493f2b1e6123c18def94295d0afab7Kenny Root 189c74663799493f2b1e6123c18def94295d0afab7Kenny Root SMLoc StartLoc, EndLoc; 190c74663799493f2b1e6123c18def94295d0afab7Kenny Root SmallVector<unsigned, 8> Registers; 191c74663799493f2b1e6123c18def94295d0afab7Kenny Root 192c74663799493f2b1e6123c18def94295d0afab7Kenny Root union { 193c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 194c74663799493f2b1e6123c18def94295d0afab7Kenny Root ARMCC::CondCodes Val; 195c74663799493f2b1e6123c18def94295d0afab7Kenny Root } CC; 196c74663799493f2b1e6123c18def94295d0afab7Kenny Root 197c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 198c74663799493f2b1e6123c18def94295d0afab7Kenny Root ARM_MB::MemBOpt Val; 199c74663799493f2b1e6123c18def94295d0afab7Kenny Root } MBOpt; 200c74663799493f2b1e6123c18def94295d0afab7Kenny Root 201c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 202c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned Val; 203c74663799493f2b1e6123c18def94295d0afab7Kenny Root } Cop; 204c74663799493f2b1e6123c18def94295d0afab7Kenny Root 205c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 206c74663799493f2b1e6123c18def94295d0afab7Kenny Root ARM_PROC::IFlags Val; 207c74663799493f2b1e6123c18def94295d0afab7Kenny Root } IFlags; 208c74663799493f2b1e6123c18def94295d0afab7Kenny Root 209c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 210c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned Val; 211c74663799493f2b1e6123c18def94295d0afab7Kenny Root } MMask; 212c74663799493f2b1e6123c18def94295d0afab7Kenny Root 213c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 214c74663799493f2b1e6123c18def94295d0afab7Kenny Root const char *Data; 215c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned Length; 216c74663799493f2b1e6123c18def94295d0afab7Kenny Root } Tok; 217c74663799493f2b1e6123c18def94295d0afab7Kenny Root 218c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 219c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned RegNum; 220c74663799493f2b1e6123c18def94295d0afab7Kenny Root } Reg; 221c74663799493f2b1e6123c18def94295d0afab7Kenny Root 222c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 223c74663799493f2b1e6123c18def94295d0afab7Kenny Root const MCExpr *Val; 224c74663799493f2b1e6123c18def94295d0afab7Kenny Root } Imm; 225c74663799493f2b1e6123c18def94295d0afab7Kenny Root 226c74663799493f2b1e6123c18def94295d0afab7Kenny Root /// Combined record for all forms of ARM address expressions. 227c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 228c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned BaseRegNum; 229c74663799493f2b1e6123c18def94295d0afab7Kenny Root // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 230c74663799493f2b1e6123c18def94295d0afab7Kenny Root // was specified. 231c74663799493f2b1e6123c18def94295d0afab7Kenny Root const MCConstantExpr *OffsetImm; // Offset immediate value 232c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 233c74663799493f2b1e6123c18def94295d0afab7Kenny Root ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 234c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned ShiftImm; // shift for OffsetReg. 235c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 236c74663799493f2b1e6123c18def94295d0afab7Kenny Root } Mem; 237c74663799493f2b1e6123c18def94295d0afab7Kenny Root 238c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 239c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned RegNum; 240c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool isAdd; 241c74663799493f2b1e6123c18def94295d0afab7Kenny Root ARM_AM::ShiftOpc ShiftTy; 242c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned ShiftImm; 243c74663799493f2b1e6123c18def94295d0afab7Kenny Root } PostIdxReg; 244c74663799493f2b1e6123c18def94295d0afab7Kenny Root 245c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 246c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool isASR; 247c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned Imm; 248c74663799493f2b1e6123c18def94295d0afab7Kenny Root } ShifterImm; 249c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 250c74663799493f2b1e6123c18def94295d0afab7Kenny Root ARM_AM::ShiftOpc ShiftTy; 251c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned SrcReg; 252c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned ShiftReg; 253c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned ShiftImm; 254c74663799493f2b1e6123c18def94295d0afab7Kenny Root } RegShiftedReg; 255c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 256c74663799493f2b1e6123c18def94295d0afab7Kenny Root ARM_AM::ShiftOpc ShiftTy; 257c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned SrcReg; 258c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned ShiftImm; 259c74663799493f2b1e6123c18def94295d0afab7Kenny Root } RegShiftedImm; 260c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 261c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned Imm; 262c74663799493f2b1e6123c18def94295d0afab7Kenny Root } RotImm; 263c74663799493f2b1e6123c18def94295d0afab7Kenny Root struct { 264c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned LSB; 265c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned Width; 266c74663799493f2b1e6123c18def94295d0afab7Kenny Root } Bitfield; 267c74663799493f2b1e6123c18def94295d0afab7Kenny Root }; 268c74663799493f2b1e6123c18def94295d0afab7Kenny Root 269c74663799493f2b1e6123c18def94295d0afab7Kenny Root ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 270c74663799493f2b1e6123c18def94295d0afab7Kenny Rootpublic: 271c74663799493f2b1e6123c18def94295d0afab7Kenny Root ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 272c74663799493f2b1e6123c18def94295d0afab7Kenny Root Kind = o.Kind; 273c74663799493f2b1e6123c18def94295d0afab7Kenny Root StartLoc = o.StartLoc; 274c74663799493f2b1e6123c18def94295d0afab7Kenny Root EndLoc = o.EndLoc; 275c74663799493f2b1e6123c18def94295d0afab7Kenny Root switch (Kind) { 276c74663799493f2b1e6123c18def94295d0afab7Kenny Root case CondCode: 277c74663799493f2b1e6123c18def94295d0afab7Kenny Root CC = o.CC; 278c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 279c74663799493f2b1e6123c18def94295d0afab7Kenny Root case Token: 280c74663799493f2b1e6123c18def94295d0afab7Kenny Root Tok = o.Tok; 281c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 282c74663799493f2b1e6123c18def94295d0afab7Kenny Root case CCOut: 283c74663799493f2b1e6123c18def94295d0afab7Kenny Root case Register: 284c74663799493f2b1e6123c18def94295d0afab7Kenny Root Reg = o.Reg; 285c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 286c74663799493f2b1e6123c18def94295d0afab7Kenny Root case RegisterList: 287c74663799493f2b1e6123c18def94295d0afab7Kenny Root case DPRRegisterList: 288c74663799493f2b1e6123c18def94295d0afab7Kenny Root case SPRRegisterList: 289c74663799493f2b1e6123c18def94295d0afab7Kenny Root Registers = o.Registers; 290c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 291c74663799493f2b1e6123c18def94295d0afab7Kenny Root case CoprocNum: 292c74663799493f2b1e6123c18def94295d0afab7Kenny Root case CoprocReg: 293c74663799493f2b1e6123c18def94295d0afab7Kenny Root Cop = o.Cop; 294c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 295c74663799493f2b1e6123c18def94295d0afab7Kenny Root case Immediate: 296c74663799493f2b1e6123c18def94295d0afab7Kenny Root Imm = o.Imm; 297c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 298c74663799493f2b1e6123c18def94295d0afab7Kenny Root case MemBarrierOpt: 299c74663799493f2b1e6123c18def94295d0afab7Kenny Root MBOpt = o.MBOpt; 300c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 301c74663799493f2b1e6123c18def94295d0afab7Kenny Root case Memory: 302c74663799493f2b1e6123c18def94295d0afab7Kenny Root Mem = o.Mem; 303c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 304c74663799493f2b1e6123c18def94295d0afab7Kenny Root case PostIndexRegister: 305c74663799493f2b1e6123c18def94295d0afab7Kenny Root PostIdxReg = o.PostIdxReg; 306c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 307c74663799493f2b1e6123c18def94295d0afab7Kenny Root case MSRMask: 308c74663799493f2b1e6123c18def94295d0afab7Kenny Root MMask = o.MMask; 309c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 310c74663799493f2b1e6123c18def94295d0afab7Kenny Root case ProcIFlags: 311c74663799493f2b1e6123c18def94295d0afab7Kenny Root IFlags = o.IFlags; 312c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 313c74663799493f2b1e6123c18def94295d0afab7Kenny Root case ShifterImmediate: 314c74663799493f2b1e6123c18def94295d0afab7Kenny Root ShifterImm = o.ShifterImm; 315c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 316c74663799493f2b1e6123c18def94295d0afab7Kenny Root case ShiftedRegister: 317c74663799493f2b1e6123c18def94295d0afab7Kenny Root RegShiftedReg = o.RegShiftedReg; 318c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 319c74663799493f2b1e6123c18def94295d0afab7Kenny Root case ShiftedImmediate: 320c74663799493f2b1e6123c18def94295d0afab7Kenny Root RegShiftedImm = o.RegShiftedImm; 321c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 322c74663799493f2b1e6123c18def94295d0afab7Kenny Root case RotateImmediate: 323c74663799493f2b1e6123c18def94295d0afab7Kenny Root RotImm = o.RotImm; 324c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 325c74663799493f2b1e6123c18def94295d0afab7Kenny Root case BitfieldDescriptor: 326c74663799493f2b1e6123c18def94295d0afab7Kenny Root Bitfield = o.Bitfield; 327c74663799493f2b1e6123c18def94295d0afab7Kenny Root break; 328c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 329c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 330c74663799493f2b1e6123c18def94295d0afab7Kenny Root 331c74663799493f2b1e6123c18def94295d0afab7Kenny Root /// getStartLoc - Get the location of the first token of this operand. 332c74663799493f2b1e6123c18def94295d0afab7Kenny Root SMLoc getStartLoc() const { return StartLoc; } 333c74663799493f2b1e6123c18def94295d0afab7Kenny Root /// getEndLoc - Get the location of the last token of this operand. 334c74663799493f2b1e6123c18def94295d0afab7Kenny Root SMLoc getEndLoc() const { return EndLoc; } 335c74663799493f2b1e6123c18def94295d0afab7Kenny Root 336c74663799493f2b1e6123c18def94295d0afab7Kenny Root ARMCC::CondCodes getCondCode() const { 337c74663799493f2b1e6123c18def94295d0afab7Kenny Root assert(Kind == CondCode && "Invalid access!"); 338c74663799493f2b1e6123c18def94295d0afab7Kenny Root return CC.Val; 339c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 340c74663799493f2b1e6123c18def94295d0afab7Kenny Root 341c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned getCoproc() const { 342c74663799493f2b1e6123c18def94295d0afab7Kenny Root assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 343c74663799493f2b1e6123c18def94295d0afab7Kenny Root return Cop.Val; 344c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 345c74663799493f2b1e6123c18def94295d0afab7Kenny Root 346c74663799493f2b1e6123c18def94295d0afab7Kenny Root StringRef getToken() const { 347c74663799493f2b1e6123c18def94295d0afab7Kenny Root assert(Kind == Token && "Invalid access!"); 348c74663799493f2b1e6123c18def94295d0afab7Kenny Root return StringRef(Tok.Data, Tok.Length); 349c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 350c74663799493f2b1e6123c18def94295d0afab7Kenny Root 351c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned getReg() const { 352c74663799493f2b1e6123c18def94295d0afab7Kenny Root assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 353c74663799493f2b1e6123c18def94295d0afab7Kenny Root return Reg.RegNum; 354c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 355c74663799493f2b1e6123c18def94295d0afab7Kenny Root 356c74663799493f2b1e6123c18def94295d0afab7Kenny Root const SmallVectorImpl<unsigned> &getRegList() const { 357c74663799493f2b1e6123c18def94295d0afab7Kenny Root assert((Kind == RegisterList || Kind == DPRRegisterList || 358c74663799493f2b1e6123c18def94295d0afab7Kenny Root Kind == SPRRegisterList) && "Invalid access!"); 359c74663799493f2b1e6123c18def94295d0afab7Kenny Root return Registers; 360c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 361c74663799493f2b1e6123c18def94295d0afab7Kenny Root 362c74663799493f2b1e6123c18def94295d0afab7Kenny Root const MCExpr *getImm() const { 363c74663799493f2b1e6123c18def94295d0afab7Kenny Root assert(Kind == Immediate && "Invalid access!"); 364c74663799493f2b1e6123c18def94295d0afab7Kenny Root return Imm.Val; 365c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 366c74663799493f2b1e6123c18def94295d0afab7Kenny Root 367c74663799493f2b1e6123c18def94295d0afab7Kenny Root ARM_MB::MemBOpt getMemBarrierOpt() const { 368c74663799493f2b1e6123c18def94295d0afab7Kenny Root assert(Kind == MemBarrierOpt && "Invalid access!"); 369c74663799493f2b1e6123c18def94295d0afab7Kenny Root return MBOpt.Val; 370c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 371c74663799493f2b1e6123c18def94295d0afab7Kenny Root 372c74663799493f2b1e6123c18def94295d0afab7Kenny Root ARM_PROC::IFlags getProcIFlags() const { 373c74663799493f2b1e6123c18def94295d0afab7Kenny Root assert(Kind == ProcIFlags && "Invalid access!"); 374c74663799493f2b1e6123c18def94295d0afab7Kenny Root return IFlags.Val; 375c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 376c74663799493f2b1e6123c18def94295d0afab7Kenny Root 377c74663799493f2b1e6123c18def94295d0afab7Kenny Root unsigned getMSRMask() const { 378c74663799493f2b1e6123c18def94295d0afab7Kenny Root assert(Kind == MSRMask && "Invalid access!"); 379c74663799493f2b1e6123c18def94295d0afab7Kenny Root return MMask.Val; 380c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 381c74663799493f2b1e6123c18def94295d0afab7Kenny Root 382c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool isCoprocNum() const { return Kind == CoprocNum; } 383c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool isCoprocReg() const { return Kind == CoprocReg; } 384c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool isCondCode() const { return Kind == CondCode; } 385c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool isCCOut() const { return Kind == CCOut; } 386c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool isImm() const { return Kind == Immediate; } 387c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool isImm0_255() const { 388c74663799493f2b1e6123c18def94295d0afab7Kenny Root if (Kind != Immediate) 389c74663799493f2b1e6123c18def94295d0afab7Kenny Root return false; 390c74663799493f2b1e6123c18def94295d0afab7Kenny Root const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 391c74663799493f2b1e6123c18def94295d0afab7Kenny Root if (!CE) return false; 392c74663799493f2b1e6123c18def94295d0afab7Kenny Root int64_t Value = CE->getValue(); 393c74663799493f2b1e6123c18def94295d0afab7Kenny Root return Value >= 0 && Value < 256; 394c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 395c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool isImm0_7() const { 396c74663799493f2b1e6123c18def94295d0afab7Kenny Root if (Kind != Immediate) 397c74663799493f2b1e6123c18def94295d0afab7Kenny Root return false; 398c74663799493f2b1e6123c18def94295d0afab7Kenny Root const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 399c74663799493f2b1e6123c18def94295d0afab7Kenny Root if (!CE) return false; 400c74663799493f2b1e6123c18def94295d0afab7Kenny Root int64_t Value = CE->getValue(); 401c74663799493f2b1e6123c18def94295d0afab7Kenny Root return Value >= 0 && Value < 8; 402c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 403c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool isImm0_15() const { 404c74663799493f2b1e6123c18def94295d0afab7Kenny Root if (Kind != Immediate) 405c74663799493f2b1e6123c18def94295d0afab7Kenny Root return false; 406c74663799493f2b1e6123c18def94295d0afab7Kenny Root const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 407c74663799493f2b1e6123c18def94295d0afab7Kenny Root if (!CE) return false; 408c74663799493f2b1e6123c18def94295d0afab7Kenny Root int64_t Value = CE->getValue(); 409c74663799493f2b1e6123c18def94295d0afab7Kenny Root return Value >= 0 && Value < 16; 410c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 411c74663799493f2b1e6123c18def94295d0afab7Kenny Root bool isImm0_31() const { 412c74663799493f2b1e6123c18def94295d0afab7Kenny Root if (Kind != Immediate) 413c74663799493f2b1e6123c18def94295d0afab7Kenny Root return false; 414c74663799493f2b1e6123c18def94295d0afab7Kenny Root const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 415c74663799493f2b1e6123c18def94295d0afab7Kenny Root if (!CE) return false; 416c74663799493f2b1e6123c18def94295d0afab7Kenny Root int64_t Value = CE->getValue(); 417c74663799493f2b1e6123c18def94295d0afab7Kenny Root return Value >= 0 && Value < 32; 418c74663799493f2b1e6123c18def94295d0afab7Kenny Root } 419 bool isImm1_16() const { 420 if (Kind != Immediate) 421 return false; 422 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 423 if (!CE) return false; 424 int64_t Value = CE->getValue(); 425 return Value > 0 && Value < 17; 426 } 427 bool isImm1_32() const { 428 if (Kind != Immediate) 429 return false; 430 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 431 if (!CE) return false; 432 int64_t Value = CE->getValue(); 433 return Value > 0 && Value < 33; 434 } 435 bool isImm0_65535() const { 436 if (Kind != Immediate) 437 return false; 438 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 439 if (!CE) return false; 440 int64_t Value = CE->getValue(); 441 return Value >= 0 && Value < 65536; 442 } 443 bool isImm0_65535Expr() const { 444 if (Kind != Immediate) 445 return false; 446 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 447 // If it's not a constant expression, it'll generate a fixup and be 448 // handled later. 449 if (!CE) return true; 450 int64_t Value = CE->getValue(); 451 return Value >= 0 && Value < 65536; 452 } 453 bool isImm24bit() const { 454 if (Kind != Immediate) 455 return false; 456 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 457 if (!CE) return false; 458 int64_t Value = CE->getValue(); 459 return Value >= 0 && Value <= 0xffffff; 460 } 461 bool isPKHLSLImm() const { 462 if (Kind != Immediate) 463 return false; 464 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 465 if (!CE) return false; 466 int64_t Value = CE->getValue(); 467 return Value >= 0 && Value < 32; 468 } 469 bool isPKHASRImm() const { 470 if (Kind != Immediate) 471 return false; 472 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 473 if (!CE) return false; 474 int64_t Value = CE->getValue(); 475 return Value > 0 && Value <= 32; 476 } 477 bool isARMSOImm() const { 478 if (Kind != Immediate) 479 return false; 480 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 481 if (!CE) return false; 482 int64_t Value = CE->getValue(); 483 return ARM_AM::getSOImmVal(Value) != -1; 484 } 485 bool isT2SOImm() const { 486 if (Kind != Immediate) 487 return false; 488 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 489 if (!CE) return false; 490 int64_t Value = CE->getValue(); 491 return ARM_AM::getT2SOImmVal(Value) != -1; 492 } 493 bool isSetEndImm() const { 494 if (Kind != Immediate) 495 return false; 496 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 497 if (!CE) return false; 498 int64_t Value = CE->getValue(); 499 return Value == 1 || Value == 0; 500 } 501 bool isReg() const { return Kind == Register; } 502 bool isRegList() const { return Kind == RegisterList; } 503 bool isDPRRegList() const { return Kind == DPRRegisterList; } 504 bool isSPRRegList() const { return Kind == SPRRegisterList; } 505 bool isToken() const { return Kind == Token; } 506 bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 507 bool isMemory() const { return Kind == Memory; } 508 bool isShifterImm() const { return Kind == ShifterImmediate; } 509 bool isRegShiftedReg() const { return Kind == ShiftedRegister; } 510 bool isRegShiftedImm() const { return Kind == ShiftedImmediate; } 511 bool isRotImm() const { return Kind == RotateImmediate; } 512 bool isBitfield() const { return Kind == BitfieldDescriptor; } 513 bool isPostIdxRegShifted() const { return Kind == PostIndexRegister; } 514 bool isPostIdxReg() const { 515 return Kind == PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift; 516 } 517 bool isMemNoOffset() const { 518 if (Kind != Memory) 519 return false; 520 // No offset of any kind. 521 return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0; 522 } 523 bool isAddrMode2() const { 524 if (Kind != Memory) 525 return false; 526 // Check for register offset. 527 if (Mem.OffsetRegNum) return true; 528 // Immediate offset in range [-4095, 4095]. 529 if (!Mem.OffsetImm) return true; 530 int64_t Val = Mem.OffsetImm->getValue(); 531 return Val > -4096 && Val < 4096; 532 } 533 bool isAM2OffsetImm() const { 534 if (Kind != Immediate) 535 return false; 536 // Immediate offset in range [-4095, 4095]. 537 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 538 if (!CE) return false; 539 int64_t Val = CE->getValue(); 540 return Val > -4096 && Val < 4096; 541 } 542 bool isAddrMode3() const { 543 if (Kind != Memory) 544 return false; 545 // No shifts are legal for AM3. 546 if (Mem.ShiftType != ARM_AM::no_shift) return false; 547 // Check for register offset. 548 if (Mem.OffsetRegNum) return true; 549 // Immediate offset in range [-255, 255]. 550 if (!Mem.OffsetImm) return true; 551 int64_t Val = Mem.OffsetImm->getValue(); 552 return Val > -256 && Val < 256; 553 } 554 bool isAM3Offset() const { 555 if (Kind != Immediate && Kind != PostIndexRegister) 556 return false; 557 if (Kind == PostIndexRegister) 558 return PostIdxReg.ShiftTy == ARM_AM::no_shift; 559 // Immediate offset in range [-255, 255]. 560 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 561 if (!CE) return false; 562 int64_t Val = CE->getValue(); 563 // Special case, #-0 is INT32_MIN. 564 return (Val > -256 && Val < 256) || Val == INT32_MIN; 565 } 566 bool isAddrMode5() const { 567 if (Kind != Memory) 568 return false; 569 // Check for register offset. 570 if (Mem.OffsetRegNum) return false; 571 // Immediate offset in range [-1020, 1020] and a multiple of 4. 572 if (!Mem.OffsetImm) return true; 573 int64_t Val = Mem.OffsetImm->getValue(); 574 return Val >= -1020 && Val <= 1020 && ((Val & 3) == 0); 575 } 576 bool isMemRegOffset() const { 577 if (Kind != Memory || !Mem.OffsetRegNum) 578 return false; 579 return true; 580 } 581 bool isMemThumbRR() const { 582 // Thumb reg+reg addressing is simple. Just two registers, a base and 583 // an offset. No shifts, negations or any other complicating factors. 584 if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative || 585 Mem.ShiftType != ARM_AM::no_shift) 586 return false; 587 return true; 588 } 589 bool isMemImm8Offset() const { 590 if (Kind != Memory || Mem.OffsetRegNum != 0) 591 return false; 592 // Immediate offset in range [-255, 255]. 593 if (!Mem.OffsetImm) return true; 594 int64_t Val = Mem.OffsetImm->getValue(); 595 return Val > -256 && Val < 256; 596 } 597 bool isMemImm12Offset() const { 598 // If we have an immediate that's not a constant, treat it as a label 599 // reference needing a fixup. If it is a constant, it's something else 600 // and we reject it. 601 if (Kind == Immediate && !isa<MCConstantExpr>(getImm())) 602 return true; 603 604 if (Kind != Memory || Mem.OffsetRegNum != 0) 605 return false; 606 // Immediate offset in range [-4095, 4095]. 607 if (!Mem.OffsetImm) return true; 608 int64_t Val = Mem.OffsetImm->getValue(); 609 return Val > -4096 && Val < 4096; 610 } 611 bool isPostIdxImm8() const { 612 if (Kind != Immediate) 613 return false; 614 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 615 if (!CE) return false; 616 int64_t Val = CE->getValue(); 617 return Val > -256 && Val < 256; 618 } 619 620 bool isMSRMask() const { return Kind == MSRMask; } 621 bool isProcIFlags() const { return Kind == ProcIFlags; } 622 623 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 624 // Add as immediates when possible. Null MCExpr = 0. 625 if (Expr == 0) 626 Inst.addOperand(MCOperand::CreateImm(0)); 627 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 628 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 629 else 630 Inst.addOperand(MCOperand::CreateExpr(Expr)); 631 } 632 633 void addCondCodeOperands(MCInst &Inst, unsigned N) const { 634 assert(N == 2 && "Invalid number of operands!"); 635 Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 636 unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 637 Inst.addOperand(MCOperand::CreateReg(RegNum)); 638 } 639 640 void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 641 assert(N == 1 && "Invalid number of operands!"); 642 Inst.addOperand(MCOperand::CreateImm(getCoproc())); 643 } 644 645 void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 646 assert(N == 1 && "Invalid number of operands!"); 647 Inst.addOperand(MCOperand::CreateImm(getCoproc())); 648 } 649 650 void addCCOutOperands(MCInst &Inst, unsigned N) const { 651 assert(N == 1 && "Invalid number of operands!"); 652 Inst.addOperand(MCOperand::CreateReg(getReg())); 653 } 654 655 void addRegOperands(MCInst &Inst, unsigned N) const { 656 assert(N == 1 && "Invalid number of operands!"); 657 Inst.addOperand(MCOperand::CreateReg(getReg())); 658 } 659 660 void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 661 assert(N == 3 && "Invalid number of operands!"); 662 assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 663 Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 664 Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 665 Inst.addOperand(MCOperand::CreateImm( 666 ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 667 } 668 669 void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 670 assert(N == 2 && "Invalid number of operands!"); 671 assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 672 Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 673 Inst.addOperand(MCOperand::CreateImm( 674 ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 675 } 676 677 678 void addShifterImmOperands(MCInst &Inst, unsigned N) const { 679 assert(N == 1 && "Invalid number of operands!"); 680 Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 681 ShifterImm.Imm)); 682 } 683 684 void addRegListOperands(MCInst &Inst, unsigned N) const { 685 assert(N == 1 && "Invalid number of operands!"); 686 const SmallVectorImpl<unsigned> &RegList = getRegList(); 687 for (SmallVectorImpl<unsigned>::const_iterator 688 I = RegList.begin(), E = RegList.end(); I != E; ++I) 689 Inst.addOperand(MCOperand::CreateReg(*I)); 690 } 691 692 void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 693 addRegListOperands(Inst, N); 694 } 695 696 void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 697 addRegListOperands(Inst, N); 698 } 699 700 void addRotImmOperands(MCInst &Inst, unsigned N) const { 701 assert(N == 1 && "Invalid number of operands!"); 702 // Encoded as val>>3. The printer handles display as 8, 16, 24. 703 Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 704 } 705 706 void addBitfieldOperands(MCInst &Inst, unsigned N) const { 707 assert(N == 1 && "Invalid number of operands!"); 708 // Munge the lsb/width into a bitfield mask. 709 unsigned lsb = Bitfield.LSB; 710 unsigned width = Bitfield.Width; 711 // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 712 uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 713 (32 - (lsb + width))); 714 Inst.addOperand(MCOperand::CreateImm(Mask)); 715 } 716 717 void addImmOperands(MCInst &Inst, unsigned N) const { 718 assert(N == 1 && "Invalid number of operands!"); 719 addExpr(Inst, getImm()); 720 } 721 722 void addImm0_255Operands(MCInst &Inst, unsigned N) const { 723 assert(N == 1 && "Invalid number of operands!"); 724 addExpr(Inst, getImm()); 725 } 726 727 void addImm0_7Operands(MCInst &Inst, unsigned N) const { 728 assert(N == 1 && "Invalid number of operands!"); 729 addExpr(Inst, getImm()); 730 } 731 732 void addImm0_15Operands(MCInst &Inst, unsigned N) const { 733 assert(N == 1 && "Invalid number of operands!"); 734 addExpr(Inst, getImm()); 735 } 736 737 void addImm0_31Operands(MCInst &Inst, unsigned N) const { 738 assert(N == 1 && "Invalid number of operands!"); 739 addExpr(Inst, getImm()); 740 } 741 742 void addImm1_16Operands(MCInst &Inst, unsigned N) const { 743 assert(N == 1 && "Invalid number of operands!"); 744 // The constant encodes as the immediate-1, and we store in the instruction 745 // the bits as encoded, so subtract off one here. 746 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 747 Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 748 } 749 750 void addImm1_32Operands(MCInst &Inst, unsigned N) const { 751 assert(N == 1 && "Invalid number of operands!"); 752 // The constant encodes as the immediate-1, and we store in the instruction 753 // the bits as encoded, so subtract off one here. 754 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 755 Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 756 } 757 758 void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 759 assert(N == 1 && "Invalid number of operands!"); 760 addExpr(Inst, getImm()); 761 } 762 763 void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 764 assert(N == 1 && "Invalid number of operands!"); 765 addExpr(Inst, getImm()); 766 } 767 768 void addImm24bitOperands(MCInst &Inst, unsigned N) const { 769 assert(N == 1 && "Invalid number of operands!"); 770 addExpr(Inst, getImm()); 771 } 772 773 void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 774 assert(N == 1 && "Invalid number of operands!"); 775 addExpr(Inst, getImm()); 776 } 777 778 void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 779 assert(N == 1 && "Invalid number of operands!"); 780 // An ASR value of 32 encodes as 0, so that's how we want to add it to 781 // the instruction as well. 782 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 783 int Val = CE->getValue(); 784 Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 785 } 786 787 void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 788 assert(N == 1 && "Invalid number of operands!"); 789 addExpr(Inst, getImm()); 790 } 791 792 void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 793 assert(N == 1 && "Invalid number of operands!"); 794 addExpr(Inst, getImm()); 795 } 796 797 void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 798 assert(N == 1 && "Invalid number of operands!"); 799 addExpr(Inst, getImm()); 800 } 801 802 void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 803 assert(N == 1 && "Invalid number of operands!"); 804 Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 805 } 806 807 void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 808 assert(N == 1 && "Invalid number of operands!"); 809 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 810 } 811 812 void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 813 assert(N == 3 && "Invalid number of operands!"); 814 int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 815 if (!Mem.OffsetRegNum) { 816 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 817 // Special case for #-0 818 if (Val == INT32_MIN) Val = 0; 819 if (Val < 0) Val = -Val; 820 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 821 } else { 822 // For register offset, we encode the shift type and negation flag 823 // here. 824 Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 825 0, Mem.ShiftType); 826 } 827 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 828 Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 829 Inst.addOperand(MCOperand::CreateImm(Val)); 830 } 831 832 void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 833 assert(N == 2 && "Invalid number of operands!"); 834 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 835 assert(CE && "non-constant AM2OffsetImm operand!"); 836 int32_t Val = CE->getValue(); 837 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 838 // Special case for #-0 839 if (Val == INT32_MIN) Val = 0; 840 if (Val < 0) Val = -Val; 841 Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 842 Inst.addOperand(MCOperand::CreateReg(0)); 843 Inst.addOperand(MCOperand::CreateImm(Val)); 844 } 845 846 void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 847 assert(N == 3 && "Invalid number of operands!"); 848 int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 849 if (!Mem.OffsetRegNum) { 850 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 851 // Special case for #-0 852 if (Val == INT32_MIN) Val = 0; 853 if (Val < 0) Val = -Val; 854 Val = ARM_AM::getAM3Opc(AddSub, Val); 855 } else { 856 // For register offset, we encode the shift type and negation flag 857 // here. 858 Val = ARM_AM::getAM3Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 859 } 860 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 861 Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 862 Inst.addOperand(MCOperand::CreateImm(Val)); 863 } 864 865 void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 866 assert(N == 2 && "Invalid number of operands!"); 867 if (Kind == PostIndexRegister) { 868 int32_t Val = 869 ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 870 Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 871 Inst.addOperand(MCOperand::CreateImm(Val)); 872 return; 873 } 874 875 // Constant offset. 876 const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 877 int32_t Val = CE->getValue(); 878 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 879 // Special case for #-0 880 if (Val == INT32_MIN) Val = 0; 881 if (Val < 0) Val = -Val; 882 Val = ARM_AM::getAM3Opc(AddSub, Val); 883 Inst.addOperand(MCOperand::CreateReg(0)); 884 Inst.addOperand(MCOperand::CreateImm(Val)); 885 } 886 887 void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 888 assert(N == 2 && "Invalid number of operands!"); 889 // The lower two bits are always zero and as such are not encoded. 890 int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0; 891 ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 892 // Special case for #-0 893 if (Val == INT32_MIN) Val = 0; 894 if (Val < 0) Val = -Val; 895 Val = ARM_AM::getAM5Opc(AddSub, Val); 896 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 897 Inst.addOperand(MCOperand::CreateImm(Val)); 898 } 899 900 void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 901 assert(N == 2 && "Invalid number of operands!"); 902 int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 903 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 904 Inst.addOperand(MCOperand::CreateImm(Val)); 905 } 906 907 void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 908 assert(N == 2 && "Invalid number of operands!"); 909 // If this is an immediate, it's a label reference. 910 if (Kind == Immediate) { 911 addExpr(Inst, getImm()); 912 Inst.addOperand(MCOperand::CreateImm(0)); 913 return; 914 } 915 916 // Otherwise, it's a normal memory reg+offset. 917 int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 918 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 919 Inst.addOperand(MCOperand::CreateImm(Val)); 920 } 921 922 void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 923 assert(N == 3 && "Invalid number of operands!"); 924 unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 925 Mem.ShiftImm, Mem.ShiftType); 926 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 927 Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 928 Inst.addOperand(MCOperand::CreateImm(Val)); 929 } 930 931 void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 932 assert(N == 2 && "Invalid number of operands!"); 933 Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 934 Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 935 } 936 937 void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 938 assert(N == 1 && "Invalid number of operands!"); 939 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 940 assert(CE && "non-constant post-idx-imm8 operand!"); 941 int Imm = CE->getValue(); 942 bool isAdd = Imm >= 0; 943 Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 944 Inst.addOperand(MCOperand::CreateImm(Imm)); 945 } 946 947 void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 948 assert(N == 2 && "Invalid number of operands!"); 949 Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 950 Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 951 } 952 953 void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 954 assert(N == 2 && "Invalid number of operands!"); 955 Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 956 // The sign, shift type, and shift amount are encoded in a single operand 957 // using the AM2 encoding helpers. 958 ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 959 unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 960 PostIdxReg.ShiftTy); 961 Inst.addOperand(MCOperand::CreateImm(Imm)); 962 } 963 964 void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 965 assert(N == 1 && "Invalid number of operands!"); 966 Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 967 } 968 969 void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 970 assert(N == 1 && "Invalid number of operands!"); 971 Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 972 } 973 974 virtual void print(raw_ostream &OS) const; 975 976 static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 977 ARMOperand *Op = new ARMOperand(CondCode); 978 Op->CC.Val = CC; 979 Op->StartLoc = S; 980 Op->EndLoc = S; 981 return Op; 982 } 983 984 static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 985 ARMOperand *Op = new ARMOperand(CoprocNum); 986 Op->Cop.Val = CopVal; 987 Op->StartLoc = S; 988 Op->EndLoc = S; 989 return Op; 990 } 991 992 static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 993 ARMOperand *Op = new ARMOperand(CoprocReg); 994 Op->Cop.Val = CopVal; 995 Op->StartLoc = S; 996 Op->EndLoc = S; 997 return Op; 998 } 999 1000 static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 1001 ARMOperand *Op = new ARMOperand(CCOut); 1002 Op->Reg.RegNum = RegNum; 1003 Op->StartLoc = S; 1004 Op->EndLoc = S; 1005 return Op; 1006 } 1007 1008 static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 1009 ARMOperand *Op = new ARMOperand(Token); 1010 Op->Tok.Data = Str.data(); 1011 Op->Tok.Length = Str.size(); 1012 Op->StartLoc = S; 1013 Op->EndLoc = S; 1014 return Op; 1015 } 1016 1017 static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 1018 ARMOperand *Op = new ARMOperand(Register); 1019 Op->Reg.RegNum = RegNum; 1020 Op->StartLoc = S; 1021 Op->EndLoc = E; 1022 return Op; 1023 } 1024 1025 static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1026 unsigned SrcReg, 1027 unsigned ShiftReg, 1028 unsigned ShiftImm, 1029 SMLoc S, SMLoc E) { 1030 ARMOperand *Op = new ARMOperand(ShiftedRegister); 1031 Op->RegShiftedReg.ShiftTy = ShTy; 1032 Op->RegShiftedReg.SrcReg = SrcReg; 1033 Op->RegShiftedReg.ShiftReg = ShiftReg; 1034 Op->RegShiftedReg.ShiftImm = ShiftImm; 1035 Op->StartLoc = S; 1036 Op->EndLoc = E; 1037 return Op; 1038 } 1039 1040 static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 1041 unsigned SrcReg, 1042 unsigned ShiftImm, 1043 SMLoc S, SMLoc E) { 1044 ARMOperand *Op = new ARMOperand(ShiftedImmediate); 1045 Op->RegShiftedImm.ShiftTy = ShTy; 1046 Op->RegShiftedImm.SrcReg = SrcReg; 1047 Op->RegShiftedImm.ShiftImm = ShiftImm; 1048 Op->StartLoc = S; 1049 Op->EndLoc = E; 1050 return Op; 1051 } 1052 1053 static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 1054 SMLoc S, SMLoc E) { 1055 ARMOperand *Op = new ARMOperand(ShifterImmediate); 1056 Op->ShifterImm.isASR = isASR; 1057 Op->ShifterImm.Imm = Imm; 1058 Op->StartLoc = S; 1059 Op->EndLoc = E; 1060 return Op; 1061 } 1062 1063 static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 1064 ARMOperand *Op = new ARMOperand(RotateImmediate); 1065 Op->RotImm.Imm = Imm; 1066 Op->StartLoc = S; 1067 Op->EndLoc = E; 1068 return Op; 1069 } 1070 1071 static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1072 SMLoc S, SMLoc E) { 1073 ARMOperand *Op = new ARMOperand(BitfieldDescriptor); 1074 Op->Bitfield.LSB = LSB; 1075 Op->Bitfield.Width = Width; 1076 Op->StartLoc = S; 1077 Op->EndLoc = E; 1078 return Op; 1079 } 1080 1081 static ARMOperand * 1082 CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1083 SMLoc StartLoc, SMLoc EndLoc) { 1084 KindTy Kind = RegisterList; 1085 1086 if (llvm::ARMMCRegisterClasses[ARM::DPRRegClassID]. 1087 contains(Regs.front().first)) 1088 Kind = DPRRegisterList; 1089 else if (llvm::ARMMCRegisterClasses[ARM::SPRRegClassID]. 1090 contains(Regs.front().first)) 1091 Kind = SPRRegisterList; 1092 1093 ARMOperand *Op = new ARMOperand(Kind); 1094 for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 1095 I = Regs.begin(), E = Regs.end(); I != E; ++I) 1096 Op->Registers.push_back(I->first); 1097 array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1098 Op->StartLoc = StartLoc; 1099 Op->EndLoc = EndLoc; 1100 return Op; 1101 } 1102 1103 static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 1104 ARMOperand *Op = new ARMOperand(Immediate); 1105 Op->Imm.Val = Val; 1106 Op->StartLoc = S; 1107 Op->EndLoc = E; 1108 return Op; 1109 } 1110 1111 static ARMOperand *CreateMem(unsigned BaseRegNum, 1112 const MCConstantExpr *OffsetImm, 1113 unsigned OffsetRegNum, 1114 ARM_AM::ShiftOpc ShiftType, 1115 unsigned ShiftImm, 1116 bool isNegative, 1117 SMLoc S, SMLoc E) { 1118 ARMOperand *Op = new ARMOperand(Memory); 1119 Op->Mem.BaseRegNum = BaseRegNum; 1120 Op->Mem.OffsetImm = OffsetImm; 1121 Op->Mem.OffsetRegNum = OffsetRegNum; 1122 Op->Mem.ShiftType = ShiftType; 1123 Op->Mem.ShiftImm = ShiftImm; 1124 Op->Mem.isNegative = isNegative; 1125 Op->StartLoc = S; 1126 Op->EndLoc = E; 1127 return Op; 1128 } 1129 1130 static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1131 ARM_AM::ShiftOpc ShiftTy, 1132 unsigned ShiftImm, 1133 SMLoc S, SMLoc E) { 1134 ARMOperand *Op = new ARMOperand(PostIndexRegister); 1135 Op->PostIdxReg.RegNum = RegNum; 1136 Op->PostIdxReg.isAdd = isAdd; 1137 Op->PostIdxReg.ShiftTy = ShiftTy; 1138 Op->PostIdxReg.ShiftImm = ShiftImm; 1139 Op->StartLoc = S; 1140 Op->EndLoc = E; 1141 return Op; 1142 } 1143 1144 static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 1145 ARMOperand *Op = new ARMOperand(MemBarrierOpt); 1146 Op->MBOpt.Val = Opt; 1147 Op->StartLoc = S; 1148 Op->EndLoc = S; 1149 return Op; 1150 } 1151 1152 static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 1153 ARMOperand *Op = new ARMOperand(ProcIFlags); 1154 Op->IFlags.Val = IFlags; 1155 Op->StartLoc = S; 1156 Op->EndLoc = S; 1157 return Op; 1158 } 1159 1160 static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 1161 ARMOperand *Op = new ARMOperand(MSRMask); 1162 Op->MMask.Val = MMask; 1163 Op->StartLoc = S; 1164 Op->EndLoc = S; 1165 return Op; 1166 } 1167}; 1168 1169} // end anonymous namespace. 1170 1171void ARMOperand::print(raw_ostream &OS) const { 1172 switch (Kind) { 1173 case CondCode: 1174 OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1175 break; 1176 case CCOut: 1177 OS << "<ccout " << getReg() << ">"; 1178 break; 1179 case CoprocNum: 1180 OS << "<coprocessor number: " << getCoproc() << ">"; 1181 break; 1182 case CoprocReg: 1183 OS << "<coprocessor register: " << getCoproc() << ">"; 1184 break; 1185 case MSRMask: 1186 OS << "<mask: " << getMSRMask() << ">"; 1187 break; 1188 case Immediate: 1189 getImm()->print(OS); 1190 break; 1191 case MemBarrierOpt: 1192 OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1193 break; 1194 case Memory: 1195 OS << "<memory " 1196 << " base:" << Mem.BaseRegNum; 1197 OS << ">"; 1198 break; 1199 case PostIndexRegister: 1200 OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 1201 << PostIdxReg.RegNum; 1202 if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 1203 OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 1204 << PostIdxReg.ShiftImm; 1205 OS << ">"; 1206 break; 1207 case ProcIFlags: { 1208 OS << "<ARM_PROC::"; 1209 unsigned IFlags = getProcIFlags(); 1210 for (int i=2; i >= 0; --i) 1211 if (IFlags & (1 << i)) 1212 OS << ARM_PROC::IFlagsToString(1 << i); 1213 OS << ">"; 1214 break; 1215 } 1216 case Register: 1217 OS << "<register " << getReg() << ">"; 1218 break; 1219 case ShifterImmediate: 1220 OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1221 << " #" << ShifterImm.Imm << ">"; 1222 break; 1223 case ShiftedRegister: 1224 OS << "<so_reg_reg " 1225 << RegShiftedReg.SrcReg 1226 << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1227 << ", " << RegShiftedReg.ShiftReg << ", " 1228 << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1229 << ">"; 1230 break; 1231 case ShiftedImmediate: 1232 OS << "<so_reg_imm " 1233 << RegShiftedImm.SrcReg 1234 << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1235 << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 1236 << ">"; 1237 break; 1238 case RotateImmediate: 1239 OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 1240 break; 1241 case BitfieldDescriptor: 1242 OS << "<bitfield " << "lsb: " << Bitfield.LSB 1243 << ", width: " << Bitfield.Width << ">"; 1244 break; 1245 case RegisterList: 1246 case DPRRegisterList: 1247 case SPRRegisterList: { 1248 OS << "<register_list "; 1249 1250 const SmallVectorImpl<unsigned> &RegList = getRegList(); 1251 for (SmallVectorImpl<unsigned>::const_iterator 1252 I = RegList.begin(), E = RegList.end(); I != E; ) { 1253 OS << *I; 1254 if (++I < E) OS << ", "; 1255 } 1256 1257 OS << ">"; 1258 break; 1259 } 1260 case Token: 1261 OS << "'" << getToken() << "'"; 1262 break; 1263 } 1264} 1265 1266/// @name Auto-generated Match Functions 1267/// { 1268 1269static unsigned MatchRegisterName(StringRef Name); 1270 1271/// } 1272 1273bool ARMAsmParser::ParseRegister(unsigned &RegNo, 1274 SMLoc &StartLoc, SMLoc &EndLoc) { 1275 RegNo = tryParseRegister(); 1276 1277 return (RegNo == (unsigned)-1); 1278} 1279 1280/// Try to parse a register name. The token must be an Identifier when called, 1281/// and if it is a register name the token is eaten and the register number is 1282/// returned. Otherwise return -1. 1283/// 1284int ARMAsmParser::tryParseRegister() { 1285 const AsmToken &Tok = Parser.getTok(); 1286 if (Tok.isNot(AsmToken::Identifier)) return -1; 1287 1288 // FIXME: Validate register for the current architecture; we have to do 1289 // validation later, so maybe there is no need for this here. 1290 std::string upperCase = Tok.getString().str(); 1291 std::string lowerCase = LowercaseString(upperCase); 1292 unsigned RegNum = MatchRegisterName(lowerCase); 1293 if (!RegNum) { 1294 RegNum = StringSwitch<unsigned>(lowerCase) 1295 .Case("r13", ARM::SP) 1296 .Case("r14", ARM::LR) 1297 .Case("r15", ARM::PC) 1298 .Case("ip", ARM::R12) 1299 .Default(0); 1300 } 1301 if (!RegNum) return -1; 1302 1303 Parser.Lex(); // Eat identifier token. 1304 return RegNum; 1305} 1306 1307// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 1308// If a recoverable error occurs, return 1. If an irrecoverable error 1309// occurs, return -1. An irrecoverable error is one where tokens have been 1310// consumed in the process of trying to parse the shifter (i.e., when it is 1311// indeed a shifter operand, but malformed). 1312int ARMAsmParser::tryParseShiftRegister( 1313 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1314 SMLoc S = Parser.getTok().getLoc(); 1315 const AsmToken &Tok = Parser.getTok(); 1316 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1317 1318 std::string upperCase = Tok.getString().str(); 1319 std::string lowerCase = LowercaseString(upperCase); 1320 ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 1321 .Case("lsl", ARM_AM::lsl) 1322 .Case("lsr", ARM_AM::lsr) 1323 .Case("asr", ARM_AM::asr) 1324 .Case("ror", ARM_AM::ror) 1325 .Case("rrx", ARM_AM::rrx) 1326 .Default(ARM_AM::no_shift); 1327 1328 if (ShiftTy == ARM_AM::no_shift) 1329 return 1; 1330 1331 Parser.Lex(); // Eat the operator. 1332 1333 // The source register for the shift has already been added to the 1334 // operand list, so we need to pop it off and combine it into the shifted 1335 // register operand instead. 1336 OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 1337 if (!PrevOp->isReg()) 1338 return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1339 int SrcReg = PrevOp->getReg(); 1340 int64_t Imm = 0; 1341 int ShiftReg = 0; 1342 if (ShiftTy == ARM_AM::rrx) { 1343 // RRX Doesn't have an explicit shift amount. The encoder expects 1344 // the shift register to be the same as the source register. Seems odd, 1345 // but OK. 1346 ShiftReg = SrcReg; 1347 } else { 1348 // Figure out if this is shifted by a constant or a register (for non-RRX). 1349 if (Parser.getTok().is(AsmToken::Hash)) { 1350 Parser.Lex(); // Eat hash. 1351 SMLoc ImmLoc = Parser.getTok().getLoc(); 1352 const MCExpr *ShiftExpr = 0; 1353 if (getParser().ParseExpression(ShiftExpr)) { 1354 Error(ImmLoc, "invalid immediate shift value"); 1355 return -1; 1356 } 1357 // The expression must be evaluatable as an immediate. 1358 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 1359 if (!CE) { 1360 Error(ImmLoc, "invalid immediate shift value"); 1361 return -1; 1362 } 1363 // Range check the immediate. 1364 // lsl, ror: 0 <= imm <= 31 1365 // lsr, asr: 0 <= imm <= 32 1366 Imm = CE->getValue(); 1367 if (Imm < 0 || 1368 ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1369 ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 1370 Error(ImmLoc, "immediate shift value out of range"); 1371 return -1; 1372 } 1373 } else if (Parser.getTok().is(AsmToken::Identifier)) { 1374 ShiftReg = tryParseRegister(); 1375 SMLoc L = Parser.getTok().getLoc(); 1376 if (ShiftReg == -1) { 1377 Error (L, "expected immediate or register in shift operand"); 1378 return -1; 1379 } 1380 } else { 1381 Error (Parser.getTok().getLoc(), 1382 "expected immediate or register in shift operand"); 1383 return -1; 1384 } 1385 } 1386 1387 if (ShiftReg && ShiftTy != ARM_AM::rrx) 1388 Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1389 ShiftReg, Imm, 1390 S, Parser.getTok().getLoc())); 1391 else 1392 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 1393 S, Parser.getTok().getLoc())); 1394 1395 return 0; 1396} 1397 1398 1399/// Try to parse a register name. The token must be an Identifier when called. 1400/// If it's a register, an AsmOperand is created. Another AsmOperand is created 1401/// if there is a "writeback". 'true' if it's not a register. 1402/// 1403/// TODO this is likely to change to allow different register types and or to 1404/// parse for a specific register type. 1405bool ARMAsmParser:: 1406tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1407 SMLoc S = Parser.getTok().getLoc(); 1408 int RegNo = tryParseRegister(); 1409 if (RegNo == -1) 1410 return true; 1411 1412 Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1413 1414 const AsmToken &ExclaimTok = Parser.getTok(); 1415 if (ExclaimTok.is(AsmToken::Exclaim)) { 1416 Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 1417 ExclaimTok.getLoc())); 1418 Parser.Lex(); // Eat exclaim token 1419 } 1420 1421 return false; 1422} 1423 1424/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1425/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1426/// "c5", ... 1427static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1428 // Use the same layout as the tablegen'erated register name matcher. Ugly, 1429 // but efficient. 1430 switch (Name.size()) { 1431 default: break; 1432 case 2: 1433 if (Name[0] != CoprocOp) 1434 return -1; 1435 switch (Name[1]) { 1436 default: return -1; 1437 case '0': return 0; 1438 case '1': return 1; 1439 case '2': return 2; 1440 case '3': return 3; 1441 case '4': return 4; 1442 case '5': return 5; 1443 case '6': return 6; 1444 case '7': return 7; 1445 case '8': return 8; 1446 case '9': return 9; 1447 } 1448 break; 1449 case 3: 1450 if (Name[0] != CoprocOp || Name[1] != '1') 1451 return -1; 1452 switch (Name[2]) { 1453 default: return -1; 1454 case '0': return 10; 1455 case '1': return 11; 1456 case '2': return 12; 1457 case '3': return 13; 1458 case '4': return 14; 1459 case '5': return 15; 1460 } 1461 break; 1462 } 1463 1464 return -1; 1465} 1466 1467/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 1468/// token must be an Identifier when called, and if it is a coprocessor 1469/// number, the token is eaten and the operand is added to the operand list. 1470ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1471parseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1472 SMLoc S = Parser.getTok().getLoc(); 1473 const AsmToken &Tok = Parser.getTok(); 1474 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1475 1476 int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 1477 if (Num == -1) 1478 return MatchOperand_NoMatch; 1479 1480 Parser.Lex(); // Eat identifier token. 1481 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 1482 return MatchOperand_Success; 1483} 1484 1485/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 1486/// token must be an Identifier when called, and if it is a coprocessor 1487/// number, the token is eaten and the operand is added to the operand list. 1488ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1489parseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1490 SMLoc S = Parser.getTok().getLoc(); 1491 const AsmToken &Tok = Parser.getTok(); 1492 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1493 1494 int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 1495 if (Reg == -1) 1496 return MatchOperand_NoMatch; 1497 1498 Parser.Lex(); // Eat identifier token. 1499 Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 1500 return MatchOperand_Success; 1501} 1502 1503/// Parse a register list, return it if successful else return null. The first 1504/// token must be a '{' when called. 1505bool ARMAsmParser:: 1506parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1507 assert(Parser.getTok().is(AsmToken::LCurly) && 1508 "Token is not a Left Curly Brace"); 1509 SMLoc S = Parser.getTok().getLoc(); 1510 1511 // Read the rest of the registers in the list. 1512 unsigned PrevRegNum = 0; 1513 SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 1514 1515 do { 1516 bool IsRange = Parser.getTok().is(AsmToken::Minus); 1517 Parser.Lex(); // Eat non-identifier token. 1518 1519 const AsmToken &RegTok = Parser.getTok(); 1520 SMLoc RegLoc = RegTok.getLoc(); 1521 if (RegTok.isNot(AsmToken::Identifier)) { 1522 Error(RegLoc, "register expected"); 1523 return true; 1524 } 1525 1526 int RegNum = tryParseRegister(); 1527 if (RegNum == -1) { 1528 Error(RegLoc, "register expected"); 1529 return true; 1530 } 1531 1532 if (IsRange) { 1533 int Reg = PrevRegNum; 1534 do { 1535 ++Reg; 1536 Registers.push_back(std::make_pair(Reg, RegLoc)); 1537 } while (Reg != RegNum); 1538 } else { 1539 Registers.push_back(std::make_pair(RegNum, RegLoc)); 1540 } 1541 1542 PrevRegNum = RegNum; 1543 } while (Parser.getTok().is(AsmToken::Comma) || 1544 Parser.getTok().is(AsmToken::Minus)); 1545 1546 // Process the right curly brace of the list. 1547 const AsmToken &RCurlyTok = Parser.getTok(); 1548 if (RCurlyTok.isNot(AsmToken::RCurly)) { 1549 Error(RCurlyTok.getLoc(), "'}' expected"); 1550 return true; 1551 } 1552 1553 SMLoc E = RCurlyTok.getLoc(); 1554 Parser.Lex(); // Eat right curly brace token. 1555 1556 // Verify the register list. 1557 SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 1558 RI = Registers.begin(), RE = Registers.end(); 1559 1560 unsigned HighRegNum = getARMRegisterNumbering(RI->first); 1561 bool EmittedWarning = false; 1562 1563 DenseMap<unsigned, bool> RegMap; 1564 RegMap[HighRegNum] = true; 1565 1566 for (++RI; RI != RE; ++RI) { 1567 const std::pair<unsigned, SMLoc> &RegInfo = *RI; 1568 unsigned Reg = getARMRegisterNumbering(RegInfo.first); 1569 1570 if (RegMap[Reg]) { 1571 Error(RegInfo.second, "register duplicated in register list"); 1572 return true; 1573 } 1574 1575 if (!EmittedWarning && Reg < HighRegNum) 1576 Warning(RegInfo.second, 1577 "register not in ascending order in register list"); 1578 1579 RegMap[Reg] = true; 1580 HighRegNum = std::max(Reg, HighRegNum); 1581 } 1582 1583 Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 1584 return false; 1585} 1586 1587/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 1588ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1589parseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1590 SMLoc S = Parser.getTok().getLoc(); 1591 const AsmToken &Tok = Parser.getTok(); 1592 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1593 StringRef OptStr = Tok.getString(); 1594 1595 unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 1596 .Case("sy", ARM_MB::SY) 1597 .Case("st", ARM_MB::ST) 1598 .Case("sh", ARM_MB::ISH) 1599 .Case("ish", ARM_MB::ISH) 1600 .Case("shst", ARM_MB::ISHST) 1601 .Case("ishst", ARM_MB::ISHST) 1602 .Case("nsh", ARM_MB::NSH) 1603 .Case("un", ARM_MB::NSH) 1604 .Case("nshst", ARM_MB::NSHST) 1605 .Case("unst", ARM_MB::NSHST) 1606 .Case("osh", ARM_MB::OSH) 1607 .Case("oshst", ARM_MB::OSHST) 1608 .Default(~0U); 1609 1610 if (Opt == ~0U) 1611 return MatchOperand_NoMatch; 1612 1613 Parser.Lex(); // Eat identifier token. 1614 Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 1615 return MatchOperand_Success; 1616} 1617 1618/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 1619ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1620parseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1621 SMLoc S = Parser.getTok().getLoc(); 1622 const AsmToken &Tok = Parser.getTok(); 1623 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1624 StringRef IFlagsStr = Tok.getString(); 1625 1626 unsigned IFlags = 0; 1627 for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 1628 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 1629 .Case("a", ARM_PROC::A) 1630 .Case("i", ARM_PROC::I) 1631 .Case("f", ARM_PROC::F) 1632 .Default(~0U); 1633 1634 // If some specific iflag is already set, it means that some letter is 1635 // present more than once, this is not acceptable. 1636 if (Flag == ~0U || (IFlags & Flag)) 1637 return MatchOperand_NoMatch; 1638 1639 IFlags |= Flag; 1640 } 1641 1642 Parser.Lex(); // Eat identifier token. 1643 Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 1644 return MatchOperand_Success; 1645} 1646 1647/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 1648ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1649parseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1650 SMLoc S = Parser.getTok().getLoc(); 1651 const AsmToken &Tok = Parser.getTok(); 1652 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1653 StringRef Mask = Tok.getString(); 1654 1655 // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 1656 size_t Start = 0, Next = Mask.find('_'); 1657 StringRef Flags = ""; 1658 std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 1659 if (Next != StringRef::npos) 1660 Flags = Mask.slice(Next+1, Mask.size()); 1661 1662 // FlagsVal contains the complete mask: 1663 // 3-0: Mask 1664 // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1665 unsigned FlagsVal = 0; 1666 1667 if (SpecReg == "apsr") { 1668 FlagsVal = StringSwitch<unsigned>(Flags) 1669 .Case("nzcvq", 0x8) // same as CPSR_f 1670 .Case("g", 0x4) // same as CPSR_s 1671 .Case("nzcvqg", 0xc) // same as CPSR_fs 1672 .Default(~0U); 1673 1674 if (FlagsVal == ~0U) { 1675 if (!Flags.empty()) 1676 return MatchOperand_NoMatch; 1677 else 1678 FlagsVal = 0; // No flag 1679 } 1680 } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 1681 if (Flags == "all") // cpsr_all is an alias for cpsr_fc 1682 Flags = "fc"; 1683 for (int i = 0, e = Flags.size(); i != e; ++i) { 1684 unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 1685 .Case("c", 1) 1686 .Case("x", 2) 1687 .Case("s", 4) 1688 .Case("f", 8) 1689 .Default(~0U); 1690 1691 // If some specific flag is already set, it means that some letter is 1692 // present more than once, this is not acceptable. 1693 if (FlagsVal == ~0U || (FlagsVal & Flag)) 1694 return MatchOperand_NoMatch; 1695 FlagsVal |= Flag; 1696 } 1697 } else // No match for special register. 1698 return MatchOperand_NoMatch; 1699 1700 // Special register without flags are equivalent to "fc" flags. 1701 if (!FlagsVal) 1702 FlagsVal = 0x9; 1703 1704 // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1705 if (SpecReg == "spsr") 1706 FlagsVal |= 16; 1707 1708 Parser.Lex(); // Eat identifier token. 1709 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 1710 return MatchOperand_Success; 1711} 1712 1713ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1714parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 1715 int Low, int High) { 1716 const AsmToken &Tok = Parser.getTok(); 1717 if (Tok.isNot(AsmToken::Identifier)) { 1718 Error(Parser.getTok().getLoc(), Op + " operand expected."); 1719 return MatchOperand_ParseFail; 1720 } 1721 StringRef ShiftName = Tok.getString(); 1722 std::string LowerOp = LowercaseString(Op); 1723 std::string UpperOp = UppercaseString(Op); 1724 if (ShiftName != LowerOp && ShiftName != UpperOp) { 1725 Error(Parser.getTok().getLoc(), Op + " operand expected."); 1726 return MatchOperand_ParseFail; 1727 } 1728 Parser.Lex(); // Eat shift type token. 1729 1730 // There must be a '#' and a shift amount. 1731 if (Parser.getTok().isNot(AsmToken::Hash)) { 1732 Error(Parser.getTok().getLoc(), "'#' expected"); 1733 return MatchOperand_ParseFail; 1734 } 1735 Parser.Lex(); // Eat hash token. 1736 1737 const MCExpr *ShiftAmount; 1738 SMLoc Loc = Parser.getTok().getLoc(); 1739 if (getParser().ParseExpression(ShiftAmount)) { 1740 Error(Loc, "illegal expression"); 1741 return MatchOperand_ParseFail; 1742 } 1743 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1744 if (!CE) { 1745 Error(Loc, "constant expression expected"); 1746 return MatchOperand_ParseFail; 1747 } 1748 int Val = CE->getValue(); 1749 if (Val < Low || Val > High) { 1750 Error(Loc, "immediate value out of range"); 1751 return MatchOperand_ParseFail; 1752 } 1753 1754 Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 1755 1756 return MatchOperand_Success; 1757} 1758 1759ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1760parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1761 const AsmToken &Tok = Parser.getTok(); 1762 SMLoc S = Tok.getLoc(); 1763 if (Tok.isNot(AsmToken::Identifier)) { 1764 Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1765 return MatchOperand_ParseFail; 1766 } 1767 int Val = StringSwitch<int>(Tok.getString()) 1768 .Case("be", 1) 1769 .Case("le", 0) 1770 .Default(-1); 1771 Parser.Lex(); // Eat the token. 1772 1773 if (Val == -1) { 1774 Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1775 return MatchOperand_ParseFail; 1776 } 1777 Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 1778 getContext()), 1779 S, Parser.getTok().getLoc())); 1780 return MatchOperand_Success; 1781} 1782 1783/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 1784/// instructions. Legal values are: 1785/// lsl #n 'n' in [0,31] 1786/// asr #n 'n' in [1,32] 1787/// n == 32 encoded as n == 0. 1788ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1789parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1790 const AsmToken &Tok = Parser.getTok(); 1791 SMLoc S = Tok.getLoc(); 1792 if (Tok.isNot(AsmToken::Identifier)) { 1793 Error(S, "shift operator 'asr' or 'lsl' expected"); 1794 return MatchOperand_ParseFail; 1795 } 1796 StringRef ShiftName = Tok.getString(); 1797 bool isASR; 1798 if (ShiftName == "lsl" || ShiftName == "LSL") 1799 isASR = false; 1800 else if (ShiftName == "asr" || ShiftName == "ASR") 1801 isASR = true; 1802 else { 1803 Error(S, "shift operator 'asr' or 'lsl' expected"); 1804 return MatchOperand_ParseFail; 1805 } 1806 Parser.Lex(); // Eat the operator. 1807 1808 // A '#' and a shift amount. 1809 if (Parser.getTok().isNot(AsmToken::Hash)) { 1810 Error(Parser.getTok().getLoc(), "'#' expected"); 1811 return MatchOperand_ParseFail; 1812 } 1813 Parser.Lex(); // Eat hash token. 1814 1815 const MCExpr *ShiftAmount; 1816 SMLoc E = Parser.getTok().getLoc(); 1817 if (getParser().ParseExpression(ShiftAmount)) { 1818 Error(E, "malformed shift expression"); 1819 return MatchOperand_ParseFail; 1820 } 1821 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1822 if (!CE) { 1823 Error(E, "shift amount must be an immediate"); 1824 return MatchOperand_ParseFail; 1825 } 1826 1827 int64_t Val = CE->getValue(); 1828 if (isASR) { 1829 // Shift amount must be in [1,32] 1830 if (Val < 1 || Val > 32) { 1831 Error(E, "'asr' shift amount must be in range [1,32]"); 1832 return MatchOperand_ParseFail; 1833 } 1834 // asr #32 encoded as asr #0. 1835 if (Val == 32) Val = 0; 1836 } else { 1837 // Shift amount must be in [1,32] 1838 if (Val < 0 || Val > 31) { 1839 Error(E, "'lsr' shift amount must be in range [0,31]"); 1840 return MatchOperand_ParseFail; 1841 } 1842 } 1843 1844 E = Parser.getTok().getLoc(); 1845 Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 1846 1847 return MatchOperand_Success; 1848} 1849 1850/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 1851/// of instructions. Legal values are: 1852/// ror #n 'n' in {0, 8, 16, 24} 1853ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1854parseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1855 const AsmToken &Tok = Parser.getTok(); 1856 SMLoc S = Tok.getLoc(); 1857 if (Tok.isNot(AsmToken::Identifier)) { 1858 Error(S, "rotate operator 'ror' expected"); 1859 return MatchOperand_ParseFail; 1860 } 1861 StringRef ShiftName = Tok.getString(); 1862 if (ShiftName != "ror" && ShiftName != "ROR") { 1863 Error(S, "rotate operator 'ror' expected"); 1864 return MatchOperand_ParseFail; 1865 } 1866 Parser.Lex(); // Eat the operator. 1867 1868 // A '#' and a rotate amount. 1869 if (Parser.getTok().isNot(AsmToken::Hash)) { 1870 Error(Parser.getTok().getLoc(), "'#' expected"); 1871 return MatchOperand_ParseFail; 1872 } 1873 Parser.Lex(); // Eat hash token. 1874 1875 const MCExpr *ShiftAmount; 1876 SMLoc E = Parser.getTok().getLoc(); 1877 if (getParser().ParseExpression(ShiftAmount)) { 1878 Error(E, "malformed rotate expression"); 1879 return MatchOperand_ParseFail; 1880 } 1881 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1882 if (!CE) { 1883 Error(E, "rotate amount must be an immediate"); 1884 return MatchOperand_ParseFail; 1885 } 1886 1887 int64_t Val = CE->getValue(); 1888 // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 1889 // normally, zero is represented in asm by omitting the rotate operand 1890 // entirely. 1891 if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 1892 Error(E, "'ror' rotate amount must be 8, 16, or 24"); 1893 return MatchOperand_ParseFail; 1894 } 1895 1896 E = Parser.getTok().getLoc(); 1897 Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 1898 1899 return MatchOperand_Success; 1900} 1901 1902ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1903parseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1904 SMLoc S = Parser.getTok().getLoc(); 1905 // The bitfield descriptor is really two operands, the LSB and the width. 1906 if (Parser.getTok().isNot(AsmToken::Hash)) { 1907 Error(Parser.getTok().getLoc(), "'#' expected"); 1908 return MatchOperand_ParseFail; 1909 } 1910 Parser.Lex(); // Eat hash token. 1911 1912 const MCExpr *LSBExpr; 1913 SMLoc E = Parser.getTok().getLoc(); 1914 if (getParser().ParseExpression(LSBExpr)) { 1915 Error(E, "malformed immediate expression"); 1916 return MatchOperand_ParseFail; 1917 } 1918 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 1919 if (!CE) { 1920 Error(E, "'lsb' operand must be an immediate"); 1921 return MatchOperand_ParseFail; 1922 } 1923 1924 int64_t LSB = CE->getValue(); 1925 // The LSB must be in the range [0,31] 1926 if (LSB < 0 || LSB > 31) { 1927 Error(E, "'lsb' operand must be in the range [0,31]"); 1928 return MatchOperand_ParseFail; 1929 } 1930 E = Parser.getTok().getLoc(); 1931 1932 // Expect another immediate operand. 1933 if (Parser.getTok().isNot(AsmToken::Comma)) { 1934 Error(Parser.getTok().getLoc(), "too few operands"); 1935 return MatchOperand_ParseFail; 1936 } 1937 Parser.Lex(); // Eat hash token. 1938 if (Parser.getTok().isNot(AsmToken::Hash)) { 1939 Error(Parser.getTok().getLoc(), "'#' expected"); 1940 return MatchOperand_ParseFail; 1941 } 1942 Parser.Lex(); // Eat hash token. 1943 1944 const MCExpr *WidthExpr; 1945 if (getParser().ParseExpression(WidthExpr)) { 1946 Error(E, "malformed immediate expression"); 1947 return MatchOperand_ParseFail; 1948 } 1949 CE = dyn_cast<MCConstantExpr>(WidthExpr); 1950 if (!CE) { 1951 Error(E, "'width' operand must be an immediate"); 1952 return MatchOperand_ParseFail; 1953 } 1954 1955 int64_t Width = CE->getValue(); 1956 // The LSB must be in the range [1,32-lsb] 1957 if (Width < 1 || Width > 32 - LSB) { 1958 Error(E, "'width' operand must be in the range [1,32-lsb]"); 1959 return MatchOperand_ParseFail; 1960 } 1961 E = Parser.getTok().getLoc(); 1962 1963 Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 1964 1965 return MatchOperand_Success; 1966} 1967 1968ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1969parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1970 // Check for a post-index addressing register operand. Specifically: 1971 // postidx_reg := '+' register {, shift} 1972 // | '-' register {, shift} 1973 // | register {, shift} 1974 1975 // This method must return MatchOperand_NoMatch without consuming any tokens 1976 // in the case where there is no match, as other alternatives take other 1977 // parse methods. 1978 AsmToken Tok = Parser.getTok(); 1979 SMLoc S = Tok.getLoc(); 1980 bool haveEaten = false; 1981 bool isAdd = true; 1982 int Reg = -1; 1983 if (Tok.is(AsmToken::Plus)) { 1984 Parser.Lex(); // Eat the '+' token. 1985 haveEaten = true; 1986 } else if (Tok.is(AsmToken::Minus)) { 1987 Parser.Lex(); // Eat the '-' token. 1988 isAdd = false; 1989 haveEaten = true; 1990 } 1991 if (Parser.getTok().is(AsmToken::Identifier)) 1992 Reg = tryParseRegister(); 1993 if (Reg == -1) { 1994 if (!haveEaten) 1995 return MatchOperand_NoMatch; 1996 Error(Parser.getTok().getLoc(), "register expected"); 1997 return MatchOperand_ParseFail; 1998 } 1999 SMLoc E = Parser.getTok().getLoc(); 2000 2001 ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 2002 unsigned ShiftImm = 0; 2003 if (Parser.getTok().is(AsmToken::Comma)) { 2004 Parser.Lex(); // Eat the ','. 2005 if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 2006 return MatchOperand_ParseFail; 2007 } 2008 2009 Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 2010 ShiftImm, S, E)); 2011 2012 return MatchOperand_Success; 2013} 2014 2015ARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2016parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2017 // Check for a post-index addressing register operand. Specifically: 2018 // am3offset := '+' register 2019 // | '-' register 2020 // | register 2021 // | # imm 2022 // | # + imm 2023 // | # - imm 2024 2025 // This method must return MatchOperand_NoMatch without consuming any tokens 2026 // in the case where there is no match, as other alternatives take other 2027 // parse methods. 2028 AsmToken Tok = Parser.getTok(); 2029 SMLoc S = Tok.getLoc(); 2030 2031 // Do immediates first, as we always parse those if we have a '#'. 2032 if (Parser.getTok().is(AsmToken::Hash)) { 2033 Parser.Lex(); // Eat the '#'. 2034 // Explicitly look for a '-', as we need to encode negative zero 2035 // differently. 2036 bool isNegative = Parser.getTok().is(AsmToken::Minus); 2037 const MCExpr *Offset; 2038 if (getParser().ParseExpression(Offset)) 2039 return MatchOperand_ParseFail; 2040 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 2041 if (!CE) { 2042 Error(S, "constant expression expected"); 2043 return MatchOperand_ParseFail; 2044 } 2045 SMLoc E = Tok.getLoc(); 2046 // Negative zero is encoded as the flag value INT32_MIN. 2047 int32_t Val = CE->getValue(); 2048 if (isNegative && Val == 0) 2049 Val = INT32_MIN; 2050 2051 Operands.push_back( 2052 ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 2053 2054 return MatchOperand_Success; 2055 } 2056 2057 2058 bool haveEaten = false; 2059 bool isAdd = true; 2060 int Reg = -1; 2061 if (Tok.is(AsmToken::Plus)) { 2062 Parser.Lex(); // Eat the '+' token. 2063 haveEaten = true; 2064 } else if (Tok.is(AsmToken::Minus)) { 2065 Parser.Lex(); // Eat the '-' token. 2066 isAdd = false; 2067 haveEaten = true; 2068 } 2069 if (Parser.getTok().is(AsmToken::Identifier)) 2070 Reg = tryParseRegister(); 2071 if (Reg == -1) { 2072 if (!haveEaten) 2073 return MatchOperand_NoMatch; 2074 Error(Parser.getTok().getLoc(), "register expected"); 2075 return MatchOperand_ParseFail; 2076 } 2077 SMLoc E = Parser.getTok().getLoc(); 2078 2079 Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 2080 0, S, E)); 2081 2082 return MatchOperand_Success; 2083} 2084 2085/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2086/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2087/// when they refer multiple MIOperands inside a single one. 2088bool ARMAsmParser:: 2089cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2090 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2091 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2092 2093 // Create a writeback register dummy placeholder. 2094 Inst.addOperand(MCOperand::CreateImm(0)); 2095 2096 ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2097 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2098 return true; 2099} 2100 2101/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2102/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2103/// when they refer multiple MIOperands inside a single one. 2104bool ARMAsmParser:: 2105cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2106 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2107 // Create a writeback register dummy placeholder. 2108 Inst.addOperand(MCOperand::CreateImm(0)); 2109 assert(0 && "cvtStWriteBackRegAddrMode2 not implemented yet!"); 2110 return true; 2111} 2112 2113/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 2114/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2115/// when they refer multiple MIOperands inside a single one. 2116bool ARMAsmParser:: 2117cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 2118 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2119 // Rt 2120 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2121 // Create a writeback register dummy placeholder. 2122 Inst.addOperand(MCOperand::CreateImm(0)); 2123 // addr 2124 ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 2125 // offset 2126 ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 2127 // pred 2128 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2129 return true; 2130} 2131 2132/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 2133/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2134/// when they refer multiple MIOperands inside a single one. 2135bool ARMAsmParser:: 2136cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 2137 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2138 // Rt 2139 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2140 // Create a writeback register dummy placeholder. 2141 Inst.addOperand(MCOperand::CreateImm(0)); 2142 // addr 2143 ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 2144 // offset 2145 ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 2146 // pred 2147 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2148 return true; 2149} 2150 2151/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 2152/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2153/// when they refer multiple MIOperands inside a single one. 2154bool ARMAsmParser:: 2155cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 2156 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2157 // Create a writeback register dummy placeholder. 2158 Inst.addOperand(MCOperand::CreateImm(0)); 2159 // Rt 2160 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2161 // addr 2162 ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 2163 // offset 2164 ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 2165 // pred 2166 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2167 return true; 2168} 2169 2170/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 2171/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2172/// when they refer multiple MIOperands inside a single one. 2173bool ARMAsmParser:: 2174cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 2175 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2176 // Create a writeback register dummy placeholder. 2177 Inst.addOperand(MCOperand::CreateImm(0)); 2178 // Rt 2179 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2180 // addr 2181 ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 2182 // offset 2183 ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 2184 // pred 2185 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2186 return true; 2187} 2188 2189/// cvtLdrdPre - Convert parsed operands to MCInst. 2190/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2191/// when they refer multiple MIOperands inside a single one. 2192bool ARMAsmParser:: 2193cvtLdrdPre(MCInst &Inst, unsigned Opcode, 2194 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2195 // Rt, Rt2 2196 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2197 ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 2198 // Create a writeback register dummy placeholder. 2199 Inst.addOperand(MCOperand::CreateImm(0)); 2200 // addr 2201 ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 2202 // pred 2203 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2204 return true; 2205} 2206 2207/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 2208/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2209/// when they refer multiple MIOperands inside a single one. 2210bool ARMAsmParser:: 2211cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 2212 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2213 ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2214 // Create a writeback register dummy placeholder. 2215 Inst.addOperand(MCOperand::CreateImm(0)); 2216 ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 2217 ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2218 return true; 2219} 2220 2221 2222/// Parse an ARM memory expression, return false if successful else return true 2223/// or an error. The first token must be a '[' when called. 2224bool ARMAsmParser:: 2225parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2226 SMLoc S, E; 2227 assert(Parser.getTok().is(AsmToken::LBrac) && 2228 "Token is not a Left Bracket"); 2229 S = Parser.getTok().getLoc(); 2230 Parser.Lex(); // Eat left bracket token. 2231 2232 const AsmToken &BaseRegTok = Parser.getTok(); 2233 int BaseRegNum = tryParseRegister(); 2234 if (BaseRegNum == -1) 2235 return Error(BaseRegTok.getLoc(), "register expected"); 2236 2237 // The next token must either be a comma or a closing bracket. 2238 const AsmToken &Tok = Parser.getTok(); 2239 if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 2240 return Error(Tok.getLoc(), "malformed memory operand"); 2241 2242 if (Tok.is(AsmToken::RBrac)) { 2243 E = Tok.getLoc(); 2244 Parser.Lex(); // Eat right bracket token. 2245 2246 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 2247 0, false, S, E)); 2248 2249 return false; 2250 } 2251 2252 assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 2253 Parser.Lex(); // Eat the comma. 2254 2255 // If we have a '#' it's an immediate offset, else assume it's a register 2256 // offset. 2257 if (Parser.getTok().is(AsmToken::Hash)) { 2258 Parser.Lex(); // Eat the '#'. 2259 E = Parser.getTok().getLoc(); 2260 2261 // FIXME: Special case #-0 so we can correctly set the U bit. 2262 2263 const MCExpr *Offset; 2264 if (getParser().ParseExpression(Offset)) 2265 return true; 2266 2267 // The expression has to be a constant. Memory references with relocations 2268 // don't come through here, as they use the <label> forms of the relevant 2269 // instructions. 2270 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 2271 if (!CE) 2272 return Error (E, "constant expression expected"); 2273 2274 // Now we should have the closing ']' 2275 E = Parser.getTok().getLoc(); 2276 if (Parser.getTok().isNot(AsmToken::RBrac)) 2277 return Error(E, "']' expected"); 2278 Parser.Lex(); // Eat right bracket token. 2279 2280 // Don't worry about range checking the value here. That's handled by 2281 // the is*() predicates. 2282 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 2283 ARM_AM::no_shift, 0, false, S,E)); 2284 2285 // If there's a pre-indexing writeback marker, '!', just add it as a token 2286 // operand. 2287 if (Parser.getTok().is(AsmToken::Exclaim)) { 2288 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 2289 Parser.Lex(); // Eat the '!'. 2290 } 2291 2292 return false; 2293 } 2294 2295 // The register offset is optionally preceded by a '+' or '-' 2296 bool isNegative = false; 2297 if (Parser.getTok().is(AsmToken::Minus)) { 2298 isNegative = true; 2299 Parser.Lex(); // Eat the '-'. 2300 } else if (Parser.getTok().is(AsmToken::Plus)) { 2301 // Nothing to do. 2302 Parser.Lex(); // Eat the '+'. 2303 } 2304 2305 E = Parser.getTok().getLoc(); 2306 int OffsetRegNum = tryParseRegister(); 2307 if (OffsetRegNum == -1) 2308 return Error(E, "register expected"); 2309 2310 // If there's a shift operator, handle it. 2311 ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 2312 unsigned ShiftImm = 0; 2313 if (Parser.getTok().is(AsmToken::Comma)) { 2314 Parser.Lex(); // Eat the ','. 2315 if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 2316 return true; 2317 } 2318 2319 // Now we should have the closing ']' 2320 E = Parser.getTok().getLoc(); 2321 if (Parser.getTok().isNot(AsmToken::RBrac)) 2322 return Error(E, "']' expected"); 2323 Parser.Lex(); // Eat right bracket token. 2324 2325 Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 2326 ShiftType, ShiftImm, isNegative, 2327 S, E)); 2328 2329 // If there's a pre-indexing writeback marker, '!', just add it as a token 2330 // operand. 2331 if (Parser.getTok().is(AsmToken::Exclaim)) { 2332 Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 2333 Parser.Lex(); // Eat the '!'. 2334 } 2335 2336 return false; 2337} 2338 2339/// parseMemRegOffsetShift - one of these two: 2340/// ( lsl | lsr | asr | ror ) , # shift_amount 2341/// rrx 2342/// return true if it parses a shift otherwise it returns false. 2343bool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 2344 unsigned &Amount) { 2345 SMLoc Loc = Parser.getTok().getLoc(); 2346 const AsmToken &Tok = Parser.getTok(); 2347 if (Tok.isNot(AsmToken::Identifier)) 2348 return true; 2349 StringRef ShiftName = Tok.getString(); 2350 if (ShiftName == "lsl" || ShiftName == "LSL") 2351 St = ARM_AM::lsl; 2352 else if (ShiftName == "lsr" || ShiftName == "LSR") 2353 St = ARM_AM::lsr; 2354 else if (ShiftName == "asr" || ShiftName == "ASR") 2355 St = ARM_AM::asr; 2356 else if (ShiftName == "ror" || ShiftName == "ROR") 2357 St = ARM_AM::ror; 2358 else if (ShiftName == "rrx" || ShiftName == "RRX") 2359 St = ARM_AM::rrx; 2360 else 2361 return Error(Loc, "illegal shift operator"); 2362 Parser.Lex(); // Eat shift type token. 2363 2364 // rrx stands alone. 2365 Amount = 0; 2366 if (St != ARM_AM::rrx) { 2367 Loc = Parser.getTok().getLoc(); 2368 // A '#' and a shift amount. 2369 const AsmToken &HashTok = Parser.getTok(); 2370 if (HashTok.isNot(AsmToken::Hash)) 2371 return Error(HashTok.getLoc(), "'#' expected"); 2372 Parser.Lex(); // Eat hash token. 2373 2374 const MCExpr *Expr; 2375 if (getParser().ParseExpression(Expr)) 2376 return true; 2377 // Range check the immediate. 2378 // lsl, ror: 0 <= imm <= 31 2379 // lsr, asr: 0 <= imm <= 32 2380 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 2381 if (!CE) 2382 return Error(Loc, "shift amount must be an immediate"); 2383 int64_t Imm = CE->getValue(); 2384 if (Imm < 0 || 2385 ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 2386 ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 2387 return Error(Loc, "immediate shift value out of range"); 2388 Amount = Imm; 2389 } 2390 2391 return false; 2392} 2393 2394/// Parse a arm instruction operand. For now this parses the operand regardless 2395/// of the mnemonic. 2396bool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2397 StringRef Mnemonic) { 2398 SMLoc S, E; 2399 2400 // Check if the current operand has a custom associated parser, if so, try to 2401 // custom parse the operand, or fallback to the general approach. 2402 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 2403 if (ResTy == MatchOperand_Success) 2404 return false; 2405 // If there wasn't a custom match, try the generic matcher below. Otherwise, 2406 // there was a match, but an error occurred, in which case, just return that 2407 // the operand parsing failed. 2408 if (ResTy == MatchOperand_ParseFail) 2409 return true; 2410 2411 switch (getLexer().getKind()) { 2412 default: 2413 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 2414 return true; 2415 case AsmToken::Identifier: { 2416 if (!tryParseRegisterWithWriteBack(Operands)) 2417 return false; 2418 int Res = tryParseShiftRegister(Operands); 2419 if (Res == 0) // success 2420 return false; 2421 else if (Res == -1) // irrecoverable error 2422 return true; 2423 2424 // Fall though for the Identifier case that is not a register or a 2425 // special name. 2426 } 2427 case AsmToken::Integer: // things like 1f and 2b as a branch targets 2428 case AsmToken::Dot: { // . as a branch target 2429 // This was not a register so parse other operands that start with an 2430 // identifier (like labels) as expressions and create them as immediates. 2431 const MCExpr *IdVal; 2432 S = Parser.getTok().getLoc(); 2433 if (getParser().ParseExpression(IdVal)) 2434 return true; 2435 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2436 Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 2437 return false; 2438 } 2439 case AsmToken::LBrac: 2440 return parseMemory(Operands); 2441 case AsmToken::LCurly: 2442 return parseRegisterList(Operands); 2443 case AsmToken::Hash: 2444 // #42 -> immediate. 2445 // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 2446 S = Parser.getTok().getLoc(); 2447 Parser.Lex(); 2448 const MCExpr *ImmVal; 2449 if (getParser().ParseExpression(ImmVal)) 2450 return true; 2451 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2452 Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 2453 return false; 2454 case AsmToken::Colon: { 2455 // ":lower16:" and ":upper16:" expression prefixes 2456 // FIXME: Check it's an expression prefix, 2457 // e.g. (FOO - :lower16:BAR) isn't legal. 2458 ARMMCExpr::VariantKind RefKind; 2459 if (parsePrefix(RefKind)) 2460 return true; 2461 2462 const MCExpr *SubExprVal; 2463 if (getParser().ParseExpression(SubExprVal)) 2464 return true; 2465 2466 const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 2467 getContext()); 2468 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2469 Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 2470 return false; 2471 } 2472 } 2473} 2474 2475// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 2476// :lower16: and :upper16:. 2477bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 2478 RefKind = ARMMCExpr::VK_ARM_None; 2479 2480 // :lower16: and :upper16: modifiers 2481 assert(getLexer().is(AsmToken::Colon) && "expected a :"); 2482 Parser.Lex(); // Eat ':' 2483 2484 if (getLexer().isNot(AsmToken::Identifier)) { 2485 Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 2486 return true; 2487 } 2488 2489 StringRef IDVal = Parser.getTok().getIdentifier(); 2490 if (IDVal == "lower16") { 2491 RefKind = ARMMCExpr::VK_ARM_LO16; 2492 } else if (IDVal == "upper16") { 2493 RefKind = ARMMCExpr::VK_ARM_HI16; 2494 } else { 2495 Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 2496 return true; 2497 } 2498 Parser.Lex(); 2499 2500 if (getLexer().isNot(AsmToken::Colon)) { 2501 Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 2502 return true; 2503 } 2504 Parser.Lex(); // Eat the last ':' 2505 return false; 2506} 2507 2508const MCExpr * 2509ARMAsmParser::applyPrefixToExpr(const MCExpr *E, 2510 MCSymbolRefExpr::VariantKind Variant) { 2511 // Recurse over the given expression, rebuilding it to apply the given variant 2512 // to the leftmost symbol. 2513 if (Variant == MCSymbolRefExpr::VK_None) 2514 return E; 2515 2516 switch (E->getKind()) { 2517 case MCExpr::Target: 2518 llvm_unreachable("Can't handle target expr yet"); 2519 case MCExpr::Constant: 2520 llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 2521 2522 case MCExpr::SymbolRef: { 2523 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 2524 2525 if (SRE->getKind() != MCSymbolRefExpr::VK_None) 2526 return 0; 2527 2528 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 2529 } 2530 2531 case MCExpr::Unary: 2532 llvm_unreachable("Can't handle unary expressions yet"); 2533 2534 case MCExpr::Binary: { 2535 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 2536 const MCExpr *LHS = applyPrefixToExpr(BE->getLHS(), Variant); 2537 const MCExpr *RHS = BE->getRHS(); 2538 if (!LHS) 2539 return 0; 2540 2541 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 2542 } 2543 } 2544 2545 assert(0 && "Invalid expression kind!"); 2546 return 0; 2547} 2548 2549/// \brief Given a mnemonic, split out possible predication code and carry 2550/// setting letters to form a canonical mnemonic and flags. 2551// 2552// FIXME: Would be nice to autogen this. 2553StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 2554 unsigned &PredicationCode, 2555 bool &CarrySetting, 2556 unsigned &ProcessorIMod) { 2557 PredicationCode = ARMCC::AL; 2558 CarrySetting = false; 2559 ProcessorIMod = 0; 2560 2561 // Ignore some mnemonics we know aren't predicated forms. 2562 // 2563 // FIXME: Would be nice to autogen this. 2564 if ((Mnemonic == "movs" && isThumb()) || 2565 Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 2566 Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 2567 Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 2568 Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 2569 Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 2570 Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 2571 Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 2572 return Mnemonic; 2573 2574 // First, split out any predication code. Ignore mnemonics we know aren't 2575 // predicated but do have a carry-set and so weren't caught above. 2576 if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 2577 Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 2578 Mnemonic != "umlals" && Mnemonic != "umulls") { 2579 unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 2580 .Case("eq", ARMCC::EQ) 2581 .Case("ne", ARMCC::NE) 2582 .Case("hs", ARMCC::HS) 2583 .Case("cs", ARMCC::HS) 2584 .Case("lo", ARMCC::LO) 2585 .Case("cc", ARMCC::LO) 2586 .Case("mi", ARMCC::MI) 2587 .Case("pl", ARMCC::PL) 2588 .Case("vs", ARMCC::VS) 2589 .Case("vc", ARMCC::VC) 2590 .Case("hi", ARMCC::HI) 2591 .Case("ls", ARMCC::LS) 2592 .Case("ge", ARMCC::GE) 2593 .Case("lt", ARMCC::LT) 2594 .Case("gt", ARMCC::GT) 2595 .Case("le", ARMCC::LE) 2596 .Case("al", ARMCC::AL) 2597 .Default(~0U); 2598 if (CC != ~0U) { 2599 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 2600 PredicationCode = CC; 2601 } 2602 } 2603 2604 // Next, determine if we have a carry setting bit. We explicitly ignore all 2605 // the instructions we know end in 's'. 2606 if (Mnemonic.endswith("s") && 2607 !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" || 2608 Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 2609 Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 2610 Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 2611 Mnemonic == "vrsqrts" || Mnemonic == "srs" || 2612 (Mnemonic == "movs" && isThumb()))) { 2613 Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 2614 CarrySetting = true; 2615 } 2616 2617 // The "cps" instruction can have a interrupt mode operand which is glued into 2618 // the mnemonic. Check if this is the case, split it and parse the imod op 2619 if (Mnemonic.startswith("cps")) { 2620 // Split out any imod code. 2621 unsigned IMod = 2622 StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 2623 .Case("ie", ARM_PROC::IE) 2624 .Case("id", ARM_PROC::ID) 2625 .Default(~0U); 2626 if (IMod != ~0U) { 2627 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 2628 ProcessorIMod = IMod; 2629 } 2630 } 2631 2632 return Mnemonic; 2633} 2634 2635/// \brief Given a canonical mnemonic, determine if the instruction ever allows 2636/// inclusion of carry set or predication code operands. 2637// 2638// FIXME: It would be nice to autogen this. 2639void ARMAsmParser:: 2640getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 2641 bool &CanAcceptPredicationCode) { 2642 if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 2643 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 2644 Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 2645 Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 2646 Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" || 2647 Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 2648 Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 2649 Mnemonic == "eor" || Mnemonic == "smlal" || 2650 (Mnemonic == "mov" && !isThumbOne())) { 2651 CanAcceptCarrySet = true; 2652 } else { 2653 CanAcceptCarrySet = false; 2654 } 2655 2656 if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 2657 Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 2658 Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 2659 Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 2660 Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" || 2661 Mnemonic == "setend" || 2662 ((Mnemonic == "pld" || Mnemonic == "pli") && !isThumb()) || 2663 ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) 2664 && !isThumb()) || 2665 Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) { 2666 CanAcceptPredicationCode = false; 2667 } else { 2668 CanAcceptPredicationCode = true; 2669 } 2670 2671 if (isThumb()) 2672 if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 2673 Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 2674 CanAcceptPredicationCode = false; 2675} 2676 2677/// Parse an arm instruction mnemonic followed by its operands. 2678bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 2679 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2680 // Create the leading tokens for the mnemonic, split by '.' characters. 2681 size_t Start = 0, Next = Name.find('.'); 2682 StringRef Mnemonic = Name.slice(Start, Next); 2683 2684 // Split out the predication code and carry setting flag from the mnemonic. 2685 unsigned PredicationCode; 2686 unsigned ProcessorIMod; 2687 bool CarrySetting; 2688 Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 2689 ProcessorIMod); 2690 2691 Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 2692 2693 // FIXME: This is all a pretty gross hack. We should automatically handle 2694 // optional operands like this via tblgen. 2695 2696 // Next, add the CCOut and ConditionCode operands, if needed. 2697 // 2698 // For mnemonics which can ever incorporate a carry setting bit or predication 2699 // code, our matching model involves us always generating CCOut and 2700 // ConditionCode operands to match the mnemonic "as written" and then we let 2701 // the matcher deal with finding the right instruction or generating an 2702 // appropriate error. 2703 bool CanAcceptCarrySet, CanAcceptPredicationCode; 2704 getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 2705 2706 // If we had a carry-set on an instruction that can't do that, issue an 2707 // error. 2708 if (!CanAcceptCarrySet && CarrySetting) { 2709 Parser.EatToEndOfStatement(); 2710 return Error(NameLoc, "instruction '" + Mnemonic + 2711 "' can not set flags, but 's' suffix specified"); 2712 } 2713 // If we had a predication code on an instruction that can't do that, issue an 2714 // error. 2715 if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 2716 Parser.EatToEndOfStatement(); 2717 return Error(NameLoc, "instruction '" + Mnemonic + 2718 "' is not predicable, but condition code specified"); 2719 } 2720 2721 // Add the carry setting operand, if necessary. 2722 // 2723 // FIXME: It would be awesome if we could somehow invent a location such that 2724 // match errors on this operand would print a nice diagnostic about how the 2725 // 's' character in the mnemonic resulted in a CCOut operand. 2726 if (CanAcceptCarrySet) 2727 Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 2728 NameLoc)); 2729 2730 // Add the predication code operand, if necessary. 2731 if (CanAcceptPredicationCode) { 2732 Operands.push_back(ARMOperand::CreateCondCode( 2733 ARMCC::CondCodes(PredicationCode), NameLoc)); 2734 } 2735 2736 // Add the processor imod operand, if necessary. 2737 if (ProcessorIMod) { 2738 Operands.push_back(ARMOperand::CreateImm( 2739 MCConstantExpr::Create(ProcessorIMod, getContext()), 2740 NameLoc, NameLoc)); 2741 } else { 2742 // This mnemonic can't ever accept a imod, but the user wrote 2743 // one (or misspelled another mnemonic). 2744 2745 // FIXME: Issue a nice error. 2746 } 2747 2748 // Add the remaining tokens in the mnemonic. 2749 while (Next != StringRef::npos) { 2750 Start = Next; 2751 Next = Name.find('.', Start + 1); 2752 StringRef ExtraToken = Name.slice(Start, Next); 2753 2754 Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 2755 } 2756 2757 // Read the remaining operands. 2758 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2759 // Read the first operand. 2760 if (parseOperand(Operands, Mnemonic)) { 2761 Parser.EatToEndOfStatement(); 2762 return true; 2763 } 2764 2765 while (getLexer().is(AsmToken::Comma)) { 2766 Parser.Lex(); // Eat the comma. 2767 2768 // Parse and remember the operand. 2769 if (parseOperand(Operands, Mnemonic)) { 2770 Parser.EatToEndOfStatement(); 2771 return true; 2772 } 2773 } 2774 } 2775 2776 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2777 Parser.EatToEndOfStatement(); 2778 return TokError("unexpected token in argument list"); 2779 } 2780 2781 Parser.Lex(); // Consume the EndOfStatement 2782 2783 2784 // The 'mov' mnemonic is special. One variant has a cc_out operand, while 2785 // another does not. Specifically, the MOVW instruction does not. So we 2786 // special case it here and remove the defaulted (non-setting) cc_out 2787 // operand if that's the instruction we're trying to match. 2788 // 2789 // We do this post-processing of the explicit operands rather than just 2790 // conditionally adding the cc_out in the first place because we need 2791 // to check the type of the parsed immediate operand. 2792 if (Mnemonic == "mov" && Operands.size() > 4 && 2793 !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 2794 static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 2795 static_cast<ARMOperand*>(Operands[1])->getReg() == 0) { 2796 ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 2797 Operands.erase(Operands.begin() + 1); 2798 delete Op; 2799 } 2800 2801 // ARM mode 'blx' need special handling, as the register operand version 2802 // is predicable, but the label operand version is not. So, we can't rely 2803 // on the Mnemonic based checking to correctly figure out when to put 2804 // a CondCode operand in the list. If we're trying to match the label 2805 // version, remove the CondCode operand here. 2806 if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 2807 static_cast<ARMOperand*>(Operands[2])->isImm()) { 2808 ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 2809 Operands.erase(Operands.begin() + 1); 2810 delete Op; 2811 } 2812 return false; 2813} 2814 2815// Validate context-sensitive operand constraints. 2816// FIXME: We would really like to be able to tablegen'erate this. 2817bool ARMAsmParser:: 2818validateInstruction(MCInst &Inst, 2819 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2820 switch (Inst.getOpcode()) { 2821 case ARM::LDRD: 2822 case ARM::LDRD_PRE: 2823 case ARM::LDRD_POST: 2824 case ARM::LDREXD: { 2825 // Rt2 must be Rt + 1. 2826 unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 2827 unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 2828 if (Rt2 != Rt + 1) 2829 return Error(Operands[3]->getStartLoc(), 2830 "destination operands must be sequential"); 2831 return false; 2832 } 2833 case ARM::STRD: 2834 case ARM::STRD_PRE: 2835 case ARM::STRD_POST: 2836 case ARM::STREXD: { 2837 // Rt2 must be Rt + 1. 2838 unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 2839 unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 2840 if (Rt2 != Rt + 1) 2841 return Error(Operands[4]->getStartLoc(), 2842 "source operands must be sequential"); 2843 return false; 2844 } 2845 case ARM::SBFX: 2846 case ARM::UBFX: { 2847 // width must be in range [1, 32-lsb] 2848 unsigned lsb = Inst.getOperand(2).getImm(); 2849 unsigned widthm1 = Inst.getOperand(3).getImm(); 2850 if (widthm1 >= 32 - lsb) 2851 return Error(Operands[5]->getStartLoc(), 2852 "bitfield width must be in range [1,32-lsb]"); 2853 } 2854 } 2855 2856 return false; 2857} 2858 2859bool ARMAsmParser:: 2860MatchAndEmitInstruction(SMLoc IDLoc, 2861 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2862 MCStreamer &Out) { 2863 MCInst Inst; 2864 unsigned ErrorInfo; 2865 MatchResultTy MatchResult; 2866 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 2867 switch (MatchResult) { 2868 case Match_Success: 2869 // Context sensitive operand constraints aren't handled by the matcher, 2870 // so check them here. 2871 if (validateInstruction(Inst, Operands)) 2872 return true; 2873 2874 Out.EmitInstruction(Inst); 2875 return false; 2876 case Match_MissingFeature: 2877 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 2878 return true; 2879 case Match_InvalidOperand: { 2880 SMLoc ErrorLoc = IDLoc; 2881 if (ErrorInfo != ~0U) { 2882 if (ErrorInfo >= Operands.size()) 2883 return Error(IDLoc, "too few operands for instruction"); 2884 2885 ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 2886 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 2887 } 2888 2889 return Error(ErrorLoc, "invalid operand for instruction"); 2890 } 2891 case Match_MnemonicFail: 2892 return Error(IDLoc, "unrecognized instruction mnemonic"); 2893 case Match_ConversionFail: 2894 return Error(IDLoc, "unable to convert operands to instruction"); 2895 } 2896 2897 llvm_unreachable("Implement any new match types added!"); 2898 return true; 2899} 2900 2901/// parseDirective parses the arm specific directives 2902bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 2903 StringRef IDVal = DirectiveID.getIdentifier(); 2904 if (IDVal == ".word") 2905 return parseDirectiveWord(4, DirectiveID.getLoc()); 2906 else if (IDVal == ".thumb") 2907 return parseDirectiveThumb(DirectiveID.getLoc()); 2908 else if (IDVal == ".thumb_func") 2909 return parseDirectiveThumbFunc(DirectiveID.getLoc()); 2910 else if (IDVal == ".code") 2911 return parseDirectiveCode(DirectiveID.getLoc()); 2912 else if (IDVal == ".syntax") 2913 return parseDirectiveSyntax(DirectiveID.getLoc()); 2914 return true; 2915} 2916 2917/// parseDirectiveWord 2918/// ::= .word [ expression (, expression)* ] 2919bool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 2920 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2921 for (;;) { 2922 const MCExpr *Value; 2923 if (getParser().ParseExpression(Value)) 2924 return true; 2925 2926 getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 2927 2928 if (getLexer().is(AsmToken::EndOfStatement)) 2929 break; 2930 2931 // FIXME: Improve diagnostic. 2932 if (getLexer().isNot(AsmToken::Comma)) 2933 return Error(L, "unexpected token in directive"); 2934 Parser.Lex(); 2935 } 2936 } 2937 2938 Parser.Lex(); 2939 return false; 2940} 2941 2942/// parseDirectiveThumb 2943/// ::= .thumb 2944bool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 2945 if (getLexer().isNot(AsmToken::EndOfStatement)) 2946 return Error(L, "unexpected token in directive"); 2947 Parser.Lex(); 2948 2949 // TODO: set thumb mode 2950 // TODO: tell the MC streamer the mode 2951 // getParser().getStreamer().Emit???(); 2952 return false; 2953} 2954 2955/// parseDirectiveThumbFunc 2956/// ::= .thumbfunc symbol_name 2957bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 2958 const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 2959 bool isMachO = MAI.hasSubsectionsViaSymbols(); 2960 StringRef Name; 2961 2962 // Darwin asm has function name after .thumb_func direction 2963 // ELF doesn't 2964 if (isMachO) { 2965 const AsmToken &Tok = Parser.getTok(); 2966 if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 2967 return Error(L, "unexpected token in .thumb_func directive"); 2968 Name = Tok.getString(); 2969 Parser.Lex(); // Consume the identifier token. 2970 } 2971 2972 if (getLexer().isNot(AsmToken::EndOfStatement)) 2973 return Error(L, "unexpected token in directive"); 2974 Parser.Lex(); 2975 2976 // FIXME: assuming function name will be the line following .thumb_func 2977 if (!isMachO) { 2978 Name = Parser.getTok().getString(); 2979 } 2980 2981 // Mark symbol as a thumb symbol. 2982 MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 2983 getParser().getStreamer().EmitThumbFunc(Func); 2984 return false; 2985} 2986 2987/// parseDirectiveSyntax 2988/// ::= .syntax unified | divided 2989bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 2990 const AsmToken &Tok = Parser.getTok(); 2991 if (Tok.isNot(AsmToken::Identifier)) 2992 return Error(L, "unexpected token in .syntax directive"); 2993 StringRef Mode = Tok.getString(); 2994 if (Mode == "unified" || Mode == "UNIFIED") 2995 Parser.Lex(); 2996 else if (Mode == "divided" || Mode == "DIVIDED") 2997 return Error(L, "'.syntax divided' arm asssembly not supported"); 2998 else 2999 return Error(L, "unrecognized syntax mode in .syntax directive"); 3000 3001 if (getLexer().isNot(AsmToken::EndOfStatement)) 3002 return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 3003 Parser.Lex(); 3004 3005 // TODO tell the MC streamer the mode 3006 // getParser().getStreamer().Emit???(); 3007 return false; 3008} 3009 3010/// parseDirectiveCode 3011/// ::= .code 16 | 32 3012bool ARMAsmParser::parseDirectiveCode(SMLoc L) { 3013 const AsmToken &Tok = Parser.getTok(); 3014 if (Tok.isNot(AsmToken::Integer)) 3015 return Error(L, "unexpected token in .code directive"); 3016 int64_t Val = Parser.getTok().getIntVal(); 3017 if (Val == 16) 3018 Parser.Lex(); 3019 else if (Val == 32) 3020 Parser.Lex(); 3021 else 3022 return Error(L, "invalid operand to .code directive"); 3023 3024 if (getLexer().isNot(AsmToken::EndOfStatement)) 3025 return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 3026 Parser.Lex(); 3027 3028 if (Val == 16) { 3029 if (!isThumb()) { 3030 SwitchMode(); 3031 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 3032 } 3033 } else { 3034 if (isThumb()) { 3035 SwitchMode(); 3036 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 3037 } 3038 } 3039 3040 return false; 3041} 3042 3043extern "C" void LLVMInitializeARMAsmLexer(); 3044 3045/// Force static initialization. 3046extern "C" void LLVMInitializeARMAsmParser() { 3047 RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 3048 RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 3049 LLVMInitializeARMAsmLexer(); 3050} 3051 3052#define GET_REGISTER_MATCHER 3053#define GET_MATCHER_IMPLEMENTATION 3054#include "ARMGenAsmMatcher.inc" 3055