ARMAsmParser.cpp revision 1e84f19337d44c04e74af4fb005550b525ef60e5
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" 2711e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach#include "llvm/ADT/BitVector.h" 2875ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h" 2994b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h" 30c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h" 310c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h" 32345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h" 33c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 34ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 35ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 36ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 373a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 38146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 39146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand; 4016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4194b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser { 42ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng MCSubtargetInfo &STI; 43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 50ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int tryParseRegister(); 521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 530d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 571355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach const MCExpr *applyPrefixToExpr(const MCExpr *E, 599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant); 609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 61a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &ShiftAmount); 641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveWord(unsigned Size, SMLoc L); 651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumb(SMLoc L); 661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumbFunc(SMLoc L); 671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveCode(SMLoc L); 681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveSyntax(SMLoc L); 69515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 701355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 715f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, unsigned &ProcessorIMod); 721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 73fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 7416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 75ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumb() const { 76ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 77ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 78ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 79ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumbOne() const { 80ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 81ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 8247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach bool isThumbTwo() const { 8347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2); 8447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 85194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach bool hasV6Ops() const { 86194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return STI.getFeatureBits() & ARM::HasV6Ops; 87194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach } 8832869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 89ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 90ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(FB); 9132869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 92ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 93a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 94a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 953483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 960692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 970692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 98a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 99a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 100a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 10143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocNumOperand( 102f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 10343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocRegOperand( 104f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 10543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemBarrierOptOperand( 1068bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 10743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseProcIFlagsOperand( 1088bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 10943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMSRMaskOperand( 1108bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 111f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 112f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef Op, int Low, int High); 113f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 114f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "lsl", 0, 31); 115f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 116f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 117f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "asr", 1, 32); 118f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 119c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 120580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 1217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 122293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 1237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 124251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 125ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 126ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 1271355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 128ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 129548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 130548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1311355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 132ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1337b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1347b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, 1442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 14514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach bool cvtStrdPre(MCInst &Inst, unsigned Opcode, 14614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 147623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 148623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 14988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode, 15088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 151189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 152189610f9466686a91fb7d847b572e1645c785323Jim Grosbach bool validateInstruction(MCInst &Inst, 153189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 154f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach void processInstruction(MCInst &Inst, 155f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 156d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach bool shouldOmitCCOutOperand(StringRef Mnemonic, 157d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 158189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 159ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 16047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach enum ARMMatchResultTy { 161194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 162194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresV6, 163194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresThumb2 16447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach }; 16547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 166ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 16794b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 168ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 16932869205052430f45d598fba25ab878d8b29da2dEvan Cheng 170ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 171ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 172ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 173ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 1741355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach // Implementation of the MCTargetAsmParser interface: 1751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 1761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseInstruction(StringRef Name, SMLoc NameLoc, 177189610f9466686a91fb7d847b572e1645c785323Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 1781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseDirective(AsmToken DirectiveID); 1791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach 18047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned checkTargetMatchPredicate(MCInst &Inst); 18147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 1821355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool MatchAndEmitInstruction(SMLoc IDLoc, 1831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach MCStreamer &Out); 185ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 18616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 18716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1883a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 1893a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 190a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 191a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 192146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 193762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 1948462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 195d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach CCOut, 196fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocNum, 197fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocReg, 198cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 199706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MemBarrierOpt, 2008462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 2017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIndexRegister, 202584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MSRMask, 203a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcIFlags, 2048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 2058d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling RegisterList, 2060f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling DPRRegisterList, 2070f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling SPRRegisterList, 208e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftedRegister, 20992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ShiftedImmediate, 210580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImmediate, 2117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotateImmediate, 212293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach BitfieldDescriptor, 2138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 214a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 215a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 216762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 21724d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 218a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 219a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 220a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 2218462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 2228462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 2238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 2248462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 225706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt Val; 226706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } MBOpt; 227706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 228706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes struct { 229fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 230fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 231fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 232fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 233a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 234a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 235a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 236a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 237584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 238584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 239584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 240584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 241a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 242a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 243a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 244a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 245a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 246a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 247a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 248a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2498155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 250cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 251cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 25216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2536a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 254a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 255a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 2567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 2577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // was specified. 2587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm; // Offset immediate value 2597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 2607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 2610d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm; // shift for OffsetReg. 2627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 263a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 2640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 2667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned RegNum; 267f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isAdd; 268f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 269f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm; 2707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } PostIdxReg; 2717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach struct { 273580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 274e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 275580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 276e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 277e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 278e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 279e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 280e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 281af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 28292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 28392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 28492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 28592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 286af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 2877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach struct { 2887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach unsigned Imm; 2897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } RotImm; 290293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach struct { 291293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned LSB; 292293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned Width; 293293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } Bitfield; 294a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 29516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 296146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 297146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 298762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 299762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 300762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 301762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 302762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 3038462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 3048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 3058462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 306762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 3078462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 308762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 309d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 310762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 311762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 312762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 3138d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling case RegisterList: 3140f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 3150f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: 31624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 3178d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 318fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 319fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 320fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 321fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 322762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 323762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 324762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 325706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 326706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 327706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 328762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 329762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 330762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 3317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach case PostIndexRegister: 3327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIdxReg = o.PostIdxReg; 3337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 334584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 335584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 336584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 337a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: 338a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 3390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 340580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 341580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 3420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 343e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 344af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 345e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 34692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 347af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 34892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 3497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach case RotateImmediate: 3507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotImm = o.RotImm; 3517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 352293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach case BitfieldDescriptor: 353293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Bitfield = o.Bitfield; 354293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 355762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 356762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 35716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 358762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 359762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 360762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 361762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 362a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 3648462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 3658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 3668462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 3678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 368fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 369fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 370fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 371fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 372fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 373a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 374a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 375a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 376a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 377a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 378a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 3796aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 3807729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 381a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 382a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3835fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 3840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling assert((Kind == RegisterList || Kind == DPRRegisterList || 3850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind == SPRRegisterList) && "Invalid access!"); 38624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 3878d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 3888d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 389cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 390cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 391cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 392cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 393cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 394706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 395706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Kind == MemBarrierOpt && "Invalid access!"); 396706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 397706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 398706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 399a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 400a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Kind == ProcIFlags && "Invalid access!"); 401a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 402a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 403a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 404584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 405584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Kind == MSRMask && "Invalid access!"); 406584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 407584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 408584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 409fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocNum() const { return Kind == CoprocNum; } 410fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocReg() const { return Kind == CoprocReg; } 4118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 412d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach bool isCCOut() const { return Kind == CCOut; } 4133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 4146b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 4156b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 4166b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 4176b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4186b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 4196b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 4206b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 4216b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 42283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 42383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 42483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 42583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 42683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 42783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 42883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 42983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 43083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 43183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 43283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 43383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 43483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 43583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 43683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 43783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 4387c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 4397c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (Kind != Immediate) 4407c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 4417c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4427c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 4437c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 4447c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 4457c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 446f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 447f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (Kind != Immediate) 448f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 449f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 450f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 451f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 452f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 453f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 4544a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 4554a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (Kind != Immediate) 4564a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 4574a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4584a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 4594a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 4604a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 4614a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 462fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 463fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (Kind != Immediate) 464fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 465fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 466fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 467fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 468fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 469fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 470ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 471ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (Kind != Immediate) 472ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 473ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 474ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 475ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 476ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 477ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 478ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 479ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 480ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 481ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (Kind != Immediate) 482ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 483ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 484ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 485ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 486ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 487ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 48870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach bool isImmThumbSR() const { 48970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (Kind != Immediate) 49070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return false; 49170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 49270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (!CE) return false; 49370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach int64_t Value = CE->getValue(); 49470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return Value > 0 && Value < 33; 49570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 496f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 497f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 498f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 499f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 500f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 501f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 502f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 503f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 504f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 505f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 506f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 507f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 508f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 509f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 510f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 511f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 5126bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 5136bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (Kind != Immediate) 5146bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 5156bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5166bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 5176bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 5186bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 5196bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 5206b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 5216b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 5226b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 5236b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5246b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 5256b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 5266b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 5276b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 528c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 529c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Kind != Immediate) 530c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 531c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 532c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 533c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 534c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 535c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 536b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling bool isReg() const { return Kind == Register; } 5378d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling bool isRegList() const { return Kind == RegisterList; } 5380f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isDPRRegList() const { return Kind == DPRRegisterList; } 5390f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isSPRRegList() const { return Kind == SPRRegisterList; } 54014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isToken() const { return Kind == Token; } 541706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 54214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemory() const { return Kind == Memory; } 543580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isShifterImm() const { return Kind == ShifterImmediate; } 544af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedReg() const { return Kind == ShiftedRegister; } 545af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedImm() const { return Kind == ShiftedImmediate; } 5467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach bool isRotImm() const { return Kind == RotateImmediate; } 547293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach bool isBitfield() const { return Kind == BitfieldDescriptor; } 548f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxRegShifted() const { return Kind == PostIndexRegister; } 549f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxReg() const { 550f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach return Kind == PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift; 551f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 5527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemNoOffset() const { 5537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 554ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 5557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // No offset of any kind. 5567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0; 557ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 5587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode2() const { 5597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 560ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 5617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 5627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return true; 5637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 5647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 5657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 5667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 5677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 568039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach bool isAM2OffsetImm() const { 569039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Kind != Immediate) 570039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return false; 571039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Immediate offset in range [-4095, 4095]. 572039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 573039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (!CE) return false; 574039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int64_t Val = CE->getValue(); 575039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return Val > -4096 && Val < 4096; 576039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 5772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAddrMode3() const { 5782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind != Memory) 5792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 5802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // No shifts are legal for AM3. 5812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Mem.ShiftType != ARM_AM::no_shift) return false; 5822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Check for register offset. 5832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Mem.OffsetRegNum) return true; 5842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 5852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!Mem.OffsetImm) return true; 5862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 5872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return Val > -256 && Val < 256; 5882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 5892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAM3Offset() const { 5902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind != Immediate && Kind != PostIndexRegister) 5912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 5922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind == PostIndexRegister) 5932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return PostIdxReg.ShiftTy == ARM_AM::no_shift; 5942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 5952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!CE) return false; 5972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = CE->getValue(); 598251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Special case, #-0 is INT32_MIN. 599251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return (Val > -256 && Val < 256) || Val == INT32_MIN; 6002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 6017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode5() const { 6027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 603ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 6047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 6057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return false; 6067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-1020, 1020] and a multiple of 4. 6077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val >= -1020 && Val <= 1020 && ((Val & 3) == 0); 6107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 6117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemRegOffset() const { 6127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || !Mem.OffsetRegNum) 613ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 614ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 615ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 6167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemThumbRR() const { 6177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Thumb reg+reg addressing is simple. Just two registers, a base and 6187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // an offset. No shifts, negations or any other complicating factors. 6197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative || 6207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Mem.ShiftType != ARM_AM::no_shift) 62187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 62260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return isARMLowRegister(Mem.BaseRegNum) && 62360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach (!Mem.OffsetRegNum || isARMLowRegister(Mem.OffsetRegNum)); 62460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 62560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach bool isMemThumbRIs4() const { 62660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || 62760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 62860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return false; 62960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach // Immediate offset, multiple of 4 in range [0, 124]. 63060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach if (!Mem.OffsetImm) return true; 63160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 632ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 124 && (Val % 4) == 0; 633ecd858968384be029574d845eb098d357049e02eJim Grosbach } 63438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach bool isMemThumbRIs2() const { 63538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || 63638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 63738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return false; 63838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach // Immediate offset, multiple of 4 in range [0, 62]. 63938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach if (!Mem.OffsetImm) return true; 64038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 64138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return Val >= 0 && Val <= 62 && (Val % 2) == 0; 64238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 64348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach bool isMemThumbRIs1() const { 64448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || 64548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 64648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return false; 64748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach // Immediate offset in range [0, 31]. 64848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach if (!Mem.OffsetImm) return true; 64948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 65048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return Val >= 0 && Val <= 31; 65148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 652ecd858968384be029574d845eb098d357049e02eJim Grosbach bool isMemThumbSPI() const { 653ecd858968384be029574d845eb098d357049e02eJim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || Mem.BaseRegNum != ARM::SP) 654ecd858968384be029574d845eb098d357049e02eJim Grosbach return false; 655ecd858968384be029574d845eb098d357049e02eJim Grosbach // Immediate offset, multiple of 4 in range [0, 1020]. 656ecd858968384be029574d845eb098d357049e02eJim Grosbach if (!Mem.OffsetImm) return true; 657ecd858968384be029574d845eb098d357049e02eJim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 658ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 659505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 6607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm8Offset() const { 6617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 662f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 6637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-255, 255]. 6647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -256 && Val < 256; 667f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 6687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm12Offset() const { 66909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 67009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 67109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // and we reject it. 67209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach if (Kind == Immediate && !isa<MCConstantExpr>(getImm())) 67309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return true; 67409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 6757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 676ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 6777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 6787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 6817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 6827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxImm8() const { 6837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Immediate) 6847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 6857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 686ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 6877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = CE->getValue(); 6887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -256 && Val < 256; 689ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 6907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 691584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes bool isMSRMask() const { return Kind == MSRMask; } 692a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool isProcIFlags() const { return Kind == ProcIFlags; } 6933483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 6943483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 69514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 69614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 69714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 69814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 6993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 7003483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 7013483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 7023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 7033483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 7048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 705345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 7068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 70704f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 70804f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 7098462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 7108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 711fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 712fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 713fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 714fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 715fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 716fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 717fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 718fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 719fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 720fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 721d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 722d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 723d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 724d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 725d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 726a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 727a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 728a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 729a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 730a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 731af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 732e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 733af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 734af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 735af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 736e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 737af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 738e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 739e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 740af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 741152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 742af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 743af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 74492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 745af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 74692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 74792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 74892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 749580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 7500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 751580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 752580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 7530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 7540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 75587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 7567729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 7575fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 7585fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 7597729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 7607729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 76187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 76287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 7630f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 7640f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 7650f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 7660f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 7670f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 7680f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 7690f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 7700f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 7717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 7727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 7747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 7757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 7767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 777293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 778293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 779293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 780293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 781293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 782293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 783293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 784293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 785293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 786293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 787293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 7883483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 7896b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7906b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 7916b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 7926b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 7936b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 7946b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7956b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 7966b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 7976b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 79883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_7Operands(MCInst &Inst, unsigned N) const { 79983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 80083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 80183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 80283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 80383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_15Operands(MCInst &Inst, unsigned N) const { 8047c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 8057c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach addExpr(Inst, getImm()); 8067c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 8077c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach 8087c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach void addImm0_31Operands(MCInst &Inst, unsigned N) const { 80983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 81083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 81183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 81283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 813f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 814f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 815f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 816f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 817f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 818f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 819f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 820f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 8214a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 8224a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 8234a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 8244a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 8254a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 8264a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 8274a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 8284a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 829fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 830fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 831fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach addExpr(Inst, getImm()); 832fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 833fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach 834ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 835ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 836ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach addExpr(Inst, getImm()); 837ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 838ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach 839ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach void addImm24bitOperands(MCInst &Inst, unsigned N) const { 840ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 841ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach addExpr(Inst, getImm()); 84270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 84370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach 84470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 84570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 84670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // The constant encodes as the immediate, except for 32, which encodes as 84770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // zero. 84870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 84970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach unsigned Imm = CE->getValue(); 85070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 851ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 852ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 853f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 854f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 855f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach addExpr(Inst, getImm()); 856f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 857f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 858f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 859f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 860f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 861f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 862f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 863f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 864f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 865f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 866f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 8676bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 8686bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 8696bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach addExpr(Inst, getImm()); 8706bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 8716bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach 8726b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 8733483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 8743483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 8753483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 87616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 877c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 878c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 879c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach addExpr(Inst, getImm()); 880c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 881c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 882706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 883706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 884706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 885706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 886706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 8877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 8887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 8897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 890505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 891505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 8927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 8937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 8947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 8957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetRegNum) { 8967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 8977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 8987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 8997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 9007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 9017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 9027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 9037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 9047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 905dd32ba337aab88c215108ca8bf4a0267fce1e773Jim Grosbach Mem.ShiftImm, Mem.ShiftType); 906ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 9077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 9097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 910ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 911ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 912039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 913039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 914039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 915039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 916039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 917039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 918039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 919039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 920039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 921039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 922039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 923039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 924039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 925039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 9262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 9272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 9282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 9292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!Mem.OffsetRegNum) { 9302fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 9312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 9322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 9332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 9342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 9352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } else { 9362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // For register offset, we encode the shift type and negation flag 9372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // here. 9382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 9392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9412fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 9422fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 9432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 9452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 9462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 9472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind == PostIndexRegister) { 9482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = 9492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 9502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 9512fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 952251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return; 9532fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 9552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Constant offset. 9562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 9572fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = CE->getValue(); 9582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 9592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 9602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 9612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 962251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 9632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 9642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 9652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 9677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 9687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 9697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 9707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0; 9717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 9727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 9737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 9747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 9757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 9767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 9787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 9797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 9807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 9817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 9827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 9837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 985ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 986ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 9877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 9887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 98909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If this is an immediate, it's a label reference. 99009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach if (Kind == Immediate) { 99109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach addExpr(Inst, getImm()); 99209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 99309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return; 99409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach } 99509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 99609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // Otherwise, it's a normal memory reg+offset. 9977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 9987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 10007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 100192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 10027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 10037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 10047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 10050d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Mem.ShiftImm, Mem.ShiftType); 10067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 10077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 10087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 10097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 1010d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 10117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 10127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 10137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 10147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 101514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 10163483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 101760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 101860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 101960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0; 102060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 102160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 102248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 102348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach 102438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 102538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 102638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 2) : 0; 102738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 102838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 102938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 103038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach 103148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 103248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 103348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue()) : 0; 103448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 103548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 103660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 103760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach 1038ecd858968384be029574d845eb098d357049e02eJim Grosbach void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 1039ecd858968384be029574d845eb098d357049e02eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1040ecd858968384be029574d845eb098d357049e02eJim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0; 1041ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1042ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1043ecd858968384be029574d845eb098d357049e02eJim Grosbach } 1044ecd858968384be029574d845eb098d357049e02eJim Grosbach 10457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 10467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 10477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 10487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 10497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 10507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 10517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 10527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1053f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1054ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 10557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 10567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 10577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1058f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 1059f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 1060f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 1061f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 1062f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1063f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1064f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // The sign, shift type, and shift amount are encoded in a single operand 1065f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // using the AM2 encoding helpers. 1066f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 1067f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 1068f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach PostIdxReg.ShiftTy); 1069f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1070ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 1071ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 1072584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 1073584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1074584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 1075584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1076584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1077a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 1078a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1079a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 1080a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1081a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1082b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 1083b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 10843a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 10853a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(CondCode); 1086345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 1087345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 1088345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 10893a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1090345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 1091345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1092fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 1093fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocNum); 1094fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1095fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1096fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1097fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1098fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1099fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1100fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 1101fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocReg); 1102fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1103fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1104fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1105fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1106fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1107fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1108d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 1109d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach ARMOperand *Op = new ARMOperand(CCOut); 1110d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 1111d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 1112d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 1113d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 1114d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1115d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 11163a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 11173a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Token); 1118762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 1119762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 1120762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1121762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 11223a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1123a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1124a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 112550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 11263a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Register); 1127762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 1128762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1129762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 11303a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1132a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1133e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1134e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 1135e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 1136e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 1137e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 1138e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARMOperand *Op = new ARMOperand(ShiftedRegister); 1139af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 1140af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 1141af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 1142af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 1143e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 1144e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 1145e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 1146e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1147e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 114892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 114992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 115092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 115192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 115292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARMOperand *Op = new ARMOperand(ShiftedImmediate); 1153af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 1154af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 1155af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 115692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 115792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 115892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 115992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 116092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1161580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 11620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 1163580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ARMOperand *Op = new ARMOperand(ShifterImmediate); 1164580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 1165580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 11660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 11670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 11680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 11690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 11700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 11717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 11727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach ARMOperand *Op = new ARMOperand(RotateImmediate); 11737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 11747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 11757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 11767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 11777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 11787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1179293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1180293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 1181293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach ARMOperand *Op = new ARMOperand(BitfieldDescriptor); 1182293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 1183293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 1184293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 1185293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 1186293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 1187293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1188293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 11897729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 11905fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1191cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 11920f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling KindTy Kind = RegisterList; 11930f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 1194275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng if (llvm::ARMMCRegisterClasses[ARM::DPRRegClassID]. 1195275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 11960f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = DPRRegisterList; 1197275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng else if (llvm::ARMMCRegisterClasses[ARM::SPRRegClassID]. 1198275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 11990f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = SPRRegisterList; 12000f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 12010f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 12025fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 12037729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 120424d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 1205cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1206cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 1207cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 12088d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 12098d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 12108d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 12113a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 12123a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Immediate); 1213762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1214762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1215762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 12163a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1217cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1218cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 12197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 12207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 12217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 12227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 12230d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm, 12247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 12253a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 12263a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Memory); 1227762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 12287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetImm = OffsetImm; 12297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetRegNum = OffsetRegNum; 1230762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 12310d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Op->Mem.ShiftImm = ShiftImm; 12327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.isNegative = isNegative; 12337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 12347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 12357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 12367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 123716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1238f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1239f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy, 1240f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm, 12417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 12427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARMOperand *Op = new ARMOperand(PostIndexRegister); 12437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 1244f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.isAdd = isAdd; 1245f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftTy = ShiftTy; 1246f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftImm = ShiftImm; 1247762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1248762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 12493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1250a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1251706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1252706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 1253706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MemBarrierOpt); 1254706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 1255706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 1256706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 1257706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 1258706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1259a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1260a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 1261a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(ProcIFlags); 1262a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 1263a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 1264a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 1265a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 1266a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1267584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1268584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 1269584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MSRMask); 1270584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 1271584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 1272584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 1273584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 1274584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1275a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 1276a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1277a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 1278a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1279b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 1280fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 1281fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 12826a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1283fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1284d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 1285d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 1286d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 1287fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 1288fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 1289fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1290fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 1291fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 1292fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1293584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 1294584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 1295584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 1296fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 1297fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 1298fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1299706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 1300706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1301706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 1302fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 13036ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 13047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach << " base:" << Mem.BaseRegNum; 13056ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 1306fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 13077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach case PostIndexRegister: 1308f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 1309f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.RegNum; 1310f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 1311f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 1312f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.ShiftImm; 1313f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ">"; 13147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 1315a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: { 1316a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 1317a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 1318a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 1319a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 1320a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 1321a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 1322a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 1323a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1324fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 132550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 1326fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1327580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 1328580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1329580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 1330e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 1331e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 133292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 1333af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedReg.SrcReg 1334af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1335af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << RegShiftedReg.ShiftReg << ", " 1336af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1337e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 13380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 133992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 134092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 1341af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedImm.SrcReg 1342af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1343af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 134492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ">"; 134592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 13467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach case RotateImmediate: 13477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 13487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 1349293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach case BitfieldDescriptor: 1350293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 1351293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 1352293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 13530f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case RegisterList: 13540f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 13550f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: { 13568d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 13578d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 13585fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 13595fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 13607729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 13617729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 13627729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 13638d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 13648d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 13658d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 13668d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 13678d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 1368fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 1369fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 1370fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1371fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 1372fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 13733483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 13743483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 13753483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 13763483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 13773483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 13783483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 13793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 13803483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 138169df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 138269df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 13831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 1384bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 1385bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 1386bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 1387bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 13889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 1389e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 1390e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 13913a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 13921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 139318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 13947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 1395d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 1396a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 1397a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 13980c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 13990c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 14000c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 14010c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 14020c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 14030c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 14040c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 14050c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 14060c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 14070c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 14080c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 14090c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 141069df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 1411b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 1412e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 1413e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 1414d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 141519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 141619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 141719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 141819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 141919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 14200d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 14210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 14220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 14230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 14240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 14250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 14260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 14270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 14280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 14290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 14300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 14310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 14320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 14330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 14340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 14350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 14360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 143719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 14380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1439e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 1440e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1441e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 1442e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 1443e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 1444eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 1445e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 1446e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1447e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 1448e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 1449e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 1450e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 1451e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 1452e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 1453e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 1454e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 1455e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 1456e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 1457e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 1458e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 1459e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 1460e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 146119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 146219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 146319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 146419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1465e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 1466e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 146719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 146819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 146919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 147019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1471e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 1472e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 1473e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 1474e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 1475e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 1476e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1477e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 147819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 147919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 1480e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1481e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 14821355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 1483e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 148419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 148519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 148619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 148719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 148819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 148919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 1490e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 149119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 149219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1493e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1494e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 149592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 149692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1497af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 14980082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 149992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 150092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 150192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 15020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 150319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 15040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 15050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 15060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 150750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 150850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 150950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 1510e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 1511e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 1512e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 151350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 15141355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1515e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 15161355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 1517e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 151850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1519d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 152050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1521a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1522e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 1523e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 152450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 152550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 1526e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 152799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 152899e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 152950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1530a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1531a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1532fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1533fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1534fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 1535fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1536e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 1537e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 1538e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 1539e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 1540e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 1541fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 1542e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1543e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 1544e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1545e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 1546e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 1547e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 1548e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 1549e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 1550e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 1551e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 1552e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 1553e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 1554e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 1555e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1556e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1557e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 1558fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 1559e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1560e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 1561e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1562e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 1563e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 1564e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 1565e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 1566e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 1567e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 1568e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1569e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1570e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1571e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1572e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1573e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1574e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 157543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 1576fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1577fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1578f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 157943904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1580e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 1581e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 1582e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1583e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1584fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 1585e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 1586f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1587e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1588e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 1589fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 1590f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1591fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 1592fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 159343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 1594fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1595fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1596f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 159743904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1598fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1599fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1600fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1601fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1602fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 1603fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 1604f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1605fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1606fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1607fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 1608f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1609e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1610e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1611c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null. The first 1612c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called. 161350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 16141355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 161518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 1616a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 1617e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 161816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 16197729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling // Read the rest of the registers in the list. 16207729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling unsigned PrevRegNum = 0; 16215fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 1622d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 16237729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling do { 1624e717610f53e0465cde198536561a3c00ce29d59fBill Wendling bool IsRange = Parser.getTok().is(AsmToken::Minus); 16257729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.Lex(); // Eat non-identifier token. 1626d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 162718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 1628d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 1629c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 1630c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 163150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1632c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1633e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 16341355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNum = tryParseRegister(); 1635c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 1636c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 163750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1638c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1639d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1640e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (IsRange) { 1641e717610f53e0465cde198536561a3c00ce29d59fBill Wendling int Reg = PrevRegNum; 1642e717610f53e0465cde198536561a3c00ce29d59fBill Wendling do { 1643e717610f53e0465cde198536561a3c00ce29d59fBill Wendling ++Reg; 1644e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(Reg, RegLoc)); 1645e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } while (Reg != RegNum); 1646e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } else { 1647e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(RegNum, RegLoc)); 1648e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1649e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1650e717610f53e0465cde198536561a3c00ce29d59fBill Wendling PrevRegNum = RegNum; 16517729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling } while (Parser.getTok().is(AsmToken::Comma) || 16527729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.getTok().is(AsmToken::Minus)); 1653e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1654e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Process the right curly brace of the list. 165518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 1656c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RCurlyTok.isNot(AsmToken::RCurly)) { 1657c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RCurlyTok.getLoc(), "'}' expected"); 165850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1659c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1660d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1661e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc E = RCurlyTok.getLoc(); 1662e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Parser.Lex(); // Eat right curly brace token. 166303f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1664e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Verify the register list. 16658e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling bool EmittedWarning = false; 166611e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach unsigned HighRegNum = 0; 166711e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach BitVector RegMap(32); 166811e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 166911e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach const std::pair<unsigned, SMLoc> &RegInfo = Registers[i]; 16707caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned Reg = getARMRegisterNumbering(RegInfo.first); 1671e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 16728e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (RegMap[Reg]) { 1673e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Error(RegInfo.second, "register duplicated in register list"); 167450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1675e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1676e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 16778e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (!EmittedWarning && Reg < HighRegNum) 1678e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Warning(RegInfo.second, 1679e717610f53e0465cde198536561a3c00ce29d59fBill Wendling "register not in ascending order in register list"); 1680e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 168111e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach RegMap.set(Reg); 16828e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling HighRegNum = std::max(Reg, HighRegNum); 1683e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1684e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 168550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 168650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1687d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 1688d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 168943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 1690f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 169143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1692706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1693706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1694706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1695706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 1696706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1697706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 1698706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 1699706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 1700032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 1701706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 1702032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 1703706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 1704706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 1705032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 1706706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 1707032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 1708706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 1709706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 1710706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 1711706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1712706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 1713f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1714706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1715706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1716706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 1717f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1718706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 1719706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 172043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 1721a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 172243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1723a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1724a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1725a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1726a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 1727a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1728a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 1729a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 1730a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 1731a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("a", ARM_PROC::A) 1732a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("i", ARM_PROC::I) 1733a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("f", ARM_PROC::F) 1734a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 1735a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1736a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // If some specific iflag is already set, it means that some letter is 1737a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // present more than once, this is not acceptable. 1738a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Flag == ~0U || (IFlags & Flag)) 1739a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_NoMatch; 1740a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1741a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags |= Flag; 1742a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1743a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1744a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1745a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 1746a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 1747584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 1748584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 174943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 1750584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 175143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1752584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1753584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1754584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1755584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 1756584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1757584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 1758584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 1759584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 1760b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 1761584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 1762584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 1763584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1764584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 1765584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 1766584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1767584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 1768584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1769584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 1770584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 1771b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 1772584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 1773584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 1774584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1775584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 17764b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 1777584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 1778584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1779584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 1780584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0; // No flag 17814b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 1782584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 178356926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 178456926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 1785584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 1786584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 1787584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 1788584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 1789584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 1790584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 1791584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1792584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1793584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 1794584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 1795584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 1796584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1797584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 1798584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1799584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 1800584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1801584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1802584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 1803584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 1804584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 1805584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1806584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1807584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 1808584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 1809584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1810584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1811584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 1812584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 1813a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 1814a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1815f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1816f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 1817f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 1818f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1819f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1820f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1821f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1822f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1823f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 1824f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string LowerOp = LowercaseString(Op); 1825f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string UpperOp = UppercaseString(Op); 1826f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 1827f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1828f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1829f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1830f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 1831f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1832f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 1833f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1834f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1835f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1836f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1837f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 1838f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1839f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 1840f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 1841f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 1842f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 1843f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1844f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1845f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1846f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 1847f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 1848f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1849f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1850f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1851f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 1852f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 1853f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1854f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1855f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1856f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 1857f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1858f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 1859f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 1860f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1861c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1862c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1863c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1864c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 1865c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1866c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1867c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 1868c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1869c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 1870c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 1871c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 1872c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 1873c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 1874c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1875c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 1876c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1877c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 1878c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1879c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 1880c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 1881c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 1882c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 1883c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 1884c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1885580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 1886580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 1887580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 1888580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 1889580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 1890580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1891580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1892580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 1893580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 1894580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1895580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 1896580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1897580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1898580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 1899580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 1900580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 1901580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 1902580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 1903580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 1904580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 1905580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 1906580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1907580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1908580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 1909580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1910580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 1911580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1912580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1913580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1914580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1915580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 1916580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1917580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 1918580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 1919580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 1920580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 1921580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1922580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1923580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1924580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 1925580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 1926580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1927580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1928580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1929580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 1930580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 1931580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 1932580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 1933580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 1934580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1935580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1936580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // asr #32 encoded as asr #0. 1937580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 1938580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 1939580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 1940580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 1941580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 1942580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1943580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1944580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1945580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1946580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 1947580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 1948580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1949580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 1950580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 1951580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 19527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 19537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 19547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 19557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 19567e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 19577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 19587e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 19597e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 19607e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(S, "rotate operator 'ror' expected"); 19617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 19647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") { 19657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(S, "rotate operator 'ror' expected"); 19667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19677e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 19697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 19707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 19717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 19727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 19737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 19767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 19777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 19787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 19797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 19807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 19817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 19847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 19857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 19867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 19897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 19907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 19917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 19927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 19937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 19947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 19957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 19987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 19997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 20007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 20017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 20027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 20037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 2004293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2005293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2006293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 2007293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 2008293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2009293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2010293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2011293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2012293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2013293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2014293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 2015293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2016293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 2017293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2018293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2019293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2020293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 2021293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2022293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 2023293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2024293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2025293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2026293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 2027293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 2028293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 2029293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 2030293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2031293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2032293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2033293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2034293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 2035293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 2036293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 2037293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2038293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2039293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2040293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2041293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2042293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2043293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2044293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2045293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2046293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 2047293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 2048293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2049293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2050293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2051293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 2052293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2053293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 2054293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2055293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2056293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2057293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 2058293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 2059293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 2060293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 2061293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2062293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2063293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2064293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2065293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 2066293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2067293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 2068293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 2069293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 20707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 20717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 20727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2073f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // postidx_reg := '+' register {, shift} 2074f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | '-' register {, shift} 2075f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | register {, shift} 20767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 20777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 20787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 20797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 20807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 20817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 20827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 208316578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = true; 20847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 20857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 20867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 20877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 20887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 20897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 209016578b50889329eb62774148091ba0f38b681a09Jim Grosbach isAdd = false; 20917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 20927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 20937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 20947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 20957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 20967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 20977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 20987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 20997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 21007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 21017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 21027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2103f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 2104f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm = 0; 21050d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 21060d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Parser.Lex(); // Eat the ','. 21070d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 21080d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach return MatchOperand_ParseFail; 21090d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach } 2110f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 2111f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 2112f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ShiftImm, S, E)); 21137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 21147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 21157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 21167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2117251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2118251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2119251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2120251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // am3offset := '+' register 2121251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | '-' register 2122251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | register 2123251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # imm 2124251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # + imm 2125251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # - imm 2126251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2127251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 2128251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // in the case where there is no match, as other alternatives take other 2129251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // parse methods. 2130251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach AsmToken Tok = Parser.getTok(); 2131251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc S = Tok.getLoc(); 2132251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2133251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Do immediates first, as we always parse those if we have a '#'. 2134251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 2135251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '#'. 2136251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Explicitly look for a '-', as we need to encode negative zero 2137251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // differently. 2138251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isNegative = Parser.getTok().is(AsmToken::Minus); 2139251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCExpr *Offset; 2140251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (getParser().ParseExpression(Offset)) 2141251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2142251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 2143251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!CE) { 2144251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(S, "constant expression expected"); 2145251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2146251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2147251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Tok.getLoc(); 2148251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Negative zero is encoded as the flag value INT32_MIN. 2149251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int32_t Val = CE->getValue(); 2150251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (isNegative && Val == 0) 2151251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = INT32_MIN; 2152251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2153251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back( 2154251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 2155251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2156251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2157251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2158251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2159251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2160251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool haveEaten = false; 2161251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isAdd = true; 2162251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int Reg = -1; 2163251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Tok.is(AsmToken::Plus)) { 2164251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '+' token. 2165251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2166251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 2167251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '-' token. 2168251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach isAdd = false; 2169251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2170251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2171251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 2172251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Reg = tryParseRegister(); 2173251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Reg == -1) { 2174251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!haveEaten) 2175251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_NoMatch; 2176251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 2177251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2178251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2179251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2180251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2181251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 2182251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 0, S, E)); 2183251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2184251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2185251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach} 2186251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 21871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2188ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2189ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2190ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 21911355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2192ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2193ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2194ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 2195ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2196ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2197ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 21987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2199ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2200ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2201ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2202ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 2203548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 2204548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2205548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2206548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser:: 2207548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 2208548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2209548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach // Create a writeback register dummy placeholder. 2210548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2211548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2212548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 2213548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2214548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach return true; 2215548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach} 2216548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach 22171355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2218ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2219ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2220ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 22211355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2222ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2223ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2224ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2225548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2226548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2227548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 22287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 22297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 22307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 22317b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 22327b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 22337b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one. 22347b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser:: 22357b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 22367b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22377b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach // Create a writeback register dummy placeholder. 22387b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 22397b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 22407b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 22417b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 22427b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach return true; 22437b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach} 22447b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach 22457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 22467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 22477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 22487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 22497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 22507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2252ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 22537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 22547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 22557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 22567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 22577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 22587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 22597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2260ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2261ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2262ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2263ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 22647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 2265ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2266ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2267ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 22687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 22697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2271aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2272ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2273ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 22747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 22757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 22767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 22777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 22787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 22797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 22807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 22817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 2282aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 22837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 22847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 22857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 22867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 22877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 22887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 22907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 22917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 22927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 22937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 22947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 22957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 22967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 22977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2298ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2299ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2300ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2301ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 23027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 2303ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2304ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2305ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 23067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 23077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2308ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2309ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 23107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2311ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 23127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 23137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 23147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 23157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 23167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2317ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2318ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2319ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2320ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 23212fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst. 23222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 23232fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one. 23242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser:: 23252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode, 23262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 23272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Rt, Rt2 23282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 23292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 23302fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Create a writeback register dummy placeholder. 23312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 23322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // addr 23332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 23342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // pred 23352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 23362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return true; 23372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach} 23382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 233914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst. 234014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 234114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one. 234214605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser:: 234314605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode, 234414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 234514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Create a writeback register dummy placeholder. 234614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 234714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt, Rt2 234814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 234914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 235014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // addr 235114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 235214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // pred 235314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 235414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return true; 235514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach} 235614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach 2357623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 2358623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2359623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2360623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser:: 2361623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 2362623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2363623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2364623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach // Create a writeback register dummy placeholder. 2365623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2366623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 2367623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2368623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach return true; 2369623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach} 2370623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 237188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst. 237288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 237388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one. 237488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser:: 237588ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode, 237688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 237788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The second source operand must be the same register as the destination 237888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // operand. 237988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach if (Operands.size() == 6 && 23807a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 23817a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->getReg()) && 23827a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 23837a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[4])->getReg())) { 238488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach Error(Operands[3]->getStartLoc(), 23857a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach "destination register must match source register"); 238688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return false; 238788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach } 238888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 238988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); 239088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1); 23917a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // If we have a three-operand form, use that, else the second source operand 23927a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // is just the destination operand again. 23937a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach if (Operands.size() == 6) 23947a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 23957a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach else 23967a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach Inst.addOperand(Inst.getOperand(0)); 239788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); 239888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach 239988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 240088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach} 2401623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 2402e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 24039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 240450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 24057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2406762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 240718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 2408a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 2409762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2410b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 2411a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 241218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 24131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 24147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 24157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 2416a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 24170571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 24180571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 24190571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 24207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 24210571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 24227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 2423762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 2424b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 2425a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 24267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 24277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 0, false, S, E)); 242803f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 24297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 24307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 243150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 24327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 24337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 243450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 24357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If we have a '#' it's an immediate offset, else assume it's a register 24367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset. 24377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 24387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '#'. 24397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 244050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 24417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // FIXME: Special case #-0 so we can correctly set the U bit. 2442e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 24437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 24447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 24457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 244605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 24477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 24487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 24497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 24507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 24517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 24527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 24537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 24547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 24557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 24567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 24577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 24587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 245905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 24607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 24617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 24627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 24637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::no_shift, 0, false, S,E)); 2464a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 24657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 24667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 24677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 24687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 24697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 2470762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 24717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 24727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 24739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 2474d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 24757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 24767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 24777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 24787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 24797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 24807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 24817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 24827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 24837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 24849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 24857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 24867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 24877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 24887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 24897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 24907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 24917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 24920d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm = 0; 24937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 24947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 24950d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 24967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 24979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 249816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 24997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 25007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 25017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 25027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 25037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 25047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 25057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 25060d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach ShiftType, ShiftImm, isNegative, 25077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 25087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2509f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 2510f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // operand. 2511f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 2512f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 2513f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Parser.Lex(); // Eat the '!'. 2514f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 25159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 25169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 25179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 25189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 25197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 2520a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 2521a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 25227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 25237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 25247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 25257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 252618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2527a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 2528a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 252938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 2530a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 25310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 2532a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 25330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 2534a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 25350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 2536a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 25370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 2538a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 25390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 2540a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 25417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 2542b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 2543a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 25447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 25457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 25467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 25477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 25487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 25497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 25507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (HashTok.isNot(AsmToken::Hash)) 25517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 25527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 25539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 25547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 25557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 25567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 25577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 25587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 25597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 25607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 25617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 25627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 25637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 25647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 25657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 25667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 25677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 25687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 25697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 2570a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2571a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 2572a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2573a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 25749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 25759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 25761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2577fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 2578762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 2579fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2580fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 2581fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 2582f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 2583f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 2584fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 2585f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 2586f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 2587f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 2588f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 2589f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 2590fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2591a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 2592146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 2593146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 259450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 259519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 25961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 259750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 25980d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 259919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 26000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 260119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 260219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 2603e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2604e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 2605e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 260619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 260767b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 260867b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 2609515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 2610515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 2611515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 2612762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2613515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 261450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2615762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 261650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 261750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 261850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 2619a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 26201355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 2621d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 26221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 2623d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 2624079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 2625079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 2626762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2627b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2628515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 2629515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 263050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2631762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 263250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 263350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 26349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 26359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 26367597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 26377597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 26387597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 26391355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 26409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 26419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26427597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 26437597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 26449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 26459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26467597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 26477597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 26489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 26497597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 26509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 26519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 2652a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2653a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2654a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 26551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 26567597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 26571355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 26587597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 26599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 26618a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 26629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 26639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 26659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 26669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 26679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 26689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 26709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 26717597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 26729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 26737597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 26749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 26759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 26769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 26779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 26789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 26799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 26819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 26829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 26839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 26849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 26859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 26869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 26879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr * 26891355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachARMAsmParser::applyPrefixToExpr(const MCExpr *E, 26909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant) { 26919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // Recurse over the given expression, rebuilding it to apply the given variant 26929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // to the leftmost symbol. 26939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (Variant == MCSymbolRefExpr::VK_None) 26949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return E; 26959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim switch (E->getKind()) { 26979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Target: 26989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle target expr yet"); 26999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Constant: 27009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 27019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::SymbolRef: { 27039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 27049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (SRE->getKind() != MCSymbolRefExpr::VK_None) 27069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 27079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 27099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 27109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Unary: 27129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle unary expressions yet"); 27139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Binary: { 27159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 27161355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach const MCExpr *LHS = applyPrefixToExpr(BE->getLHS(), Variant); 27179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *RHS = BE->getRHS(); 27189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (!LHS) 27199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 27209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 27229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 27239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 27249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim assert(0 && "Invalid expression kind!"); 27269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 27279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 27289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 2729352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 2730352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 2731352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 2732badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 27331355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 27345f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 27355f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 27365f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &ProcessorIMod) { 2737352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 2738352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 2739a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 2740352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2741badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 2742352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 2743352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 27445f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 27455f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 27465f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 27475f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 27485f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 27495f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 27505f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 27515f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 2752352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2753badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 27543f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 27553f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 2756ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 275771725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 275804d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 275904d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "sbcs") { 27603f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 27613f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 27623f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 27633f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 27643f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 27653f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 27663f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 27673f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 27683f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 27693f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 27703f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 27713f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 27723f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 27733f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 27743f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 27753f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 27763f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 27773f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 27783f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 27793f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 27803f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 27813f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 27823f00e317064560ad11168d22030416d853829f6eJim Grosbach } 278352925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 2784345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2785352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 2786352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 2787352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 278800f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach !(Mnemonic == "cps" || Mnemonic == "mls" || 27895f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 27905f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 27915f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 2792e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || 2793e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 2794352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 2795352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 2796352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 2797352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2798a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 2799a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 2800a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 2801a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 2802a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 2803a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 2804a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 2805a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 2806a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 2807a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 2808a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 2809a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 2810a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2811a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2812a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2813352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2814352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 28153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 28163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 28173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 28183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 28193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 2820fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 28211355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 2822fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 2823eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 2824eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 2825eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 2826eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 2827be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" || 2828eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 2829eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 28302c3f70e5d4b4f179f21ed1b2ba14674f9d65c9b0Jim Grosbach Mnemonic == "eor" || Mnemonic == "smlal" || Mnemonic == "neg" || 2831194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // FIXME: We need a better way. This really confused Thumb2 2832194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // parsing for 'mov'. 2833ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng (Mnemonic == "mov" && !isThumbOne())) { 2834eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 2835eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } else { 2836eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 2837eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } 28383771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 2839eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 2840eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 2841eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 2842eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 28435f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" || 2844c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Mnemonic == "setend" || 28450780b6303b99441fef04340b7a083006484f4743Jim Grosbach (Mnemonic == "nop" && isThumbOne()) || 284648c693ff564c422153733424ab845106161430acJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli") && !isThumb()) || 2847e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) 2848e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach && !isThumb()) || 28495f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) { 28503771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 28513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 28523771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 28533771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } 2854fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 2855ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (isThumb()) 2856fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 285763b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 2858fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 2859badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 2860badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2861d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 2862d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2863d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 2864d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 2865d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 2866d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 2867d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // operand if that's the instruction we're trying to match. 2868d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // 2869d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // We do this as post-processing of the explicit operands rather than just 2870d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // conditionally adding the cc_out in the first place because we need 2871d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // to check the type of the parsed immediate operand. 2872d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach if (Mnemonic == "mov" && Operands.size() > 4 && 2873d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 2874d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 2875d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 2876d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return true; 28773912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 28783912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 28793912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // when there are only two register operands. 28803912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 28813912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 28823912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 28833912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 28843912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach return true; 28853912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 2886d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return false; 2887d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach} 2888d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 2889badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 2890badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 2891badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2892badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 2893badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 2894ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 2895badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2896352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 2897352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 2898a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 2899352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 29001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 2901c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach ProcessorIMod); 2902badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2903ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 2904ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2905ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 2906ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 29079717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 29083771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 29093771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 29103771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 29113771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 29123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 29133771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 29143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 29153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 29161355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 29173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 291833c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 291933c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 292033c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 292133c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 2922ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 292333c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 292433c16a27370939de39679245c3dff72383c210bdJim Grosbach } 2925c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 2926c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 2927c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 2928c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 2929c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 2930c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 2931c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 293233c16a27370939de39679245c3dff72383c210bdJim Grosbach 29333771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 29343771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 29353771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: It would be awesome if we could somehow invent a location such that 29363771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // match errors on this operand would print a nice diagnostic about how the 29373771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 's' character in the mnemonic resulted in a CCOut operand. 293833c16a27370939de39679245c3dff72383c210bdJim Grosbach if (CanAcceptCarrySet) 29393771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 29403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar NameLoc)); 29413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 29423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 29433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 29443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 29453771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar ARMCC::CondCodes(PredicationCode), NameLoc)); 2946badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 2947345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2948a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 2949a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 2950a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 2951a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 2952a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 2953a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } else { 2954a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // This mnemonic can't ever accept a imod, but the user wrote 2955a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // one (or misspelled another mnemonic). 2956a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2957a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // FIXME: Issue a nice error. 2958a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2959a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2960345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 29615747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 29625747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 29635747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 2964a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 2965a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2966a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 29675747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 29685747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 29695747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 29705747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 2971a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 29721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 2973cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2974cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2975cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2976a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2977a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 2978b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 2979a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2980a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 29811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 2982cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 2983cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 2984cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2985a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2986a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 298716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2988cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 2989cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 299034e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 2991cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 2992146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 299334e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 2994ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2995d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // Some instructions, mostly Thumb, have forms for the same mnemonic that 2996d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // do and don't have a cc_out optional-def operand. With some spot-checks 2997d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // of the operand list, we can figure out which variant we're trying to 2998d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // parse and adjust accordingly before actually matching. Reason number 2999d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // #317 the table driven matcher doesn't fit well with the ARM instruction 3000d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // set. 3001d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach if (shouldOmitCCOutOperand(Mnemonic, Operands)) { 3002ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 3003ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 3004ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 3005ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 3006ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 3007cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 3008cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 3009cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 3010cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // a CondCode operand in the list. If we're trying to match the label 3011cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // version, remove the CondCode operand here. 3012cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 3013cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 3014cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 3015cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 3016cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 3017cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 3018857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach 3019857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // The vector-compare-to-zero instructions have a literal token "#0" at 3020857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // the end that comes to here as an immediate operand. Convert it to a 3021857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // token to play nicely with the matcher. 3022857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 3023857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 3024857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 3025857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 3026857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3027857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if (CE && CE->getValue() == 0) { 3028857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.erase(Operands.begin() + 5); 3029857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3030857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach delete Op; 3031857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 3032857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 3033934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the 3034934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // end. Convert it to a token here. 3035934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 && 3036934755ac040c516eac7fdd974e87590543acd16aJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 3037934755ac040c516eac7fdd974e87590543acd16aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 3038934755ac040c516eac7fdd974e87590543acd16aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3039934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (CE && CE->getValue() == 0) { 3040934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.erase(Operands.begin() + 5); 3041934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3042934755ac040c516eac7fdd974e87590543acd16aJim Grosbach delete Op; 3043934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 3044934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 3045934755ac040c516eac7fdd974e87590543acd16aJim Grosbach 30469898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 3047ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3048ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3049189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 3050aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 3051aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers, 3052aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set 3053aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true. 3054aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg, 3055aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned HiReg, bool &containsReg) { 3056aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = false; 3057aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 3058aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 3059aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (OpReg == Reg) 3060aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = true; 3061aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach // Anything other than a low register isn't legal here. 3062aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 3063aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return true; 3064aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach } 3065aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return false; 3066aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach} 3067aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 3068189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 3069189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 3070189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 3071189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3072189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 30732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD: 30742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_PRE: 30752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_POST: 3076189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 3077189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 3078189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 3079189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 3080189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 3081189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 3082189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 3083189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3084189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 308514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach case ARM::STRD: { 308614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt2 must be Rt + 1. 308714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 308814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 308914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach if (Rt2 != Rt + 1) 309014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 309114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach "source operands must be sequential"); 309214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return false; 309314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach } 309453642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_PRE: 309553642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_POST: 3096189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 3097189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 3098189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 3099189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 3100189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 310114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 3102189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 3103189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3104189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 3105fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 3106fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 3107fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 3108fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 3109fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 3110fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 3111fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 3112fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 311300c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach return false; 3114fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 311593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach case ARM::tLDMIA: { 311693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // Thumb LDM instructions are writeback iff the base register is not 311793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // in the register list. 311893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 31197260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach bool hasWritebackToken = 31207260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 31217260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 3122aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 3123aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase)) 3124aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[3 + hasWritebackToken]->getStartLoc(), 3125aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7"); 312693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // If we should have writeback, then there should be a '!' token. 3127aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!listContainsBase && !hasWritebackToken) 312893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach return Error(Operands[2]->getStartLoc(), 312993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach "writeback operator '!' expected"); 31307260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach // Likewise, if we should not have writeback, there must not be a '!' 3131aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (listContainsBase && hasWritebackToken) 31327260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach return Error(Operands[3]->getStartLoc(), 31337260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "writeback operator '!' not allowed when base register " 31347260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "in register list"); 313593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach 313693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach break; 313793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach } 31386dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPOP: { 3139aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 3140aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase)) 3141aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 3142aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or pc"); 31436dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 31446dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 31456dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPUSH: { 3146aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 3147aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase)) 3148aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 3149aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or lr"); 31506dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 31516dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 31521e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach case ARM::tSTMIA_UPD: { 31531e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach bool listContainsBase; 31541e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach if (checkLowRegisterList(Inst, 3, 0, 0, listContainsBase)) 31551e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach return Error(Operands[4]->getStartLoc(), 31561e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach "registers must be in range r0-r7"); 31571e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach break; 31581e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach } 3159189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 3160189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3161189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3162189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 3163189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3164f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser:: 3165f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst, 3166f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3167f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach switch (Inst.getOpcode()) { 3168f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach case ARM::LDMIA_UPD: 3169f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // If this is a load of a single register via a 'pop', then we should use 3170f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 3171f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 3172f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst.getNumOperands() == 5) { 3173f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach MCInst TmpInst; 3174f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.setOpcode(ARM::LDR_POST_IMM); 3175f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 3176f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 3177f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 3178f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 3179f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 3180f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 3181f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 3182f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst = TmpInst; 3183f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 3184f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach break; 3185f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach case ARM::STMDB_UPD: 3186f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // If this is a store of a single register via a 'push', then we should use 3187f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 3188f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 3189f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst.getNumOperands() == 5) { 3190f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach MCInst TmpInst; 3191f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.setOpcode(ARM::STR_PRE_IMM); 3192f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 3193f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 3194f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 3195f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 3196f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 3197f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 3198f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst = TmpInst; 3199f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach } 3200f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach break; 320189e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach case ARM::tADDi8: 320289e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach // If the immediate is in the range 0-7, we really wanted tADDi3. 320389e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach if (Inst.getOperand(3).getImm() < 8) 320489e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach Inst.setOpcode(ARM::tADDi3); 320589e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach break; 3206395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach case ARM::tBcc: 3207395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach // If the conditional is AL, we really want tB. 3208395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL) 3209395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach Inst.setOpcode(ARM::tB); 32103ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach break; 3211f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 3212f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach} 3213f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 321447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 321547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward 321647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// API changes, though. Better way? 321747a0d52b69056250a1edaca8b28f705993094542Jim Grosbachnamespace llvm { 321847a0d52b69056250a1edaca8b28f705993094542Jim Grosbachextern MCInstrDesc ARMInsts[]; 321947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 322047a0d52b69056250a1edaca8b28f705993094542Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) { 322147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return ARMInsts[Opcode]; 322247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 322347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 322447a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 322547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // 16-bit thumb arithmetic instructions either require or preclude the 'S' 322647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // suffix depending on whether they're in an IT block or not. 3227194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach unsigned Opc = Inst.getOpcode(); 3228194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach MCInstrDesc &MCID = getInstDesc(Opc); 322947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 323047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.hasOptionalDef() && 323147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "optionally flag setting instruction missing optional def operand"); 323247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.NumOperands == Inst.getNumOperands() && 323347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "operand count mismatch!"); 323447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // Find the optional-def operand (cc_out). 323547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned OpNo; 323647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach for (OpNo = 0; 323747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 323847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ++OpNo) 323947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ; 324047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb1, reject it completely. 324147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 324247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_MnemonicFail; 324347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb2, which form is legal depends on whether we're 324447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // in an IT block. 324547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // FIXME: We don't yet do IT blocks, so just always consider it to be 324647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // that we aren't in one until we do. 324747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 324847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_RequiresITBlock; 324947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 3250194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Some high-register supporting Thumb1 encodings only allow both registers 3251194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // to be from r0-r7 when in Thumb2. 3252194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach else if (Opc == ARM::tADDhirr && isThumbOne() && 3253194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 3254194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(2).getReg())) 3255194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresThumb2; 3256194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Others only require ARMv6 or later. 32574ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && 3258194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(0).getReg()) && 3259194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg())) 3260194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresV6; 326147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_Success; 326247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 326347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 3264fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 3265fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 3266fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 3267fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 3268fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 3269fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 327019cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned MatchResult; 3271193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 3272193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 327319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 3274e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 3275189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 3276189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 3277189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (validateInstruction(Inst, Operands)) 3278189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 3279189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3280f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // Some instructions need post-processing to, for example, tweak which 3281f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // encoding is selected. 3282f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach processInstruction(Inst, Operands); 3283f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 3284fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 3285fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 3286e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 3287e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 3288e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 3289e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 3290e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 3291e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 3292e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 3293e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 329416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3295e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 3296e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 3297e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 329816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3299e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 3300e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 3301e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 330247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "invalid instruction"); 3303b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 330488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The converter function will have already emited a diagnostic. 330588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 330647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach case Match_RequiresITBlock: 330747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "instruction only valid inside IT block"); 3308194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresV6: 3309194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires ARMv6 or later"); 3310194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresThumb2: 3311194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires Thumb2"); 3312fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 331316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3314c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 3315146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 3316fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 3317fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 33181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 3319ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 3320ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 3321ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 33221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 3323515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 33241355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 3325515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 33261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 3327515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 33281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 3329515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 33301355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 3331ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 3332ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3333ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 33341355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 3335ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 33361355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 3337ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 3338ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 3339ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 3340ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 3341ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 3342ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3343aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 3344ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3345ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 3346ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 334716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3348ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 3349ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 3350ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 3351b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3352ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 3353ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 3354ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3355b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3356ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 3357ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3358ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 33591355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 3360515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 33611355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 3362515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 3363515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 3364b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3365515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3366515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 3367515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 3368515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 3369515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3370515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3371515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 33721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 3373515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 33741355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 33756469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 33766469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 33776469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 33786469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 33796469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 33806469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 33816469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 33826469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 33836469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 33846469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 33856469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 33866469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 33876469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 33886469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 3389515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 3390515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 3391b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3392515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 33936469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 33946469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 33956469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 33966469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 33976469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 3398642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 3399642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 3400642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 3401515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3402515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3403515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 34041355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 3405515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 34061355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 340718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3408515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 3409515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 341038e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 341158c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 3412b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 341358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 34149e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 3415515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 3416515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 3417515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3418515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 341918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 3420b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3421515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3422515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 3423515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 3424515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3425515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3426515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 34271355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 3428515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 34291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 343018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3431515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 3432515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 343318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 343458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 3435b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 343658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 3437b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3438515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 3439515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 3440515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3441515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 344218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 3443b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3444515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 344532869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 3446bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (!isThumb()) { 3447ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 3448bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 3449bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 345032869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 3451bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (isThumb()) { 3452ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 3453bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 3454bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 3455eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 34562a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 3457515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3458515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3459515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 346090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 346190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 34629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 3463ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 346494b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 346594b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 346690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 3467ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 34683483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 34690692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 34700692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 34713483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 3472