ARMAsmParser.cpp revision 70939ee1415722d7f39f13faf9b3644b96007996
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===// 2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// The LLVM Compiler Infrastructure 4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source 6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details. 7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// 8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===// 9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/ARMBaseInfo.h" 11ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h" 12ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h" 13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h" 14c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h" 15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h" 17642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h" 18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h" 19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h" 20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h" 2194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCRegisterInfo.h" 22ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 2394b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h" 24ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h" 25c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h" 26fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h" 2775ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h" 2894b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h" 29c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h" 300c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h" 31345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h" 32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 33ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 34ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 35ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 363a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 37146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 38146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand; 3916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4094b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser { 41ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng MCSubtargetInfo &STI; 42ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int tryParseRegister(); 511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 520d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 531355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 571355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach const MCExpr *applyPrefixToExpr(const MCExpr *E, 589081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant); 599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 60a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &ShiftAmount); 631355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveWord(unsigned Size, SMLoc L); 641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumb(SMLoc L); 651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumbFunc(SMLoc L); 661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveCode(SMLoc L); 671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveSyntax(SMLoc L); 68515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 705f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, unsigned &ProcessorIMod); 711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 72fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 7316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 74ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumb() const { 75ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 76ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 77ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 78ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumbOne() const { 79ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 80ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 8147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach bool isThumbTwo() const { 8247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2); 8347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 84194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach bool hasV6Ops() const { 85194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return STI.getFeatureBits() & ARM::HasV6Ops; 86194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach } 8732869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 88ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 89ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(FB); 9032869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 91ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 92a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 93a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 943483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 950692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 960692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 97a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 98a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 99a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 10043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocNumOperand( 101f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 10243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocRegOperand( 103f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 10443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemBarrierOptOperand( 1058bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 10643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseProcIFlagsOperand( 1078bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 10843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMSRMaskOperand( 1098bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 110f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 111f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef Op, int Low, int High); 112f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 113f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "lsl", 0, 31); 114f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 115f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 116f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "asr", 1, 32); 117f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 118c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 119580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 1207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 121293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 1227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 123251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 124ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 125ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 1261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 127ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 128548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 129548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1301355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 131ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1327b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1337b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1422fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, 1432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 14414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach bool cvtStrdPre(MCInst &Inst, unsigned Opcode, 14514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 146623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 147623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 148189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 149189610f9466686a91fb7d847b572e1645c785323Jim Grosbach bool validateInstruction(MCInst &Inst, 150189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 151f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach void processInstruction(MCInst &Inst, 152f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 153d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach bool shouldOmitCCOutOperand(StringRef Mnemonic, 154d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 155189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 156ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 15747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach enum ARMMatchResultTy { 158194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 159194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresV6, 160194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresThumb2 16147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach }; 16247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 163ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 16494b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 165ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 16632869205052430f45d598fba25ab878d8b29da2dEvan Cheng 167ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 168ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 169ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 170ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 1711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach // Implementation of the MCTargetAsmParser interface: 1721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 1731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseInstruction(StringRef Name, SMLoc NameLoc, 174189610f9466686a91fb7d847b572e1645c785323Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 1751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseDirective(AsmToken DirectiveID); 1761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach 17747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned checkTargetMatchPredicate(MCInst &Inst); 17847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 1791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool MatchAndEmitInstruction(SMLoc IDLoc, 1801355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach MCStreamer &Out); 182ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 18316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 18416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1853a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 1863a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 187a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 188a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 189146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 190762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 1918462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 192d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach CCOut, 193fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocNum, 194fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocReg, 195cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 196706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MemBarrierOpt, 1978462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 1987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIndexRegister, 199584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MSRMask, 200a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcIFlags, 2018462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 2028d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling RegisterList, 2030f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling DPRRegisterList, 2040f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling SPRRegisterList, 205e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftedRegister, 20692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ShiftedImmediate, 207580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImmediate, 2087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotateImmediate, 209293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach BitfieldDescriptor, 2108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 211a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 213762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 21424d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 215a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 217a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 2188462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 2198462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 2208462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 2218462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 222706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt Val; 223706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } MBOpt; 224706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 225706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes struct { 226fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 227fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 228fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 229fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 230a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 231a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 232a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 233a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 234584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 235584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 236584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 237584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 238a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 239a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 240a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 241a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 242a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 243a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 244a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 245a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2468155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 247cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 248cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 24916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2506a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 251a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 252a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 2537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 2547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // was specified. 2557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm; // Offset immediate value 2567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 2577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 2580d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm; // shift for OffsetReg. 2597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 260a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 2610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 2637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned RegNum; 264f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isAdd; 265f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 266f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm; 2677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } PostIdxReg; 2687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach struct { 270580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 271e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 272580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 273e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 274e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 275e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 276e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 277e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 278af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 27992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 28092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 28192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 28292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 283af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 2847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach struct { 2857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach unsigned Imm; 2867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } RotImm; 287293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach struct { 288293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned LSB; 289293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned Width; 290293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } Bitfield; 291a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 29216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 293146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 294146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 295762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 296762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 297762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 298762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 299762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 3008462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 3018462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 3028462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 303762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 3048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 305762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 306d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 307762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 308762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 309762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 3108d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling case RegisterList: 3110f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 3120f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: 31324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 3148d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 315fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 316fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 317fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 318fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 319762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 320762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 321762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 322706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 323706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 324706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 325762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 326762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 327762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 3287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach case PostIndexRegister: 3297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIdxReg = o.PostIdxReg; 3307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 331584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 332584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 333584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 334a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: 335a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 3360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 337580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 338580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 3390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 340e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 341af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 342e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 34392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 344af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 34592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 3467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach case RotateImmediate: 3477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotImm = o.RotImm; 3487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 349293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach case BitfieldDescriptor: 350293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Bitfield = o.Bitfield; 351293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 352762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 353762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 35416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 355762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 356762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 357762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 358762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 359a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3608462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 3618462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 3628462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 3638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 3648462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 365fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 366fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 367fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 368fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 369fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 370a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 371a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 372a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 373a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 374a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 375a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 3766aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 3777729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 378a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 379a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3805fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 3810f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling assert((Kind == RegisterList || Kind == DPRRegisterList || 3820f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind == SPRRegisterList) && "Invalid access!"); 38324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 3848d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 3858d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 386cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 387cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 388cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 389cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 390cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 391706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 392706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Kind == MemBarrierOpt && "Invalid access!"); 393706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 394706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 395706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 396a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 397a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Kind == ProcIFlags && "Invalid access!"); 398a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 399a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 400a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 401584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 402584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Kind == MSRMask && "Invalid access!"); 403584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 404584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 405584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 406fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocNum() const { return Kind == CoprocNum; } 407fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocReg() const { return Kind == CoprocReg; } 4088462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 409d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach bool isCCOut() const { return Kind == CCOut; } 4103483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 4116b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 4126b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 4136b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 4146b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4156b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 4166b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 4176b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 4186b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 41983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 42083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 42183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 42283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 42383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 42483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 42583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 42683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 42783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 42883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 42983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 43083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 43183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 43283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 43383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 43483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 4357c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 4367c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (Kind != Immediate) 4377c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 4387c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4397c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 4407c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 4417c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 4427c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 443f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 444f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (Kind != Immediate) 445f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 446f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 447f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 448f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 449f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 450f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 4514a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 4524a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (Kind != Immediate) 4534a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 4544a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4554a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 4564a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 4574a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 4584a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 459fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 460fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (Kind != Immediate) 461fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 462fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 463fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 464fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 465fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 466fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 467ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 468ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (Kind != Immediate) 469ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 470ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 471ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 472ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 473ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 474ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 475ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 476ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 477ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 478ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (Kind != Immediate) 479ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 480ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 481ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 482ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 483ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 484ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 48570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach bool isImmThumbSR() const { 48670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (Kind != Immediate) 48770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return false; 48870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 48970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (!CE) return false; 49070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach int64_t Value = CE->getValue(); 49170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return Value > 0 && Value < 33; 49270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 493f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 494f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 495f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 496f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 497f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 498f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 499f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 500f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 501f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 502f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 503f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 504f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 505f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 506f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 507f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 508f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 5096bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 5106bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (Kind != Immediate) 5116bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 5126bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5136bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 5146bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 5156bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 5166bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 5176b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 5186b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 5196b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 5206b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5216b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 5226b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 5236b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 5246b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 525c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 526c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Kind != Immediate) 527c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 528c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 529c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 530c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 531c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 532c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 533b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling bool isReg() const { return Kind == Register; } 5348d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling bool isRegList() const { return Kind == RegisterList; } 5350f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isDPRRegList() const { return Kind == DPRRegisterList; } 5360f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isSPRRegList() const { return Kind == SPRRegisterList; } 53714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isToken() const { return Kind == Token; } 538706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 53914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemory() const { return Kind == Memory; } 540580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isShifterImm() const { return Kind == ShifterImmediate; } 541af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedReg() const { return Kind == ShiftedRegister; } 542af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedImm() const { return Kind == ShiftedImmediate; } 5437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach bool isRotImm() const { return Kind == RotateImmediate; } 544293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach bool isBitfield() const { return Kind == BitfieldDescriptor; } 545f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxRegShifted() const { return Kind == PostIndexRegister; } 546f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxReg() const { 547f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach return Kind == PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift; 548f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 5497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemNoOffset() const { 5507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 551ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 5527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // No offset of any kind. 5537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0; 554ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 5557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode2() const { 5567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 557ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 5587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 5597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return true; 5607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 5617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 5627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 5637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 5647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 565039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach bool isAM2OffsetImm() const { 566039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Kind != Immediate) 567039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return false; 568039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Immediate offset in range [-4095, 4095]. 569039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 570039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (!CE) return false; 571039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int64_t Val = CE->getValue(); 572039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return Val > -4096 && Val < 4096; 573039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 5742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAddrMode3() const { 5752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind != Memory) 5762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 5772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // No shifts are legal for AM3. 5782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Mem.ShiftType != ARM_AM::no_shift) return false; 5792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Check for register offset. 5802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Mem.OffsetRegNum) return true; 5812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 5822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!Mem.OffsetImm) return true; 5832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 5842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return Val > -256 && Val < 256; 5852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 5862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAM3Offset() const { 5872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind != Immediate && Kind != PostIndexRegister) 5882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 5892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind == PostIndexRegister) 5902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return PostIdxReg.ShiftTy == ARM_AM::no_shift; 5912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 5922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!CE) return false; 5942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = CE->getValue(); 595251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Special case, #-0 is INT32_MIN. 596251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return (Val > -256 && Val < 256) || Val == INT32_MIN; 5972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 5987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode5() const { 5997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 600ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 6017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 6027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return false; 6037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-1020, 1020] and a multiple of 4. 6047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val >= -1020 && Val <= 1020 && ((Val & 3) == 0); 6077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 6087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemRegOffset() const { 6097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || !Mem.OffsetRegNum) 610ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 611ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 612ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 6137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemThumbRR() const { 6147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Thumb reg+reg addressing is simple. Just two registers, a base and 6157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // an offset. No shifts, negations or any other complicating factors. 6167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative || 6177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Mem.ShiftType != ARM_AM::no_shift) 61887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 619505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes return true; 620505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 6217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm8Offset() const { 6227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 623f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 6247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-255, 255]. 6257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -256 && Val < 256; 628f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 6297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm12Offset() const { 63009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 63109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 63209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // and we reject it. 63309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach if (Kind == Immediate && !isa<MCConstantExpr>(getImm())) 63409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return true; 63509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 6367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 637ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 6387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 6397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 6427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 6437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxImm8() const { 6447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Immediate) 6457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 6467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 647ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 6487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = CE->getValue(); 6497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -256 && Val < 256; 650ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 6517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 652584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes bool isMSRMask() const { return Kind == MSRMask; } 653a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool isProcIFlags() const { return Kind == ProcIFlags; } 6543483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 6553483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 65614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 65714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 65814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 65914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 6603483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 6613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 6623483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 6633483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 6643483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 6658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 666345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 6678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 66804f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 66904f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 6708462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 6718462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 672fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 673fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 674fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 675fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 676fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 677fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 678fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 679fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 680fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 681fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 682d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 683d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 684d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 685d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 686d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 687a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 688a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 689a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 690a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 691a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 692af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 693e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 694af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 695af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 696af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 697e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 698af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 699e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 700e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 701af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 702152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 703af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 704af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 70592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 706af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 70792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 70892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 70992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 710580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 7110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 712580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 713580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 7140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 7150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 71687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 7177729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 7185fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 7195fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 7207729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 7217729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 72287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 72387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 7240f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 7250f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 7260f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 7270f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 7280f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 7290f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 7300f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 7310f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 7327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 7337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 7357e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 7367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 7377e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 738293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 739293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 740293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 741293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 742293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 743293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 744293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 745293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 746293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 747293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 748293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 7493483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 7506b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7516b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 7526b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 7536b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 7546b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 7556b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7566b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 7576b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 7586b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 75983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_7Operands(MCInst &Inst, unsigned N) const { 76083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 76183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 76283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 76383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 76483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_15Operands(MCInst &Inst, unsigned N) const { 7657c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7667c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach addExpr(Inst, getImm()); 7677c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 7687c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach 7697c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach void addImm0_31Operands(MCInst &Inst, unsigned N) const { 77083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 77183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 77283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 77383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 774f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 775f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 776f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 777f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 778f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 779f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 780f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 781f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 7824a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 7834a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 7844a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 7854a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 7864a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 7874a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 7884a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 7894a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 790fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 791fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 792fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach addExpr(Inst, getImm()); 793fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 794fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach 795ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 796ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 797ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach addExpr(Inst, getImm()); 798ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 799ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach 800ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach void addImm24bitOperands(MCInst &Inst, unsigned N) const { 801ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 802ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach addExpr(Inst, getImm()); 80370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 80470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach 80570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 80670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 80770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // The constant encodes as the immediate, except for 32, which encodes as 80870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // zero. 80970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 81070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach unsigned Imm = CE->getValue(); 81170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 812ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 813ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 814f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 815f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 816f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach addExpr(Inst, getImm()); 817f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 818f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 819f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 820f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 821f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 822f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 823f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 824f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 825f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 826f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 827f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 8286bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 8296bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 8306bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach addExpr(Inst, getImm()); 8316bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 8326bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach 8336b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 8343483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 8353483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 8363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 83716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 838c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 839c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 840c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach addExpr(Inst, getImm()); 841c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 842c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 843706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 844706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 845706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 846706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 847706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 8487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 8497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 8507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 851505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 852505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 8537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 8547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 8557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 8567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetRegNum) { 8577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 8587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 8597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 8607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 8617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 8627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 8637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 8647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 8657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 866dd32ba337aab88c215108ca8bf4a0267fce1e773Jim Grosbach Mem.ShiftImm, Mem.ShiftType); 867ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 8687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 8697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 8707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 871ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 872ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 873039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 874039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 875039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 876039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 877039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 878039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 879039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 880039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 881039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 882039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 883039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 884039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 885039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 886039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 8872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 8882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 8892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 8902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!Mem.OffsetRegNum) { 8912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 8922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 8932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 8942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 8952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 8962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } else { 8972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // For register offset, we encode the shift type and negation flag 8982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // here. 8992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 9002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 9032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 9042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 9062fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 9072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 9082fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind == PostIndexRegister) { 9092fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = 9102fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 9112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 9122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 913251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return; 9142fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9152fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 9162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Constant offset. 9172fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 9182fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = CE->getValue(); 9192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 9202fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 9212fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 9222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 923251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 9242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 9252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 9262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 9287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 9297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 9307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 9317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0; 9327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 9337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 9347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 9357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 9367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 9377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 9397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 9407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 9417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 9427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 9437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 9447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 946ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 947ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 9487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 9497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 95009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If this is an immediate, it's a label reference. 95109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach if (Kind == Immediate) { 95209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach addExpr(Inst, getImm()); 95309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 95409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return; 95509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach } 95609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 95709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // Otherwise, it's a normal memory reg+offset. 9587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 9597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 9617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 96292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 9637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 9647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 9657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 9660d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Mem.ShiftImm, Mem.ShiftType); 9677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 9697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 9707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 971d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 9727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 9737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 9747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 97614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 9773483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 9787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 9797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 9807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 9817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 9827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 9837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 9847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 9857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 986f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 987ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 9887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 9897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 9907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 991f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 992f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 993f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 994f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 995f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 996f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 997f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // The sign, shift type, and shift amount are encoded in a single operand 998f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // using the AM2 encoding helpers. 999f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 1000f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 1001f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach PostIdxReg.ShiftTy); 1002f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1003ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 1004ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 1005584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 1006584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1007584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 1008584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1009584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1010a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 1011a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1012a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 1013a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1014a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1015b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 1016b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 10173a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 10183a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(CondCode); 1019345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 1020345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 1021345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 10223a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1023345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 1024345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1025fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 1026fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocNum); 1027fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1028fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1029fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1030fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1031fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1032fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1033fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 1034fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocReg); 1035fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1036fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1037fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1038fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1039fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1040fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1041d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 1042d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach ARMOperand *Op = new ARMOperand(CCOut); 1043d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 1044d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 1045d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 1046d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 1047d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1048d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 10493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 10503a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Token); 1051762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 1052762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 1053762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1054762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 10553a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1056a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1057a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 105850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 10593a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Register); 1060762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 1061762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1062762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 10633a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1064a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1065a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1066e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1067e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 1068e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 1069e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 1070e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 1071e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARMOperand *Op = new ARMOperand(ShiftedRegister); 1072af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 1073af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 1074af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 1075af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 1076e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 1077e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 1078e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 1079e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1080e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 108192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 108292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 108392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 108492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 108592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARMOperand *Op = new ARMOperand(ShiftedImmediate); 1086af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 1087af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 1088af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 108992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 109092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 109192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 109292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 109392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1094580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 10950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 1096580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ARMOperand *Op = new ARMOperand(ShifterImmediate); 1097580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 1098580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 10990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 11000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 11010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 11020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 11030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 11047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 11057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach ARMOperand *Op = new ARMOperand(RotateImmediate); 11067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 11077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 11087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 11097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 11107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 11117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1112293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1113293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 1114293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach ARMOperand *Op = new ARMOperand(BitfieldDescriptor); 1115293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 1116293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 1117293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 1118293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 1119293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 1120293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1121293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 11227729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 11235fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1124cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 11250f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling KindTy Kind = RegisterList; 11260f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 1127275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng if (llvm::ARMMCRegisterClasses[ARM::DPRRegClassID]. 1128275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 11290f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = DPRRegisterList; 1130275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng else if (llvm::ARMMCRegisterClasses[ARM::SPRRegClassID]. 1131275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 11320f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = SPRRegisterList; 11330f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 11340f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 11355fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 11367729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 113724d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 1138cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1139cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 1140cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 11418d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 11428d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 11438d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 11443a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 11453a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Immediate); 1146762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1147762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1148762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 11493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1150cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1151cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 11527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 11537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 11547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 11557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 11560d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm, 11577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 11583a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 11593a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Memory); 1160762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 11617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetImm = OffsetImm; 11627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetRegNum = OffsetRegNum; 1163762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 11640d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Op->Mem.ShiftImm = ShiftImm; 11657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.isNegative = isNegative; 11667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 11677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 11687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 11697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 117016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1171f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1172f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy, 1173f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm, 11747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 11757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARMOperand *Op = new ARMOperand(PostIndexRegister); 11767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 1177f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.isAdd = isAdd; 1178f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftTy = ShiftTy; 1179f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftImm = ShiftImm; 1180762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1181762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 11823a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1184706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1185706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 1186706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MemBarrierOpt); 1187706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 1188706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 1189706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 1190706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 1191706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1192a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1193a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 1194a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(ProcIFlags); 1195a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 1196a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 1197a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 1198a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 1199a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1200584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1201584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 1202584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MSRMask); 1203584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 1204584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 1205584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 1206584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 1207584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1208a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 1209a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 1211a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1212b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 1213fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 1214fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 12156a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1216fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1217d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 1218d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 1219d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 1220fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 1221fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 1222fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1223fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 1224fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 1225fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1226584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 1227584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 1228584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 1229fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 1230fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 1231fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1232706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 1233706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1234706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 1235fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 12366ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 12377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach << " base:" << Mem.BaseRegNum; 12386ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 1239fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 12407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach case PostIndexRegister: 1241f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 1242f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.RegNum; 1243f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 1244f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 1245f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.ShiftImm; 1246f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ">"; 12477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 1248a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: { 1249a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 1250a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 1251a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 1252a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 1253a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 1254a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 1255a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 1256a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1257fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 125850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 1259fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1260580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 1261580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1262580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 1263e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 1264e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 126592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 1266af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedReg.SrcReg 1267af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1268af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << RegShiftedReg.ShiftReg << ", " 1269af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1270e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 12710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 127292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 127392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 1274af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedImm.SrcReg 1275af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1276af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 127792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ">"; 127892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 12797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach case RotateImmediate: 12807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 12817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 1282293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach case BitfieldDescriptor: 1283293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 1284293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 1285293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 12860f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case RegisterList: 12870f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 12880f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: { 12898d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 12908d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 12915fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 12925fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 12937729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 12947729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 12957729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 12968d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 12978d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 12988d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 12998d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 13008d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 1301fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 1302fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 1303fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1304fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 1305fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 13063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 13073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 13083483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 13093483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 13103483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 13113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 13123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 13133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 131469df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 131569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 13161355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 1317bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 1318bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 1319bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 1320bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 13219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 1322e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 1323e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 13243a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 13251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 132618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 13277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 1328d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 1329a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 1330a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 13310c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 13320c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 13330c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 13340c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 13350c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 13360c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 13370c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 13380c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 13390c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 13400c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 13410c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 13420c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 134369df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 1344b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 1345e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 1346e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 1347d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 134819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 134919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 135019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 135119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 135219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 13530d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 13540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 13550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 13560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 13570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 13580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 13590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 13600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 13610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 13620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 13630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 13640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 13650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 13660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 13670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 13680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 13690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 137019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 13710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1372e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 1373e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1374e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 1375e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 1376e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 1377eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 1378e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 1379e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1380e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 1381e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 1382e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 1383e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 1384e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 1385e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 1386e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 1387e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 1388e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 1389e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 1390e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 1391e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 1392e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 1393e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 139419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 139519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 139619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 139719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1398e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 1399e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 140019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 140119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 140219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 140319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1404e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 1405e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 1406e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 1407e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 1408e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 1409e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1410e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 141119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 141219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 1413e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1414e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 14151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 1416e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 141719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 141819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 141919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 142019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 142119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 142219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 1423e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 142419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 142519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1426e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1427e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 142892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 142992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1430af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 14310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 143292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 143392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 143492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 14350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 143619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 14370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 14380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 14390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 144050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 144150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 144250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 1443e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 1444e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 1445e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 144650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 14471355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1448e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 14491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 1450e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 145150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1452d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 145350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1454a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1455e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 1456e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 145750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 145850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 1459e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 146099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 146199e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 146250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1463a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1464a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1465fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1466fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1467fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 1468fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1469e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 1470e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 1471e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 1472e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 1473e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 1474fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 1475e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1476e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 1477e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1478e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 1479e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 1480e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 1481e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 1482e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 1483e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 1484e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 1485e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 1486e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 1487e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 1488e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1489e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1490e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 1491fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 1492e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1493e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 1494e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1495e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 1496e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 1497e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 1498e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 1499e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 1500e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 1501e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1502e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1503e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1504e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1505e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1506e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1507e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 150843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 1509fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1510fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1511f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 151243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1513e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 1514e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 1515e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1516e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1517fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 1518e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 1519f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1520e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1521e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 1522fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 1523f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1524fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 1525fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 152643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 1527fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1528fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1529f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 153043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1531fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1532fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1533fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1534fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1535fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 1536fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 1537f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1538fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1539fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1540fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 1541f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1542e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1543e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1544c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null. The first 1545c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called. 154650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 15471355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 154818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 1549a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 1550e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 155116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 15527729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling // Read the rest of the registers in the list. 15537729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling unsigned PrevRegNum = 0; 15545fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 1555d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 15567729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling do { 1557e717610f53e0465cde198536561a3c00ce29d59fBill Wendling bool IsRange = Parser.getTok().is(AsmToken::Minus); 15587729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.Lex(); // Eat non-identifier token. 1559d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 156018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 1561d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 1562c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 1563c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 156450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1565c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1566e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 15671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNum = tryParseRegister(); 1568c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 1569c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 157050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1571c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1572d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1573e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (IsRange) { 1574e717610f53e0465cde198536561a3c00ce29d59fBill Wendling int Reg = PrevRegNum; 1575e717610f53e0465cde198536561a3c00ce29d59fBill Wendling do { 1576e717610f53e0465cde198536561a3c00ce29d59fBill Wendling ++Reg; 1577e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(Reg, RegLoc)); 1578e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } while (Reg != RegNum); 1579e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } else { 1580e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(RegNum, RegLoc)); 1581e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1582e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1583e717610f53e0465cde198536561a3c00ce29d59fBill Wendling PrevRegNum = RegNum; 15847729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling } while (Parser.getTok().is(AsmToken::Comma) || 15857729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.getTok().is(AsmToken::Minus)); 1586e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1587e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Process the right curly brace of the list. 158818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 1589c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RCurlyTok.isNot(AsmToken::RCurly)) { 1590c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RCurlyTok.getLoc(), "'}' expected"); 159150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1592c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1593d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1594e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc E = RCurlyTok.getLoc(); 1595e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Parser.Lex(); // Eat right curly brace token. 159603f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1597e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Verify the register list. 15985fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 1599e717610f53e0465cde198536561a3c00ce29d59fBill Wendling RI = Registers.begin(), RE = Registers.end(); 1600e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 16017caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned HighRegNum = getARMRegisterNumbering(RI->first); 16028e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling bool EmittedWarning = false; 16038e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling 16047caebff83d90a59aa74876ff887e822387f479e0Bill Wendling DenseMap<unsigned, bool> RegMap; 16057caebff83d90a59aa74876ff887e822387f479e0Bill Wendling RegMap[HighRegNum] = true; 16067caebff83d90a59aa74876ff887e822387f479e0Bill Wendling 1607e717610f53e0465cde198536561a3c00ce29d59fBill Wendling for (++RI; RI != RE; ++RI) { 16087729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling const std::pair<unsigned, SMLoc> &RegInfo = *RI; 16097caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned Reg = getARMRegisterNumbering(RegInfo.first); 1610e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 16118e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (RegMap[Reg]) { 1612e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Error(RegInfo.second, "register duplicated in register list"); 161350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1614e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1615e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 16168e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (!EmittedWarning && Reg < HighRegNum) 1617e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Warning(RegInfo.second, 1618e717610f53e0465cde198536561a3c00ce29d59fBill Wendling "register not in ascending order in register list"); 1619e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 16208e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling RegMap[Reg] = true; 16218e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling HighRegNum = std::max(Reg, HighRegNum); 1622e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1623e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 162450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 162550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1626d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 1627d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 162843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 1629f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 163043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1631706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1632706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1633706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1634706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 1635706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1636706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 1637706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 1638706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 1639032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 1640706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 1641032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 1642706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 1643706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 1644032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 1645706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 1646032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 1647706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 1648706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 1649706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 1650706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1651706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 1652f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1653706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1654706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1655706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 1656f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1657706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 1658706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 165943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 1660a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 166143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1662a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1663a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1664a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1665a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 1666a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1667a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 1668a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 1669a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 1670a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("a", ARM_PROC::A) 1671a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("i", ARM_PROC::I) 1672a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("f", ARM_PROC::F) 1673a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 1674a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1675a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // If some specific iflag is already set, it means that some letter is 1676a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // present more than once, this is not acceptable. 1677a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Flag == ~0U || (IFlags & Flag)) 1678a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_NoMatch; 1679a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1680a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags |= Flag; 1681a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1682a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1683a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1684a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 1685a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 1686584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 1687584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 168843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 1689584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 169043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1691584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1692584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1693584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1694584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 1695584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1696584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 1697584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 1698584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 1699b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 1700584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 1701584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 1702584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1703584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 1704584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 1705584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1706584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 1707584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1708584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 1709584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 1710b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 1711584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 1712584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 1713584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1714584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 17154b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 1716584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 1717584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1718584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 1719584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0; // No flag 17204b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 1721584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 172256926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 172356926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 1724584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 1725584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 1726584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 1727584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 1728584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 1729584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 1730584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1731584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1732584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 1733584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 1734584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 1735584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1736584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 1737584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1738584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 1739584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1740584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1741584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 1742584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 1743584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 1744584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1745584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1746584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 1747584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 1748584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1749584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1750584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 1751584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 1752a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 1753a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1754f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1755f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 1756f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 1757f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1758f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1759f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1760f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1761f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1762f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 1763f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string LowerOp = LowercaseString(Op); 1764f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string UpperOp = UppercaseString(Op); 1765f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 1766f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1767f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1768f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1769f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 1770f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1771f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 1772f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1773f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1774f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1775f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1776f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 1777f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1778f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 1779f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 1780f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 1781f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 1782f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1783f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1784f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1785f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 1786f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 1787f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1788f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1789f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1790f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 1791f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 1792f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1793f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1794f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1795f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 1796f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1797f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 1798f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 1799f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1800c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1801c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1802c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1803c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 1804c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1805c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1806c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 1807c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1808c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 1809c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 1810c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 1811c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 1812c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 1813c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1814c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 1815c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1816c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 1817c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1818c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 1819c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 1820c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 1821c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 1822c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 1823c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1824580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 1825580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 1826580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 1827580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 1828580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 1829580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1830580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1831580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 1832580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 1833580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1834580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 1835580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1836580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1837580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 1838580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 1839580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 1840580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 1841580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 1842580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 1843580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 1844580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 1845580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1846580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1847580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 1848580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1849580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 1850580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1851580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1852580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1853580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1854580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 1855580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1856580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 1857580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 1858580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 1859580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 1860580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1861580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1862580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1863580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 1864580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 1865580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1866580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1867580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1868580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 1869580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 1870580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 1871580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 1872580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 1873580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1874580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1875580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // asr #32 encoded as asr #0. 1876580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 1877580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 1878580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 1879580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 1880580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 1881580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1882580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1883580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1884580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1885580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 1886580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 1887580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1888580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 1889580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 1890580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 18917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 18927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 18937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 18947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 18957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 18967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 18977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 18987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 18997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(S, "rotate operator 'ror' expected"); 19007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 19037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") { 19047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(S, "rotate operator 'ror' expected"); 19057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 19087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 19097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 19107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 19117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 19127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 19157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 19167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 19177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 19187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 19197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 19207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 19237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 19247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 19257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 19287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 19297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 19307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 19317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 19327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 19337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 19347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19357e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 19377e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 19387e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 19397e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 19407e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 19417e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 19427e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1943293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1944293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1945293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 1946293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 1947293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1948293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1949293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1950293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1951293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 1952293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1953293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 1954293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 1955293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 1956293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 1957293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1958293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1959293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 1960293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 1961293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 1962293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1963293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1964293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1965293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 1966293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 1967293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 1968293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 1969293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1970293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1971293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 1972293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1973293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 1974293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 1975293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 1976293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1977293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1978293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 1979293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1980293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1981293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1982293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1983293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 1984293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1985293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 1986293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 1987293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 1988293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1989293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1990293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 1991293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 1992293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 1993293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 1994293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1995293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 1996293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 1997293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 1998293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 1999293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 2000293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2001293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2002293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2003293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2004293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 2005293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2006293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 2007293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 2008293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 20097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 20107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 20117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2012f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // postidx_reg := '+' register {, shift} 2013f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | '-' register {, shift} 2014f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | register {, shift} 20157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 20167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 20177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 20187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 20197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 20207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 20217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 202216578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = true; 20237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 20247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 20257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 20267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 20277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 20287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 202916578b50889329eb62774148091ba0f38b681a09Jim Grosbach isAdd = false; 20307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 20317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 20327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 20337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 20347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 20357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 20367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 20377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 20387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 20397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 20407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 20417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2042f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 2043f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm = 0; 20440d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 20450d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Parser.Lex(); // Eat the ','. 20460d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 20470d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach return MatchOperand_ParseFail; 20480d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach } 2049f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 2050f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 2051f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ShiftImm, S, E)); 20527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 20537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 20547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 20557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2056251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2057251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2058251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2059251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // am3offset := '+' register 2060251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | '-' register 2061251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | register 2062251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # imm 2063251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # + imm 2064251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # - imm 2065251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2066251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 2067251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // in the case where there is no match, as other alternatives take other 2068251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // parse methods. 2069251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach AsmToken Tok = Parser.getTok(); 2070251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc S = Tok.getLoc(); 2071251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2072251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Do immediates first, as we always parse those if we have a '#'. 2073251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 2074251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '#'. 2075251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Explicitly look for a '-', as we need to encode negative zero 2076251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // differently. 2077251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isNegative = Parser.getTok().is(AsmToken::Minus); 2078251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCExpr *Offset; 2079251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (getParser().ParseExpression(Offset)) 2080251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2081251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 2082251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!CE) { 2083251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(S, "constant expression expected"); 2084251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2085251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2086251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Tok.getLoc(); 2087251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Negative zero is encoded as the flag value INT32_MIN. 2088251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int32_t Val = CE->getValue(); 2089251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (isNegative && Val == 0) 2090251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = INT32_MIN; 2091251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2092251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back( 2093251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 2094251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2095251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2096251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2097251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2098251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2099251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool haveEaten = false; 2100251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isAdd = true; 2101251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int Reg = -1; 2102251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Tok.is(AsmToken::Plus)) { 2103251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '+' token. 2104251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2105251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 2106251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '-' token. 2107251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach isAdd = false; 2108251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2109251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2110251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 2111251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Reg = tryParseRegister(); 2112251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Reg == -1) { 2113251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!haveEaten) 2114251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_NoMatch; 2115251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 2116251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2117251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2118251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2119251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2120251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 2121251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 0, S, E)); 2122251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2123251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2124251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach} 2125251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 21261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2127ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2128ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2129ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 21301355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2131ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2132ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2133ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 2134ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2135ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2136ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 21377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2138ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2139ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2140ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2141ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 2142548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 2143548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2144548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2145548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser:: 2146548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 2147548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2148548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach // Create a writeback register dummy placeholder. 2149548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2150548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2151548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 2152548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2153548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach return true; 2154548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach} 2155548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach 21561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2157ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2158ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2159ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 21601355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2161ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2162ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2163ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2164548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2165548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2166548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 21677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 21687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 21697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 21707b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 21717b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 21727b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one. 21737b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser:: 21747b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 21757b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 21767b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach // Create a writeback register dummy placeholder. 21777b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 21787b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 21797b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 21807b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 21817b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach return true; 21827b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach} 21837b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach 21847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 21857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 21867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 21877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 21887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 21897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 21907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2191ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 21927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 21937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 21947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 21957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 21967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 21977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 21987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2199ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2200ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2201ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2202ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 22037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 2204ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2205ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2206ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 22077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 22087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2210aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2211ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2212ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 22137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 22147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 22157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 22167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 22177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 22187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 22197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 22207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 2221aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 22227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 22237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 22247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 22257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 22267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 22277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 22297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 22307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 22317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 22327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 22337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 22347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 22357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 22367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2237ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2238ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2239ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2240ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 22417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 2242ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2243ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2244ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 22457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 22467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2247ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2248ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 22497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2250ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 22517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 22527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 22537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 22547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 22557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2256ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2257ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2258ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2259ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 22602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst. 22612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 22622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one. 22632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser:: 22642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode, 22652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Rt, Rt2 22672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 22682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 22692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Create a writeback register dummy placeholder. 22702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 22712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // addr 22722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 22732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // pred 22742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 22752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return true; 22762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach} 22772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 227814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst. 227914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 228014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one. 228114605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser:: 228214605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode, 228314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 228414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Create a writeback register dummy placeholder. 228514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 228614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt, Rt2 228714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 228814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 228914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // addr 229014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 229114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // pred 229214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 229314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return true; 229414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach} 229514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach 2296623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 2297623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2298623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2299623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser:: 2300623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 2301623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2302623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2303623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach // Create a writeback register dummy placeholder. 2304623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2305623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 2306623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2307623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach return true; 2308623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach} 2309623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 2310623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 2311e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 23129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 231350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 23147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2315762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 231618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 2317a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 2318762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2319b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 2320a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 232118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 23221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 23237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 23247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 2325a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 23260571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 23270571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 23280571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 23297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 23300571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 23317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 2332762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 2333b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 2334a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 23357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 23367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 0, false, S, E)); 233703f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 23387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 23397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 234050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 23417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 23427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 234350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 23447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If we have a '#' it's an immediate offset, else assume it's a register 23457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset. 23467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 23477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '#'. 23487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 234950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 23507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // FIXME: Special case #-0 so we can correctly set the U bit. 2351e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 23527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 23537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 23547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 235505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 23567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 23577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 23587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 23597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 23607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 23617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 23627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 23637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 23647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 23657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 23667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 23677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 236805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 23697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 23707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 23717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 23727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::no_shift, 0, false, S,E)); 2373a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 23747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 23757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 23767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 23777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 23787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 2379762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 23807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 23817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 23829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 2383d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 23847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 23857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 23867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 23877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 23887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 23897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 23907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 23917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 23927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 23939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 23947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 23957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 23967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 23977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 23987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 23997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 24007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 24010d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm = 0; 24027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 24037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 24040d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 24057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 24069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 240716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 24087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 24097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 24107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 24117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 24127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 24137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 24147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 24150d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach ShiftType, ShiftImm, isNegative, 24167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 24177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2418f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 2419f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // operand. 2420f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 2421f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 2422f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Parser.Lex(); // Eat the '!'. 2423f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 24249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 24259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 24269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 24279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 24287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 2429a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 2430a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 24317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 24327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 24337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 24347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 243518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2436a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 2437a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 243838e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 2439a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 24400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 2441a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 24420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 2443a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 24440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 2445a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 24460082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 2447a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 24480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 2449a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 24507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 2451b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 2452a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 24537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 24547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 24557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 24567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 24577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 24587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 24597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (HashTok.isNot(AsmToken::Hash)) 24607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 24617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 24629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 24637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 24647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 24657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 24667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 24677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 24687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 24697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 24707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 24717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 24727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 24737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 24747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 24757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 24767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 24777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 24787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 2479a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2480a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 2481a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2482a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 24839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 24849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 24851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2486fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 2487762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 2488fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2489fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 2490fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 2491f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 2492f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 2493fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 2494f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 2495f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 2496f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 2497f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 2498f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 2499fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2500a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 2501146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 2502146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 250350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 250419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 25051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 250650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 25070d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 250819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 25090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 251019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 251119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 2512e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2513e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 2514e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 251519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 251667b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 251767b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 2518515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 2519515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 2520515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 2521762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2522515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 252350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2524762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 252550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 252650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 252750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 2528a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 25291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 2530d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 25311355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 2532d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 2533079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 2534079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 2535762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2536b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2537515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 2538515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 253950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2540762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 254150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 254250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 25439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 25449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 25457597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 25467597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 25477597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 25481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 25499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 25509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25517597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 25527597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 25539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 25549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25557597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 25567597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 25579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 25587597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 25599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 25609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 2561a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2562a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2563a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 25641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 25657597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 25661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 25677597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 25689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 25708a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 25719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 25729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 25749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 25759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 25769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 25779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 25799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 25807597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 25819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 25827597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 25839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 25849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 25859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 25869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 25879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 25889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 25909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 25919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 25929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 25939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 25949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 25959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 25969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 25979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr * 25981355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachARMAsmParser::applyPrefixToExpr(const MCExpr *E, 25999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant) { 26009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // Recurse over the given expression, rebuilding it to apply the given variant 26019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // to the leftmost symbol. 26029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (Variant == MCSymbolRefExpr::VK_None) 26039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return E; 26049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim switch (E->getKind()) { 26069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Target: 26079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle target expr yet"); 26089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Constant: 26099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 26109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::SymbolRef: { 26129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 26139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (SRE->getKind() != MCSymbolRefExpr::VK_None) 26159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 26169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 26189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 26199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Unary: 26219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle unary expressions yet"); 26229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Binary: { 26249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 26251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach const MCExpr *LHS = applyPrefixToExpr(BE->getLHS(), Variant); 26269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *RHS = BE->getRHS(); 26279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (!LHS) 26289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 26299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 26319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 26329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 26339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim assert(0 && "Invalid expression kind!"); 26359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 26369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 26379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 2638352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 2639352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 2640352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 2641badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 26421355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 26435f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 26445f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 26455f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &ProcessorIMod) { 2646352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 2647352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 2648a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 2649352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2650badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 2651352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 2652352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 26535f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 26545f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 26555f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 26565f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 26575f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 26585f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 26595f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 26605f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 2661352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2662badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 26633f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 26643f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 2665ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 266671725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 266749f2ceddd25c75373f8a39fa25e8b9db33bcdaccJim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls") { 26683f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 26693f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 26703f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 26713f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 26723f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 26733f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 26743f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 26753f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 26763f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 26773f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 26783f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 26793f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 26803f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 26813f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 26823f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 26833f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 26843f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 26853f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 26863f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 26873f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 26883f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 26893f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 26903f00e317064560ad11168d22030416d853829f6eJim Grosbach } 269152925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 2692345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2693352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 2694352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 2695352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 2696352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" || 26975f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 26985f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 26995f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 2700e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || 2701e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 2702352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 2703352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 2704352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 2705352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2706a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 2707a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 2708a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 2709a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 2710a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 2711a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 2712a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 2713a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 2714a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 2715a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 2716a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 2717a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 2718a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2719a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2720a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2721352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2722352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 27233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 27243771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 27253771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 27263771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 27273771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 2728fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 27291355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 2730fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 2731eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 2732eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 2733eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 2734eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 2735be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" || 2736eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 2737eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 2738be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "eor" || Mnemonic == "smlal" || 2739194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // FIXME: We need a better way. This really confused Thumb2 2740194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // parsing for 'mov'. 2741ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng (Mnemonic == "mov" && !isThumbOne())) { 2742eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 2743eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } else { 2744eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 2745eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } 27463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 2747eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 2748eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 2749eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 2750eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 27515f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" || 2752c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Mnemonic == "setend" || 275348c693ff564c422153733424ab845106161430acJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli") && !isThumb()) || 2754e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) 2755e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach && !isThumb()) || 27565f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) { 27573771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 27583771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 27593771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 27603771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } 2761fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 2762ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (isThumb()) 2763fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 276463b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 2765fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 2766badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 2767badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2768d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 2769d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2770d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 2771d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 2772d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 2773d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 2774d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // operand if that's the instruction we're trying to match. 2775d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // 2776d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // We do this as post-processing of the explicit operands rather than just 2777d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // conditionally adding the cc_out in the first place because we need 2778d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // to check the type of the parsed immediate operand. 2779d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach if (Mnemonic == "mov" && Operands.size() > 4 && 2780d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 2781d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 2782d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 2783d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return true; 27843912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 27853912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 27863912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // when there are only two register operands. 27873912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 27883912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 27893912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 27903912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 27913912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach return true; 27923912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 2793d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return false; 2794d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach} 2795d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 2796badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 2797badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 2798badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2799badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 2800badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 2801ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 2802badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2803352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 2804352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 2805a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 2806352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 28071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 2808c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach ProcessorIMod); 2809badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2810ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 2811ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2812ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 2813ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 28149717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 28153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 28163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 28173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 28183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 28193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 28203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 28213771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 28223771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 28231355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 28243771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 282533c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 282633c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 282733c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 282833c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 2829ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 283033c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 283133c16a27370939de39679245c3dff72383c210bdJim Grosbach } 2832c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 2833c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 2834c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 2835c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 2836c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 2837c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 2838c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 283933c16a27370939de39679245c3dff72383c210bdJim Grosbach 28403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 28413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 28423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: It would be awesome if we could somehow invent a location such that 28433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // match errors on this operand would print a nice diagnostic about how the 28443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 's' character in the mnemonic resulted in a CCOut operand. 284533c16a27370939de39679245c3dff72383c210bdJim Grosbach if (CanAcceptCarrySet) 28463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 28473771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar NameLoc)); 28483771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 28493771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 28503771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 28513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 28523771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar ARMCC::CondCodes(PredicationCode), NameLoc)); 2853badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 2854345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2855a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 2856a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 2857a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 2858a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 2859a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 2860a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } else { 2861a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // This mnemonic can't ever accept a imod, but the user wrote 2862a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // one (or misspelled another mnemonic). 2863a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2864a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // FIXME: Issue a nice error. 2865a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2866a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2867345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 28685747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 28695747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 28705747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 2871a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 2872a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2873a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 28745747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 28755747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 28765747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 28775747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 2878a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 28791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 2880cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2881cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2882cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2883a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2884a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 2885b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 2886a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2887a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 28881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 2889cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2890cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2891cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2892a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2893a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 289416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2895cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 2896cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 289734e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 2898cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2899146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 290034e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 2901ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2902d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // Some instructions, mostly Thumb, have forms for the same mnemonic that 2903d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // do and don't have a cc_out optional-def operand. With some spot-checks 2904d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // of the operand list, we can figure out which variant we're trying to 2905d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // parse and adjust accordingly before actually matching. Reason number 2906d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // #317 the table driven matcher doesn't fit well with the ARM instruction 2907d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // set. 2908d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach if (shouldOmitCCOutOperand(Mnemonic, Operands)) { 2909ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 2910ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 2911ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 2912ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 2913ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2914cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 2915cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 2916cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 2917cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // a CondCode operand in the list. If we're trying to match the label 2918cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // version, remove the CondCode operand here. 2919cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 2920cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 2921cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 2922cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 2923cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 2924cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 2925857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach 2926857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // The vector-compare-to-zero instructions have a literal token "#0" at 2927857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // the end that comes to here as an immediate operand. Convert it to a 2928857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // token to play nicely with the matcher. 2929857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 2930857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 2931857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 2932857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 2933857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 2934857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if (CE && CE->getValue() == 0) { 2935857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.erase(Operands.begin() + 5); 2936857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 2937857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach delete Op; 2938857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 2939857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 29409898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 2941ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 2942ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 2943189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 2944189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 2945189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 2946189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 2947189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2948189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 29492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD: 29502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_PRE: 29512fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_POST: 2952189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 2953189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 2954189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 2955189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 2956189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 2957189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 2958189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 2959189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 2960189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 296114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach case ARM::STRD: { 296214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt2 must be Rt + 1. 296314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 296414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 296514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach if (Rt2 != Rt + 1) 296614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 296714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach "source operands must be sequential"); 296814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return false; 296914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach } 297053642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_PRE: 297153642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_POST: 2972189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 2973189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 2974189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 2975189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 2976189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 297714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 2978189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 2979189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 2980189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 2981fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 2982fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 2983fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 2984fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 2985fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 2986fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 2987fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 2988fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 298900c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach return false; 2990fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 2991189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 2992189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 2993189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 2994189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 2995189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 2996f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser:: 2997f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst, 2998f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2999f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach switch (Inst.getOpcode()) { 3000f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach case ARM::LDMIA_UPD: 3001f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // If this is a load of a single register via a 'pop', then we should use 3002f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 3003f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 3004f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst.getNumOperands() == 5) { 3005f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach MCInst TmpInst; 3006f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.setOpcode(ARM::LDR_POST_IMM); 3007f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 3008f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 3009f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 3010f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 3011f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 3012f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 3013f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 3014f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst = TmpInst; 3015f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 3016f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach break; 3017f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach case ARM::STMDB_UPD: 3018f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // If this is a store of a single register via a 'push', then we should use 3019f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 3020f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 3021f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst.getNumOperands() == 5) { 3022f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach MCInst TmpInst; 3023f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.setOpcode(ARM::STR_PRE_IMM); 3024f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 3025f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 3026f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 3027f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 3028f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 3029f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 3030f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst = TmpInst; 3031f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach } 3032f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach break; 303389e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach case ARM::tADDi8: 303489e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach // If the immediate is in the range 0-7, we really wanted tADDi3. 303589e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach if (Inst.getOperand(3).getImm() < 8) 303689e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach Inst.setOpcode(ARM::tADDi3); 303789e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach break; 3038f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 3039f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach} 3040f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 304147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 304247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward 304347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// API changes, though. Better way? 304447a0d52b69056250a1edaca8b28f705993094542Jim Grosbachnamespace llvm { 304547a0d52b69056250a1edaca8b28f705993094542Jim Grosbachextern MCInstrDesc ARMInsts[]; 304647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 304747a0d52b69056250a1edaca8b28f705993094542Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) { 304847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return ARMInsts[Opcode]; 304947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 305047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 305147a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 305247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // 16-bit thumb arithmetic instructions either require or preclude the 'S' 305347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // suffix depending on whether they're in an IT block or not. 3054194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach unsigned Opc = Inst.getOpcode(); 3055194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach MCInstrDesc &MCID = getInstDesc(Opc); 305647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 305747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.hasOptionalDef() && 305847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "optionally flag setting instruction missing optional def operand"); 305947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.NumOperands == Inst.getNumOperands() && 306047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "operand count mismatch!"); 306147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // Find the optional-def operand (cc_out). 306247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned OpNo; 306347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach for (OpNo = 0; 306447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 306547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ++OpNo) 306647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ; 306747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb1, reject it completely. 306847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 306947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_MnemonicFail; 307047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb2, which form is legal depends on whether we're 307147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // in an IT block. 307247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // FIXME: We don't yet do IT blocks, so just always consider it to be 307347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // that we aren't in one until we do. 307447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 307547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_RequiresITBlock; 307647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 3077194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Some high-register supporting Thumb1 encodings only allow both registers 3078194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // to be from r0-r7 when in Thumb2. 3079194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach else if (Opc == ARM::tADDhirr && isThumbOne() && 3080194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 3081194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(2).getReg())) 3082194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresThumb2; 3083194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Others only require ARMv6 or later. 3084194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach else if (Opc == ARM::tMOVr && isThumbOne() && 3085194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(0).getReg()) && 3086194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg())) 3087194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresV6; 308847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_Success; 308947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 309047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 3091fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 3092fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 3093fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 3094fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 3095fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 3096fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 309719cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned MatchResult; 3098193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 3099193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 310019cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 3101e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 3102189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 3103189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 3104189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (validateInstruction(Inst, Operands)) 3105189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 3106189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3107f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // Some instructions need post-processing to, for example, tweak which 3108f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // encoding is selected. 3109f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach processInstruction(Inst, Operands); 3110f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 3111fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 3112fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 3113e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 3114e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 3115e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 3116e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 3117e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 3118e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 3119e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 3120e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 312116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3122e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 3123e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 3124e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 312516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3126e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 3127e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 3128e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 312947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "invalid instruction"); 3130b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 3131b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar return Error(IDLoc, "unable to convert operands to instruction"); 313247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach case Match_RequiresITBlock: 313347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "instruction only valid inside IT block"); 3134194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresV6: 3135194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires ARMv6 or later"); 3136194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresThumb2: 3137194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires Thumb2"); 3138fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 313916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3140c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 3141146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 3142fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 3143fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 31441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 3145ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 3146ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 3147ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 31481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 3149515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 31501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 3151515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 31521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 3153515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 31541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 3155515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 31561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 3157ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 3158ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3159ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 31601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 3161ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 31621355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 3163ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 3164ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 3165ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 3166ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 3167ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 3168ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3169aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 3170ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3171ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 3172ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 317316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3174ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 3175ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 3176ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 3177b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3178ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 3179ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 3180ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3181b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3182ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 3183ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3184ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 31851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 3186515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 31871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 3188515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 3189515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 3190b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3191515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3192515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 3193515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 3194515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 3195515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3196515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3197515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 31981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 3199515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 32001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 32016469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 32026469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 32036469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 32046469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 32056469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 32066469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 32076469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 32086469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 32096469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 32106469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 32116469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 32126469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 32136469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 32146469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 3215515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 3216515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 3217b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3218515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 32196469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 32206469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 32216469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 32226469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 32236469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 3224642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 3225642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 3226642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 3227515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3228515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3229515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 32301355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 3231515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 32321355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 323318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3234515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 3235515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 323638e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 323758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 3238b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 323958c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 32409e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 3241515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 3242515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 3243515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3244515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 324518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 3246b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3247515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3248515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 3249515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 3250515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3251515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3252515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 32531355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 3254515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 32551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 325618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3257515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 3258515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 325918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 326058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 3261b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 326258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 3263b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3264515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 3265515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 3266515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3267515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 326818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 3269b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3270515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 327132869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 3272bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (!isThumb()) { 3273ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 3274bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 3275bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 327632869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 3277bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (isThumb()) { 3278ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 3279bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 3280bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 3281eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 32822a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 3283515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3284515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3285515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 328690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 328790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 32889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 3289ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 329094b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 329194b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 329290b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 3293ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 32943483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 32950692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 32960692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 32973483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 3298