ARMAsmParser.cpp revision 0c49ac05cd2374a99a3126ebe6c8370490a73ca5
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" 217801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng#include "llvm/MC/MCInstrDesc.h" 2294b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCRegisterInfo.h" 23ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 2494b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h" 25c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h" 263e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 27fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h" 2811e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach#include "llvm/ADT/BitVector.h" 2975ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h" 3094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h" 31c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h" 320c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h" 33345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h" 34c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h" 35ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 36ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm; 37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 383a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 39146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand; 4116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 4294b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser { 43ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng MCSubtargetInfo &STI; 44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &Parser; 45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmParser &getParser() const { return Parser; } 47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby MCAsmLexer &getLexer() const { return Parser.getLexer(); } 48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 50ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 51ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int tryParseRegister(); 531355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &); 540d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &); 551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &); 567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &); 571355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic); 581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parsePrefix(ARMMCExpr::VariantKind &RefKind); 591355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach const MCExpr *applyPrefixToExpr(const MCExpr *E, 609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant); 619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 62a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType, 647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &ShiftAmount); 651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveWord(unsigned Size, SMLoc L); 661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumb(SMLoc L); 671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveThumbFunc(SMLoc L); 681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveCode(SMLoc L); 691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool parseDirectiveSyntax(SMLoc L); 70515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, 725f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, unsigned &ProcessorIMod); 731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 74fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode); 7516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 76ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumb() const { 77ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // FIXME: Can tablegen auto-generate this? 78ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return (STI.getFeatureBits() & ARM::ModeThumb) != 0; 79ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 80ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng bool isThumbOne() const { 81ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0; 82ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 8347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach bool isThumbTwo() const { 8447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2); 8547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 86194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach bool hasV6Ops() const { 87194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return STI.getFeatureBits() & ARM::HasV6Ops; 88194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach } 8932869205052430f45d598fba25ab878d8b29da2dEvan Cheng void SwitchMode() { 90ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb)); 91ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(FB); 9232869205052430f45d598fba25ab878d8b29da2dEvan Cheng } 93ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 94a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// @name Auto-generated Match Functions 95a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// { 963483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 970692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER 980692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc" 99a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 100a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby /// } 101a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 10243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocNumOperand( 103f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 10443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseCoprocRegOperand( 105f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*>&); 10643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMemBarrierOptOperand( 1078bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 10843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseProcIFlagsOperand( 1098bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 11043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach OperandMatchResultTy parseMSRMaskOperand( 1118bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes SmallVectorImpl<MCParsedAsmOperand*>&); 112f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O, 113f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef Op, int Low, int High); 114f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 115f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "lsl", 0, 31); 116f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 117f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) { 118f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return parsePKHImm(O, "asr", 1, 32); 119f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 120c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&); 121580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&); 1227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&); 123293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&); 1247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&); 125251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&); 126ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 127ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Asm Match Converter Methods 1281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 129ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 130548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 131548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1321355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 133ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &); 1347b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 1357b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 1417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 1437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 1442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool cvtLdrdPre(MCInst &Inst, unsigned Opcode, 1452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 14614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach bool cvtStrdPre(MCInst &Inst, unsigned Opcode, 14714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 148623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 149623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 15088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode, 15188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &); 152189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 153189610f9466686a91fb7d847b572e1645c785323Jim Grosbach bool validateInstruction(MCInst &Inst, 154189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 155f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach void processInstruction(MCInst &Inst, 156f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Ops); 157d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach bool shouldOmitCCOutOperand(StringRef Mnemonic, 158d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 159189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 160ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic: 16147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach enum ARMMatchResultTy { 162194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY, 163194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresV6, 164194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach Match_RequiresThumb2 16547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach }; 16647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 167ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 16894b9550a32d189704a8eae55505edf62662c0534Evan Cheng : MCTargetAsmParser(), STI(_STI), Parser(_Parser) { 169ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCAsmParserExtension::Initialize(_Parser); 17032869205052430f45d598fba25ab878d8b29da2dEvan Cheng 171ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng // Initialize the set of available features. 172ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 173ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 174ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 1751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach // Implementation of the MCTargetAsmParser interface: 1761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 1771355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseInstruction(StringRef Name, SMLoc NameLoc, 178189610f9466686a91fb7d847b572e1645c785323Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands); 1791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool ParseDirective(AsmToken DirectiveID); 1801355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach 18147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned checkTargetMatchPredicate(MCInst &Inst); 18247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 1831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach bool MatchAndEmitInstruction(SMLoc IDLoc, 1841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach MCStreamer &Out); 186ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}; 18716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace 18816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1893a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace { 1903a69756e392942bc522193f38d7f33958ed3b131Chris Lattner 191a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine 192a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction. 193146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand { 194762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan enum KindTy { 1958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CondCode, 196d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach CCOut, 197fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocNum, 198fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes CoprocReg, 199cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby Immediate, 200706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MemBarrierOpt, 2018462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Memory, 2027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIndexRegister, 203584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MSRMask, 204a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcIFlags, 2058462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Register, 2068d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling RegisterList, 2070f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling DPRRegisterList, 2080f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling SPRRegisterList, 209e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftedRegister, 21092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ShiftedImmediate, 211580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImmediate, 2127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotateImmediate, 213293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach BitfieldDescriptor, 2148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Token 215a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Kind; 216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 217762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc StartLoc, EndLoc; 21824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling SmallVector<unsigned, 8> Registers; 219a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 220a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby union { 221a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 2228462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes Val; 2238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } CC; 2248462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 2258462b30548fb5969250858036638c73c16b65b43Daniel Dunbar struct { 226706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt Val; 227706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } MBOpt; 228706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 229706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes struct { 230fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned Val; 231fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } Cop; 232fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 233fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes struct { 234a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags Val; 235a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } IFlags; 236a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 237a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes struct { 238584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Val; 239584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } MMask; 240584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 241584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes struct { 242a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby const char *Data; 243a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned Length; 244a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Tok; 245a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 246a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 247a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned RegNum; 248a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Reg; 249a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2508155e5b753aca42973cf317727f3805faddcaf90Bill Wendling struct { 251cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *Val; 252cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } Imm; 25316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 2546a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar /// Combined record for all forms of ARM address expressions. 255a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby struct { 256a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned BaseRegNum; 2577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Offset is in OffsetReg or OffsetImm. If both are zero, no offset 2587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // was specified. 2597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm; // Offset immediate value 2607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum; // Offset register num, when OffsetImm == NULL 2617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg 2620d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm; // shift for OffsetReg. 2637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned isNegative : 1; // Negated OffsetReg? (~'U' bit) 264a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } Mem; 2650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 2660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson struct { 2677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned RegNum; 268f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isAdd; 269f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy; 270f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm; 2717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } PostIdxReg; 2727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach struct { 274580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 275e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned Imm; 276580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } ShifterImm; 277e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach struct { 278e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARM_AM::ShiftOpc ShiftTy; 279e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg; 280e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg; 281e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm; 282af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedReg; 28392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson struct { 28492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARM_AM::ShiftOpc ShiftTy; 28592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg; 28692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm; 287af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach } RegShiftedImm; 2887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach struct { 2897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach unsigned Imm; 2907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } RotImm; 291293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach struct { 292293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned LSB; 293293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned Width; 294293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } Bitfield; 295a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby }; 29616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 297146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 298146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic: 299762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() { 300762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Kind = o.Kind; 301762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan StartLoc = o.StartLoc; 302762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan EndLoc = o.EndLoc; 303762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan switch (Kind) { 3048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar case CondCode: 3058462b30548fb5969250858036638c73c16b65b43Daniel Dunbar CC = o.CC; 3068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar break; 307762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Token: 3088462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Tok = o.Tok; 309762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 310d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 311762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Register: 312762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Reg = o.Reg; 313762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 3148d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling case RegisterList: 3150f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 3160f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: 31724d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Registers = o.Registers; 3188d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 319fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 320fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 321fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Cop = o.Cop; 322fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 323762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Immediate: 324762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Imm = o.Imm; 325762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 326706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 327706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes MBOpt = o.MBOpt; 328706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 329762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan case Memory: 330762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Mem = o.Mem; 331762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan break; 3327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach case PostIndexRegister: 3337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach PostIdxReg = o.PostIdxReg; 3347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 335584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 336584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes MMask = o.MMask; 337584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 338a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: 339a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags = o.IFlags; 3400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 341580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 342580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm = o.ShifterImm; 3430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 344e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 345af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedReg = o.RegShiftedReg; 346e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 34792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 348af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach RegShiftedImm = o.RegShiftedImm; 34992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 3507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach case RotateImmediate: 3517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach RotImm = o.RotImm; 3527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 353293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach case BitfieldDescriptor: 354293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Bitfield = o.Bitfield; 355293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 356762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 357762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 35816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 359762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getStartLoc - Get the location of the first token of this operand. 360762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getStartLoc() const { return StartLoc; } 361762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan /// getEndLoc - Get the location of the last token of this operand. 362762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc getEndLoc() const { return EndLoc; } 363a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3648462b30548fb5969250858036638c73c16b65b43Daniel Dunbar ARMCC::CondCodes getCondCode() const { 3658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar assert(Kind == CondCode && "Invalid access!"); 3668462b30548fb5969250858036638c73c16b65b43Daniel Dunbar return CC.Val; 3678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 3688462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 369fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes unsigned getCoproc() const { 370fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!"); 371fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Cop.Val; 372fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 373fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 374a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby StringRef getToken() const { 375a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(Kind == Token && "Invalid access!"); 376a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return StringRef(Tok.Data, Tok.Length); 377a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 378a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 379a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby unsigned getReg() const { 3806aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer assert((Kind == Register || Kind == CCOut) && "Invalid access!"); 3817729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling return Reg.RegNum; 382a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 383a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3845fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &getRegList() const { 3850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling assert((Kind == RegisterList || Kind == DPRRegisterList || 3860f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind == SPRRegisterList) && "Invalid access!"); 38724d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling return Registers; 3888d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 3898d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 390cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby const MCExpr *getImm() const { 391cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby assert(Kind == Immediate && "Invalid access!"); 392cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby return Imm.Val; 393cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 394cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 395706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARM_MB::MemBOpt getMemBarrierOpt() const { 396706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Kind == MemBarrierOpt && "Invalid access!"); 397706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return MBOpt.Val; 398706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 399706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 400a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARM_PROC::IFlags getProcIFlags() const { 401a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Kind == ProcIFlags && "Invalid access!"); 402a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return IFlags.Val; 403a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 404a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 405584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned getMSRMask() const { 406584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Kind == MSRMask && "Invalid access!"); 407584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MMask.Val; 408584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 409584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 410fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocNum() const { return Kind == CoprocNum; } 411fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes bool isCoprocReg() const { return Kind == CoprocReg; } 4128462b30548fb5969250858036638c73c16b65b43Daniel Dunbar bool isCondCode() const { return Kind == CondCode; } 413d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach bool isCCOut() const { return Kind == CCOut; } 4143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar bool isImm() const { return Kind == Immediate; } 41572f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_1020s4() const { 41672f39f8436848885176943b0ba985a7171145423Jim Grosbach if (Kind != Immediate) 41772f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 41872f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 41972f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 42072f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 42172f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 1020; 42272f39f8436848885176943b0ba985a7171145423Jim Grosbach } 42372f39f8436848885176943b0ba985a7171145423Jim Grosbach bool isImm0_508s4() const { 42472f39f8436848885176943b0ba985a7171145423Jim Grosbach if (Kind != Immediate) 42572f39f8436848885176943b0ba985a7171145423Jim Grosbach return false; 42672f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 42772f39f8436848885176943b0ba985a7171145423Jim Grosbach if (!CE) return false; 42872f39f8436848885176943b0ba985a7171145423Jim Grosbach int64_t Value = CE->getValue(); 42972f39f8436848885176943b0ba985a7171145423Jim Grosbach return ((Value & 3) == 0) && Value >= 0 && Value <= 508; 43072f39f8436848885176943b0ba985a7171145423Jim Grosbach } 4316b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isImm0_255() const { 4326b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 4336b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 4346b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4356b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 4366b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 4376b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return Value >= 0 && Value < 256; 4386b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 43983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_7() const { 44083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 44183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 44283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 44383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 44483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 44583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 8; 44683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 44783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach bool isImm0_15() const { 44883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (Kind != Immediate) 44983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return false; 45083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 45183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach if (!CE) return false; 45283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach int64_t Value = CE->getValue(); 45383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach return Value >= 0 && Value < 16; 45483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 4557c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach bool isImm0_31() const { 4567c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (Kind != Immediate) 4577c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return false; 4587c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4597c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach if (!CE) return false; 4607c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach int64_t Value = CE->getValue(); 4617c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach return Value >= 0 && Value < 32; 4627c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 463f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach bool isImm1_16() const { 464f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (Kind != Immediate) 465f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return false; 466f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 467f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach if (!CE) return false; 468f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach int64_t Value = CE->getValue(); 469f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach return Value > 0 && Value < 17; 470f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 4714a5ffb399f841783c201c599b88d576757f1922eJim Grosbach bool isImm1_32() const { 4724a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (Kind != Immediate) 4734a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return false; 4744a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 4754a5ffb399f841783c201c599b88d576757f1922eJim Grosbach if (!CE) return false; 4764a5ffb399f841783c201c599b88d576757f1922eJim Grosbach int64_t Value = CE->getValue(); 4774a5ffb399f841783c201c599b88d576757f1922eJim Grosbach return Value > 0 && Value < 33; 4784a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 479fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach bool isImm0_65535() const { 480fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (Kind != Immediate) 481fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return false; 482fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 483fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach if (!CE) return false; 484fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach int64_t Value = CE->getValue(); 485fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach return Value >= 0 && Value < 65536; 486fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 487ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach bool isImm0_65535Expr() const { 488ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (Kind != Immediate) 489ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return false; 490ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 491ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // If it's not a constant expression, it'll generate a fixup and be 492ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // handled later. 493ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach if (!CE) return true; 494ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach int64_t Value = CE->getValue(); 495ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Value >= 0 && Value < 65536; 496ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 497ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach bool isImm24bit() const { 498ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (Kind != Immediate) 499ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return false; 500ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 501ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach if (!CE) return false; 502ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach int64_t Value = CE->getValue(); 503ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach return Value >= 0 && Value <= 0xffffff; 504ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 50570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach bool isImmThumbSR() const { 50670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (Kind != Immediate) 50770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return false; 50870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 50970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach if (!CE) return false; 51070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach int64_t Value = CE->getValue(); 51170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach return Value > 0 && Value < 33; 51270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 513f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHLSLImm() const { 514f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 515f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 516f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 517f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 518f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 519f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value >= 0 && Value < 32; 520f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 521f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach bool isPKHASRImm() const { 522f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Kind != Immediate) 523f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return false; 524f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 525f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) return false; 526f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int64_t Value = CE->getValue(); 527f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return Value > 0 && Value <= 32; 528f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 5296bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach bool isARMSOImm() const { 5306bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (Kind != Immediate) 5316bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return false; 5326bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5336bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach if (!CE) return false; 5346bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach int64_t Value = CE->getValue(); 5356bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach return ARM_AM::getSOImmVal(Value) != -1; 5366bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 5376b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach bool isT2SOImm() const { 5386b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (Kind != Immediate) 5396b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return false; 5406b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 5416b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach if (!CE) return false; 5426b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach int64_t Value = CE->getValue(); 5436b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach return ARM_AM::getT2SOImmVal(Value) != -1; 5446b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 545c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach bool isSetEndImm() const { 546c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Kind != Immediate) 547c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return false; 548c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 549c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CE) return false; 550c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int64_t Value = CE->getValue(); 551c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Value == 1 || Value == 0; 552c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 553b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling bool isReg() const { return Kind == Register; } 5548d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling bool isRegList() const { return Kind == RegisterList; } 5550f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isDPRRegList() const { return Kind == DPRRegisterList; } 5560f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling bool isSPRRegList() const { return Kind == SPRRegisterList; } 55714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isToken() const { return Kind == Token; } 558706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; } 55914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner bool isMemory() const { return Kind == Memory; } 560580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isShifterImm() const { return Kind == ShifterImmediate; } 561af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedReg() const { return Kind == ShiftedRegister; } 562af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach bool isRegShiftedImm() const { return Kind == ShiftedImmediate; } 5637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach bool isRotImm() const { return Kind == RotateImmediate; } 564293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach bool isBitfield() const { return Kind == BitfieldDescriptor; } 565f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxRegShifted() const { return Kind == PostIndexRegister; } 566f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach bool isPostIdxReg() const { 567f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach return Kind == PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift; 568f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 5697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemNoOffset() const { 5707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 571ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return false; 5727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // No offset of any kind. 5737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0; 574ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 5757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode2() const { 5767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 577ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 5787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 5797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return true; 5807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 5817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 5827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 5837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 5847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 585039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach bool isAM2OffsetImm() const { 586039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Kind != Immediate) 587039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return false; 588039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Immediate offset in range [-4095, 4095]. 589039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 590039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (!CE) return false; 591039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int64_t Val = CE->getValue(); 592039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach return Val > -4096 && Val < 4096; 593039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 5942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAddrMode3() const { 5952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind != Memory) 5962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 5972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // No shifts are legal for AM3. 5982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Mem.ShiftType != ARM_AM::no_shift) return false; 5992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Check for register offset. 6002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Mem.OffsetRegNum) return true; 6012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 6022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!Mem.OffsetImm) return true; 6032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return Val > -256 && Val < 256; 6052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 6062fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach bool isAM3Offset() const { 6072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind != Immediate && Kind != PostIndexRegister) 6082fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return false; 6092fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind == PostIndexRegister) 6102fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return PostIdxReg.ShiftTy == ARM_AM::no_shift; 6112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Immediate offset in range [-255, 255]. 6122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 6132fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!CE) return false; 6142fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int64_t Val = CE->getValue(); 615251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Special case, #-0 is INT32_MIN. 616251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return (Val > -256 && Val < 256) || Val == INT32_MIN; 6172fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 6187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAddrMode5() const { 6197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory) 620ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 6217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for register offset. 6227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Mem.OffsetRegNum) return false; 6237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-1020, 1020] and a multiple of 4. 6247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val >= -1020 && Val <= 1020 && ((Val & 3) == 0); 6277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 6287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemRegOffset() const { 6297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || !Mem.OffsetRegNum) 630ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return false; 631ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 632ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 6337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemThumbRR() const { 6347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Thumb reg+reg addressing is simple. Just two registers, a base and 6357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // an offset. No shifts, negations or any other complicating factors. 6367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative || 6377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Mem.ShiftType != ARM_AM::no_shift) 63887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling return false; 63960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return isARMLowRegister(Mem.BaseRegNum) && 64060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach (!Mem.OffsetRegNum || isARMLowRegister(Mem.OffsetRegNum)); 64160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 64260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach bool isMemThumbRIs4() const { 64360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || 64460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 64560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach return false; 64660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach // Immediate offset, multiple of 4 in range [0, 124]. 64760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach if (!Mem.OffsetImm) return true; 64860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 649ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 124 && (Val % 4) == 0; 650ecd858968384be029574d845eb098d357049e02eJim Grosbach } 65138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach bool isMemThumbRIs2() const { 65238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || 65338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 65438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return false; 65538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach // Immediate offset, multiple of 4 in range [0, 62]. 65638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach if (!Mem.OffsetImm) return true; 65738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 65838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach return Val >= 0 && Val <= 62 && (Val % 2) == 0; 65938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 66048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach bool isMemThumbRIs1() const { 66148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || 66248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach !isARMLowRegister(Mem.BaseRegNum)) 66348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return false; 66448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach // Immediate offset in range [0, 31]. 66548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach if (!Mem.OffsetImm) return true; 66648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 66748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach return Val >= 0 && Val <= 31; 66848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 669ecd858968384be029574d845eb098d357049e02eJim Grosbach bool isMemThumbSPI() const { 670ecd858968384be029574d845eb098d357049e02eJim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0 || Mem.BaseRegNum != ARM::SP) 671ecd858968384be029574d845eb098d357049e02eJim Grosbach return false; 672ecd858968384be029574d845eb098d357049e02eJim Grosbach // Immediate offset, multiple of 4 in range [0, 1020]. 673ecd858968384be029574d845eb098d357049e02eJim Grosbach if (!Mem.OffsetImm) return true; 674ecd858968384be029574d845eb098d357049e02eJim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 675ecd858968384be029574d845eb098d357049e02eJim Grosbach return Val >= 0 && Val <= 1020 && (Val % 4) == 0; 676505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 6777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm8Offset() const { 6787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 679f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling return false; 6807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-255, 255]. 6817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -256 && Val < 256; 684f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 6857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isMemImm12Offset() const { 68609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If we have an immediate that's not a constant, treat it as a label 68709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // reference needing a fixup. If it is a constant, it's something else 68809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // and we reject it. 68909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach if (Kind == Immediate && !isa<MCConstantExpr>(getImm())) 69009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return true; 69109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 6927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Memory || Mem.OffsetRegNum != 0) 693ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling return false; 6947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Immediate offset in range [-4095, 4095]. 6957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetImm) return true; 6967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm->getValue(); 6977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -4096 && Val < 4096; 6987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 6997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isPostIdxImm8() const { 7007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Kind != Immediate) 7017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 7027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 703ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling if (!CE) return false; 7047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = CE->getValue(); 7057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Val > -256 && Val < 256; 706ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 7077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 708584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes bool isMSRMask() const { return Kind == MSRMask; } 709a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes bool isProcIFlags() const { return Kind == ProcIFlags; } 7103483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 7113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addExpr(MCInst &Inst, const MCExpr *Expr) const { 71214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner // Add as immediates when possible. Null MCExpr = 0. 71314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner if (Expr == 0) 71414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner Inst.addOperand(MCOperand::CreateImm(0)); 71514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 7163483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 7173483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar else 7183483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar Inst.addOperand(MCOperand::CreateExpr(Expr)); 7193483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 7203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 7218462b30548fb5969250858036638c73c16b65b43Daniel Dunbar void addCondCodeOperands(MCInst &Inst, unsigned N) const { 722345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar assert(N == 2 && "Invalid number of operands!"); 7238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); 72404f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR; 72504f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegNum)); 7268462b30548fb5969250858036638c73c16b65b43Daniel Dunbar } 7278462b30548fb5969250858036638c73c16b65b43Daniel Dunbar 728fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocNumOperands(MCInst &Inst, unsigned N) const { 729fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 730fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 731fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 732fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 733fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes void addCoprocRegOperands(MCInst &Inst, unsigned N) const { 734fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 735fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(getCoproc())); 736fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 737fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 738d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach void addCCOutOperands(MCInst &Inst, unsigned N) const { 739d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 740d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Inst.addOperand(MCOperand::CreateReg(getReg())); 741d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 742d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 743a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby void addRegOperands(MCInst &Inst, unsigned N) const { 744a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby assert(N == 1 && "Invalid number of operands!"); 745a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby Inst.addOperand(MCOperand::CreateReg(getReg())); 746a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 747a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 748af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const { 749e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach assert(N == 3 && "Invalid number of operands!"); 750af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!"); 751af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg)); 752af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg)); 753e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Inst.addOperand(MCOperand::CreateImm( 754af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm))); 755e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 756e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 757af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const { 758152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson assert(N == 2 && "Invalid number of operands!"); 759af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!"); 760af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); 76192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Inst.addOperand(MCOperand::CreateImm( 762af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); 76392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 76492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 76592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 766580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach void addShifterImmOperands(MCInst &Inst, unsigned N) const { 7670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(N == 1 && "Invalid number of operands!"); 768580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) | 769580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ShifterImm.Imm)); 7700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 7710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 77287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling void addRegListOperands(MCInst &Inst, unsigned N) const { 7737729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling assert(N == 1 && "Invalid number of operands!"); 7745fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 7755fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 7767729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ++I) 7777729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Inst.addOperand(MCOperand::CreateReg(*I)); 77887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling } 77987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling 7800f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addDPRRegListOperands(MCInst &Inst, unsigned N) const { 7810f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 7820f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 7830f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 7840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling void addSPRRegListOperands(MCInst &Inst, unsigned N) const { 7850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling addRegListOperands(Inst, N); 7860f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling } 7870f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 7887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach void addRotImmOperands(MCInst &Inst, unsigned N) const { 7897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 7907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Encoded as val>>3. The printer handles display as 8, 16, 24. 7917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3)); 7927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 7937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 794293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach void addBitfieldOperands(MCInst &Inst, unsigned N) const { 795293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 796293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Munge the lsb/width into a bitfield mask. 797293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned lsb = Bitfield.LSB; 798293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach unsigned width = Bitfield.Width; 799293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Make a 32-bit mask w/ the referenced bits clear and all other bits set. 800293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >> 801293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach (32 - (lsb + width))); 802293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Mask)); 803293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 804293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 8053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar void addImmOperands(MCInst &Inst, unsigned N) const { 8066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 8076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 8086b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 8096b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 81072f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const { 81172f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 81272f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 81372f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 81472f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 81572f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 81672f39f8436848885176943b0ba985a7171145423Jim Grosbach } 81772f39f8436848885176943b0ba985a7171145423Jim Grosbach 81872f39f8436848885176943b0ba985a7171145423Jim Grosbach void addImm0_508s4Operands(MCInst &Inst, unsigned N) const { 81972f39f8436848885176943b0ba985a7171145423Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 82072f39f8436848885176943b0ba985a7171145423Jim Grosbach // The immediate is scaled by four in the encoding and is stored 82172f39f8436848885176943b0ba985a7171145423Jim Grosbach // in the MCInst as such. Lop off the low two bits here. 82272f39f8436848885176943b0ba985a7171145423Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 82372f39f8436848885176943b0ba985a7171145423Jim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4)); 82472f39f8436848885176943b0ba985a7171145423Jim Grosbach } 82572f39f8436848885176943b0ba985a7171145423Jim Grosbach 8266b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addImm0_255Operands(MCInst &Inst, unsigned N) const { 8276b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 8286b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach addExpr(Inst, getImm()); 8296b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach } 8306b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach 83183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_7Operands(MCInst &Inst, unsigned N) const { 83283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 83383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 83483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 83583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 83683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach void addImm0_15Operands(MCInst &Inst, unsigned N) const { 8377c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 8387c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach addExpr(Inst, getImm()); 8397c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach } 8407c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach 8417c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach void addImm0_31Operands(MCInst &Inst, unsigned N) const { 84283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 84383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach addExpr(Inst, getImm()); 84483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach } 84583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach 846f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach void addImm1_16Operands(MCInst &Inst, unsigned N) const { 847f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach assert(N == 1 && "Invalid number of operands!"); 848f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 849f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach // the bits as encoded, so subtract off one here. 850f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 851f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 852f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach } 853f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach 8544a5ffb399f841783c201c599b88d576757f1922eJim Grosbach void addImm1_32Operands(MCInst &Inst, unsigned N) const { 8554a5ffb399f841783c201c599b88d576757f1922eJim Grosbach assert(N == 1 && "Invalid number of operands!"); 8564a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // The constant encodes as the immediate-1, and we store in the instruction 8574a5ffb399f841783c201c599b88d576757f1922eJim Grosbach // the bits as encoded, so subtract off one here. 8584a5ffb399f841783c201c599b88d576757f1922eJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 8594a5ffb399f841783c201c599b88d576757f1922eJim Grosbach Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1)); 8604a5ffb399f841783c201c599b88d576757f1922eJim Grosbach } 8614a5ffb399f841783c201c599b88d576757f1922eJim Grosbach 862fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach void addImm0_65535Operands(MCInst &Inst, unsigned N) const { 863fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 864fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach addExpr(Inst, getImm()); 865fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach } 866fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach 867ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const { 868ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 869ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach addExpr(Inst, getImm()); 870ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach } 871ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach 872ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach void addImm24bitOperands(MCInst &Inst, unsigned N) const { 873ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach assert(N == 1 && "Invalid number of operands!"); 874ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach addExpr(Inst, getImm()); 87570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach } 87670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach 87770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach void addImmThumbSROperands(MCInst &Inst, unsigned N) const { 87870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 87970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // The constant encodes as the immediate, except for 32, which encodes as 88070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach // zero. 88170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 88270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach unsigned Imm = CE->getValue(); 88370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm))); 884ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 885ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 886f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const { 887f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 888f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach addExpr(Inst, getImm()); 889f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 890f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 891f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach void addPKHASRImmOperands(MCInst &Inst, unsigned N) const { 892f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 893f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // An ASR value of 32 encodes as 0, so that's how we want to add it to 894f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // the instruction as well. 895f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 896f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 897f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val)); 898f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 899f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 9006bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach void addARMSOImmOperands(MCInst &Inst, unsigned N) const { 9016bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach assert(N == 1 && "Invalid number of operands!"); 9026bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach addExpr(Inst, getImm()); 9036bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach } 9046bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach 9056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach void addT2SOImmOperands(MCInst &Inst, unsigned N) const { 9063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar assert(N == 1 && "Invalid number of operands!"); 9073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar addExpr(Inst, getImm()); 9083483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar } 90916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 910c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach void addSetEndImmOperands(MCInst &Inst, unsigned N) const { 911c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 912c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach addExpr(Inst, getImm()); 913c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 914c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 915706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const { 916706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 917706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt()))); 918706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 919706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 9207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const { 9217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 9227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 923505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes } 924505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes 9257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode2Operands(MCInst &Inst, unsigned N) const { 9267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 9277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 9287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!Mem.OffsetRegNum) { 9297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 9307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 9317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 9327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 9337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 9347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else { 9357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // For register offset, we encode the shift type and negation flag 9367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // here. 9377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 938dd32ba337aab88c215108ca8bf4a0267fce1e773Jim Grosbach Mem.ShiftImm, Mem.ShiftType); 939ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 9407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 9427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 943ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes } 944ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 945039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const { 946039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 947039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 948039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach assert(CE && "non-constant AM2OffsetImm operand!"); 949039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach int32_t Val = CE->getValue(); 950039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 951039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach // Special case for #-0 952039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val == INT32_MIN) Val = 0; 953039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach if (Val < 0) Val = -Val; 954039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift); 955039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 956039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 957039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach } 958039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach 9592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAddrMode3Operands(MCInst &Inst, unsigned N) const { 9602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 9612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 9622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (!Mem.OffsetRegNum) { 9632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 9642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 9652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 9662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 9672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 9682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } else { 9692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // For register offset, we encode the shift type and negation flag 9702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // here. 9712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Val = ARM_AM::getAM3Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 0); 9722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 9742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 9752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 9762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 9782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach void addAM3OffsetOperands(MCInst &Inst, unsigned N) const { 9792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 9802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Kind == PostIndexRegister) { 9812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = 9822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0); 9832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 9842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 985251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return; 9862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 9882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Constant offset. 9892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm()); 9902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach int32_t Val = CE->getValue(); 9912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 9922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Special case for #-0 9932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val == INT32_MIN) Val = 0; 9942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach if (Val < 0) Val = -Val; 995251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = ARM_AM::getAM3Opc(AddSub, Val); 9962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateReg(0)); 9972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 9982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach } 9992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 10007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addAddrMode5Operands(MCInst &Inst, unsigned N) const { 10017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 10027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The lower two bits are always zero and as such are not encoded. 10037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0; 10047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add; 10057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Special case for #-0 10067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val == INT32_MIN) Val = 0; 10077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Val < 0) Val = -Val; 10087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Val = ARM_AM::getAM5Opc(AddSub, Val); 10097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 10107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 10117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 10127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 10137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const { 10147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 10157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 10167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 10177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1018ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes } 1019ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 10207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const { 10217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 102209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // If this is an immediate, it's a label reference. 102309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach if (Kind == Immediate) { 102409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach addExpr(Inst, getImm()); 102509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 102609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach return; 102709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach } 102809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach 102909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach // Otherwise, it's a normal memory reg+offset. 10307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0; 10317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 10327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 10337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 103492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling 10357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const { 10367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 3 && "Invalid number of operands!"); 10377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 10380d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Mem.ShiftImm, Mem.ShiftType); 10397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 10407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 10417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 10427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 1043d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar 10447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addMemThumbRROperands(MCInst &Inst, unsigned N) const { 10457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 10467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 10477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum)); 104814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner } 10493483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 105060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const { 105160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 105260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0; 105360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 105460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 105548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach } 105648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach 105738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const { 105838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 105938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 2) : 0; 106038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 106138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 106238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach } 106338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach 106448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const { 106548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 106648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue()) : 0; 106748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 106848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 106960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach } 107060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach 1071ecd858968384be029574d845eb098d357049e02eJim Grosbach void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const { 1072ecd858968384be029574d845eb098d357049e02eJim Grosbach assert(N == 2 && "Invalid number of operands!"); 1073ecd858968384be029574d845eb098d357049e02eJim Grosbach int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0; 1074ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum)); 1075ecd858968384be029574d845eb098d357049e02eJim Grosbach Inst.addOperand(MCOperand::CreateImm(Val)); 1076ecd858968384be029574d845eb098d357049e02eJim Grosbach } 1077ecd858968384be029574d845eb098d357049e02eJim Grosbach 10787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const { 10797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 1 && "Invalid number of operands!"); 10807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 10817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(CE && "non-constant post-idx-imm8 operand!"); 10827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Imm = CE->getValue(); 10837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isAdd = Imm >= 0; 10847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8; 10857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1086f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling } 1087ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 10887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach void addPostIdxRegOperands(MCInst &Inst, unsigned N) const { 10897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 10907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1091f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd)); 1092f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 1093f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 1094f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const { 1095f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach assert(N == 2 && "Invalid number of operands!"); 1096f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum)); 1097f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // The sign, shift type, and shift amount are encoded in a single operand 1098f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // using the AM2 encoding helpers. 1099f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub; 1100f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm, 1101f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach PostIdxReg.ShiftTy); 1102f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Inst.addOperand(MCOperand::CreateImm(Imm)); 1103ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling } 1104ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling 1105584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes void addMSRMaskOperands(MCInst &Inst, unsigned N) const { 1106584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1107584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask()))); 1108584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1109584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1110a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes void addProcIFlagsOperands(MCInst &Inst, unsigned N) const { 1111a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(N == 1 && "Invalid number of operands!"); 1112a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags()))); 1113a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1114a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1115b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach virtual void print(raw_ostream &OS) const; 1116b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar 11173a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) { 11183a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(CondCode); 1119345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->CC.Val = CC; 1120345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->StartLoc = S; 1121345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar Op->EndLoc = S; 11223a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1123345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar } 1124345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 1125fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) { 1126fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocNum); 1127fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1128fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1129fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1130fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1131fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1132fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1133fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) { 1134fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(CoprocReg); 1135fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->Cop.Val = CopVal; 1136fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->StartLoc = S; 1137fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Op->EndLoc = S; 1138fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return Op; 1139fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes } 1140fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1141d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) { 1142d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach ARMOperand *Op = new ARMOperand(CCOut); 1143d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->Reg.RegNum = RegNum; 1144d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->StartLoc = S; 1145d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach Op->EndLoc = S; 1146d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach return Op; 1147d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach } 1148d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach 11493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateToken(StringRef Str, SMLoc S) { 11503a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Token); 1151762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Data = Str.data(); 1152762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Tok.Length = Str.size(); 1153762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1154762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = S; 11553a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1156a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1157a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 115850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 11593a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Register); 1160762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Reg.RegNum = RegNum; 1161762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1162762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 11633a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1164a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1165a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1166e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, 1167e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned SrcReg, 1168e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftReg, 1169e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach unsigned ShiftImm, 1170e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc S, SMLoc E) { 1171e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ARMOperand *Op = new ARMOperand(ShiftedRegister); 1172af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftTy = ShTy; 1173af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.SrcReg = SrcReg; 1174af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftReg = ShiftReg; 1175af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedReg.ShiftImm = ShiftImm; 1176e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->StartLoc = S; 1177e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Op->EndLoc = E; 1178e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Op; 1179e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1180e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 118192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, 118292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned SrcReg, 118392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson unsigned ShiftImm, 118492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson SMLoc S, SMLoc E) { 118592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson ARMOperand *Op = new ARMOperand(ShiftedImmediate); 1186af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftTy = ShTy; 1187af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.SrcReg = SrcReg; 1188af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach Op->RegShiftedImm.ShiftImm = ShiftImm; 118992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->StartLoc = S; 119092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Op->EndLoc = E; 119192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson return Op; 119292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson } 119392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson 1194580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm, 11950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S, SMLoc E) { 1196580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach ARMOperand *Op = new ARMOperand(ShifterImmediate); 1197580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.isASR = isASR; 1198580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Op->ShifterImm.Imm = Imm; 11990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->StartLoc = S; 12000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson Op->EndLoc = E; 12010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return Op; 12020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson } 12030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 12047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) { 12057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach ARMOperand *Op = new ARMOperand(RotateImmediate); 12067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->RotImm.Imm = Imm; 12077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->StartLoc = S; 12087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Op->EndLoc = E; 12097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return Op; 12107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 12117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 1212293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width, 1213293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S, SMLoc E) { 1214293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach ARMOperand *Op = new ARMOperand(BitfieldDescriptor); 1215293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.LSB = LSB; 1216293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->Bitfield.Width = Width; 1217293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->StartLoc = S; 1218293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Op->EndLoc = E; 1219293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return Op; 1220293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 1221293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 12227729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling static ARMOperand * 12235fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs, 1224cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay SMLoc StartLoc, SMLoc EndLoc) { 12250f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling KindTy Kind = RegisterList; 12260f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 1227275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng if (llvm::ARMMCRegisterClasses[ARM::DPRRegClassID]. 1228275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 12290f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = DPRRegisterList; 1230275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng else if (llvm::ARMMCRegisterClasses[ARM::SPRRegClassID]. 1231275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng contains(Regs.front().first)) 12320f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling Kind = SPRRegisterList; 12330f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling 12340f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling ARMOperand *Op = new ARMOperand(Kind); 12355fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator 12367729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = Regs.begin(), E = Regs.end(); I != E; ++I) 123724d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling Op->Registers.push_back(I->first); 1238cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling array_pod_sort(Op->Registers.begin(), Op->Registers.end()); 1239cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->StartLoc = StartLoc; 1240cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay Op->EndLoc = EndLoc; 12418d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling return Op; 12428d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 12438d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 12443a69756e392942bc522193f38d7f33958ed3b131Chris Lattner static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 12453a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Immediate); 1246762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Imm.Val = Val; 1247762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1248762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 12493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1250cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby } 1251cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby 12527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach static ARMOperand *CreateMem(unsigned BaseRegNum, 12537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *OffsetImm, 12547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned OffsetRegNum, 12557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType, 12560d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm, 12577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative, 12583a69756e392942bc522193f38d7f33958ed3b131Chris Lattner SMLoc S, SMLoc E) { 12593a69756e392942bc522193f38d7f33958ed3b131Chris Lattner ARMOperand *Op = new ARMOperand(Memory); 1260762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.BaseRegNum = BaseRegNum; 12617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetImm = OffsetImm; 12627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.OffsetRegNum = OffsetRegNum; 1263762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->Mem.ShiftType = ShiftType; 12640d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Op->Mem.ShiftImm = ShiftImm; 12657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->Mem.isNegative = isNegative; 12667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->StartLoc = S; 12677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->EndLoc = E; 12687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Op; 12697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 127016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 1271f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd, 1272f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy, 1273f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm, 12747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S, SMLoc E) { 12757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARMOperand *Op = new ARMOperand(PostIndexRegister); 12767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Op->PostIdxReg.RegNum = RegNum; 1277f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.isAdd = isAdd; 1278f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftTy = ShiftTy; 1279f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Op->PostIdxReg.ShiftImm = ShiftImm; 1280762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->StartLoc = S; 1281762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan Op->EndLoc = E; 12823a69756e392942bc522193f38d7f33958ed3b131Chris Lattner return Op; 1283a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 1284706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1285706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { 1286706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MemBarrierOpt); 1287706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->MBOpt.Val = Opt; 1288706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->StartLoc = S; 1289706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Op->EndLoc = S; 1290706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes return Op; 1291706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes } 1292a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1293a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { 1294a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(ProcIFlags); 1295a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->IFlags.Val = IFlags; 1296a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->StartLoc = S; 1297a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Op->EndLoc = S; 1298a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return Op; 1299a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1300584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1301584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) { 1302584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes ARMOperand *Op = new ARMOperand(MSRMask); 1303584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->MMask.Val = MMask; 1304584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->StartLoc = S; 1305584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Op->EndLoc = S; 1306584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return Op; 1307584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1308a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}; 1309a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1310a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace. 1311a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1312b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const { 1313fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar switch (Kind) { 1314fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case CondCode: 13156a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">"; 1316fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1317d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach case CCOut: 1318d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach OS << "<ccout " << getReg() << ">"; 1319d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach break; 1320fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocNum: 1321fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor number: " << getCoproc() << ">"; 1322fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1323fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes case CoprocReg: 1324fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes OS << "<coprocessor register: " << getCoproc() << ">"; 1325fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes break; 1326584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes case MSRMask: 1327584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes OS << "<mask: " << getMSRMask() << ">"; 1328584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes break; 1329fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Immediate: 1330fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar getImm()->print(OS); 1331fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1332706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes case MemBarrierOpt: 1333706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">"; 1334706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes break; 1335fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Memory: 13366ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << "<memory " 13377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach << " base:" << Mem.BaseRegNum; 13386ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar OS << ">"; 1339fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 13407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach case PostIndexRegister: 1341f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-") 1342f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.RegNum; 1343f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (PostIdxReg.ShiftTy != ARM_AM::no_shift) 1344f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " " 1345f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach << PostIdxReg.ShiftImm; 1346f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach OS << ">"; 13477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach break; 1348a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes case ProcIFlags: { 1349a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << "<ARM_PROC::"; 1350a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = getProcIFlags(); 1351a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i=2; i >= 0; --i) 1352a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IFlags & (1 << i)) 1353a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ARM_PROC::IFlagsToString(1 << i); 1354a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes OS << ">"; 1355a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes break; 1356a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1357fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Register: 135850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling OS << "<register " << getReg() << ">"; 1359fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1360580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach case ShifterImmediate: 1361580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl") 1362580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach << " #" << ShifterImm.Imm << ">"; 1363e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach break; 1364e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach case ShiftedRegister: 136592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_reg " 1366af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedReg.SrcReg 1367af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm)) 1368af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << RegShiftedReg.ShiftReg << ", " 1369af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm) 1370e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach << ">"; 13710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson break; 137292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson case ShiftedImmediate: 137392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson OS << "<so_reg_imm " 1374af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << RegShiftedImm.SrcReg 1375af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm)) 1376af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm) 137792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson << ">"; 137892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson break; 13797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach case RotateImmediate: 13807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach OS << "<ror " << " #" << (RotImm.Imm * 8) << ">"; 13817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach break; 1382293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach case BitfieldDescriptor: 1383293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach OS << "<bitfield " << "lsb: " << Bitfield.LSB 1384293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach << ", width: " << Bitfield.Width << ">"; 1385293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach break; 13860f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case RegisterList: 13870f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case DPRRegisterList: 13880f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling case SPRRegisterList: { 13898d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << "<register_list "; 13908d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 13915fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling const SmallVectorImpl<unsigned> &RegList = getRegList(); 13925fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling for (SmallVectorImpl<unsigned>::const_iterator 13937729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling I = RegList.begin(), E = RegList.end(); I != E; ) { 13947729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling OS << *I; 13957729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling if (++I < E) OS << ", "; 13968d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 13978d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling 13988d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling OS << ">"; 13998d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling break; 14008d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling } 1401fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar case Token: 1402fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar OS << "'" << getToken() << "'"; 1403fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar break; 1404fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar } 1405fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar} 14063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 14073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions 14083483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// { 14093483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 14103483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name); 14113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 14123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// } 14133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 141469df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo, 141569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson SMLoc &StartLoc, SMLoc &EndLoc) { 14161355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach RegNo = tryParseRegister(); 1417bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 1418bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky return (RegNo == (unsigned)-1); 1419bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky} 1420bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky 14219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name. The token must be an Identifier when called, 1422e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is 1423e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned. Otherwise return -1. 14243a69756e392942bc522193f38d7f33958ed3b131Chris Lattner/// 14251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() { 142618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 14277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) return -1; 1428d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 1429a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // FIXME: Validate register for the current architecture; we have to do 1430a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // validation later, so maybe there is no need for this here. 14310c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string upperCase = Tok.getString().str(); 14320c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson std::string lowerCase = LowercaseString(upperCase); 14330c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson unsigned RegNum = MatchRegisterName(lowerCase); 14340c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) { 14350c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson RegNum = StringSwitch<unsigned>(lowerCase) 14360c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r13", ARM::SP) 14370c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r14", ARM::LR) 14380c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("r15", ARM::PC) 14390c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Case("ip", ARM::R12) 14400c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson .Default(0); 14410c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson } 14420c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson if (!RegNum) return -1; 144369df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson 1444b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat identifier token. 1445e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner return RegNum; 1446e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner} 1447d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 144819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. 144919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error 145019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been 145119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is 145219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed). 14530d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister( 14540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 14550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 14560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson const AsmToken &Tok = Parser.getTok(); 14570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 14580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 14590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string upperCase = Tok.getString().str(); 14600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson std::string lowerCase = LowercaseString(upperCase); 14610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) 14620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsl", ARM_AM::lsl) 14630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("lsr", ARM_AM::lsr) 14640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("asr", ARM_AM::asr) 14650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("ror", ARM_AM::ror) 14660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Case("rrx", ARM_AM::rrx) 14670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson .Default(ARM_AM::no_shift); 14680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 14690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson if (ShiftTy == ARM_AM::no_shift) 147019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 1; 14710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 1472e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat the operator. 1473e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 1474e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The source register for the shift has already been added to the 1475e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // operand list, so we need to pop it off and combine it into the shifted 1476e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // register operand instead. 1477eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val()); 1478e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (!PrevOp->isReg()) 1479e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach return Error(PrevOp->getStartLoc(), "shift must be of a register"); 1480e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int SrcReg = PrevOp->getReg(); 1481e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int64_t Imm = 0; 1482e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach int ShiftReg = 0; 1483e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (ShiftTy == ARM_AM::rrx) { 1484e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // RRX Doesn't have an explicit shift amount. The encoder expects 1485e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // the shift register to be the same as the source register. Seems odd, 1486e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // but OK. 1487e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ShiftReg = SrcReg; 1488e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else { 1489e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Figure out if this is shifted by a constant or a register (for non-RRX). 1490e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 1491e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Parser.Lex(); // Eat hash. 1492e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc ImmLoc = Parser.getTok().getLoc(); 1493e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCExpr *ShiftExpr = 0; 149419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (getParser().ParseExpression(ShiftExpr)) { 149519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 149619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 149719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1498e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // The expression must be evaluatable as an immediate. 1499e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr); 150019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (!CE) { 150119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "invalid immediate shift value"); 150219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 150319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1504e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // Range check the immediate. 1505e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsl, ror: 0 <= imm <= 31 1506e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach // lsr, asr: 0 <= imm <= 32 1507e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach Imm = CE->getValue(); 1508e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach if (Imm < 0 || 1509e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) || 1510e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) { 151119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error(ImmLoc, "immediate shift value out of range"); 151219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 1513e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1514e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } else if (Parser.getTok().is(AsmToken::Identifier)) { 15151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach ShiftReg = tryParseRegister(); 1516e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach SMLoc L = Parser.getTok().getLoc(); 151719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (ShiftReg == -1) { 151819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (L, "expected immediate or register in shift operand"); 151919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 152019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 152119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } else { 152219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach Error (Parser.getTok().getLoc(), 1523e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach "expected immediate or register in shift operand"); 152419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return -1; 152519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 1526e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach } 1527e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach 152892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson if (ShiftReg && ShiftTy != ARM_AM::rrx) 152992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg, 1530af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach ShiftReg, Imm, 15310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson S, Parser.getTok().getLoc())); 153292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson else 153392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm, 153492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson S, Parser.getTok().getLoc())); 15350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 153619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return 0; 15370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson} 15380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 15390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson 154050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name. The token must be an Identifier when called. 154150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created 154250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register. 1543e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// 1544e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to 1545e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type. 154650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 15471355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1548e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner SMLoc S = Parser.getTok().getLoc(); 15491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNo = tryParseRegister(); 1550e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (RegNo == -1) 155150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1552d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 155350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1554a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1555e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner const AsmToken &ExclaimTok = Parser.getTok(); 1556e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner if (ExclaimTok.is(AsmToken::Exclaim)) { 155750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(), 155850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling ExclaimTok.getLoc())); 1559e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner Parser.Lex(); // Eat exclaim token 156099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby } 156199e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby 156250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1563a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 1564a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 1565fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related 1566fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3", 1567fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ... 1568fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) { 1569e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Use the same layout as the tablegen'erated register name matcher. Ugly, 1570e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // but efficient. 1571e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name.size()) { 1572e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: break; 1573e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 2: 1574fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp) 1575e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1576e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[1]) { 1577e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1578e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 0; 1579e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 1; 1580e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 2; 1581e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 3; 1582e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 4; 1583e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 5; 1584e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '6': return 6; 1585e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '7': return 7; 1586e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '8': return 8; 1587e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '9': return 9; 1588e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1589e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1590e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case 3: 1591fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Name[0] != CoprocOp || Name[1] != '1') 1592e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1593e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson switch (Name[2]) { 1594e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson default: return -1; 1595e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '0': return 10; 1596e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '1': return 11; 1597e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '2': return 12; 1598e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '3': return 13; 1599e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '4': return 14; 1600e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson case '5': return 15; 1601e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1602e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson break; 1603e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson } 1604e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1605e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson return -1; 1606e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1607e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 160843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The 1609fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1610fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1611f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 161243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1613e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson SMLoc S = Parser.getTok().getLoc(); 1614e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson const AsmToken &Tok = Parser.getTok(); 1615e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1616e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1617fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Num = MatchCoprocessorOperandName(Tok.getString(), 'p'); 1618e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson if (Num == -1) 1619f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1620e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1621e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson Parser.Lex(); // Eat identifier token. 1622fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocNum(Num, S)); 1623f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1624fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes} 1625fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 162643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The 1627fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor 1628fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list. 1629f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 163043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1631fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1632fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1633fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1634fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1635fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c'); 1636fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes if (Reg == -1) 1637f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1638fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 1639fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1640fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S)); 1641f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1642e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson} 1643e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 1644c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null. The first 1645c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called. 164650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 16471355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 164818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LCurly) && 1649a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Curly Brace"); 1650e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc S = Parser.getTok().getLoc(); 165116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 16527729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling // Read the rest of the registers in the list. 16537729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling unsigned PrevRegNum = 0; 16545fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling SmallVector<std::pair<unsigned, SMLoc>, 32> Registers; 1655d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 16567729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling do { 1657e717610f53e0465cde198536561a3c00ce29d59fBill Wendling bool IsRange = Parser.getTok().is(AsmToken::Minus); 16587729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.Lex(); // Eat non-identifier token. 1659d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 166018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RegTok = Parser.getTok(); 1661d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby SMLoc RegLoc = RegTok.getLoc(); 1662c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegTok.isNot(AsmToken::Identifier)) { 1663c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 166450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1665c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1666e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 16671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int RegNum = tryParseRegister(); 1668c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RegNum == -1) { 1669c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RegLoc, "register expected"); 167050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1671c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1672d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1673e717610f53e0465cde198536561a3c00ce29d59fBill Wendling if (IsRange) { 1674e717610f53e0465cde198536561a3c00ce29d59fBill Wendling int Reg = PrevRegNum; 1675e717610f53e0465cde198536561a3c00ce29d59fBill Wendling do { 1676e717610f53e0465cde198536561a3c00ce29d59fBill Wendling ++Reg; 1677e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(Reg, RegLoc)); 1678e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } while (Reg != RegNum); 1679e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } else { 1680e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Registers.push_back(std::make_pair(RegNum, RegLoc)); 1681e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1682e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1683e717610f53e0465cde198536561a3c00ce29d59fBill Wendling PrevRegNum = RegNum; 16847729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling } while (Parser.getTok().is(AsmToken::Comma) || 16857729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling Parser.getTok().is(AsmToken::Minus)); 1686e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 1687e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Process the right curly brace of the list. 168818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &RCurlyTok = Parser.getTok(); 1689c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner if (RCurlyTok.isNot(AsmToken::RCurly)) { 1690c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner Error(RCurlyTok.getLoc(), "'}' expected"); 169150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1692c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner } 1693d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 1694e717610f53e0465cde198536561a3c00ce29d59fBill Wendling SMLoc E = RCurlyTok.getLoc(); 1695e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Parser.Lex(); // Eat right curly brace token. 169603f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 1697e717610f53e0465cde198536561a3c00ce29d59fBill Wendling // Verify the register list. 16988e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling bool EmittedWarning = false; 169911e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach unsigned HighRegNum = 0; 170011e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach BitVector RegMap(32); 170111e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 170211e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach const std::pair<unsigned, SMLoc> &RegInfo = Registers[i]; 17037caebff83d90a59aa74876ff887e822387f479e0Bill Wendling unsigned Reg = getARMRegisterNumbering(RegInfo.first); 1704e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 17058e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (RegMap[Reg]) { 1706e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Error(RegInfo.second, "register duplicated in register list"); 170750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 1708e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1709e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 17108e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling if (!EmittedWarning && Reg < HighRegNum) 1711e717610f53e0465cde198536561a3c00ce29d59fBill Wendling Warning(RegInfo.second, 1712e717610f53e0465cde198536561a3c00ce29d59fBill Wendling "register not in ascending order in register list"); 1713e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 171411e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach RegMap.set(Reg); 17158e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling HighRegNum = std::max(Reg, HighRegNum); 1716e717610f53e0465cde198536561a3c00ce29d59fBill Wendling } 1717e717610f53e0465cde198536561a3c00ce29d59fBill Wendling 171850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateRegList(Registers, S, E)); 171950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 1720d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby} 1721d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby 172243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options. 1723f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 172443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1725706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1726706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1727706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1728706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes StringRef OptStr = Tok.getString(); 1729706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1730706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size())) 1731706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("sy", ARM_MB::SY) 1732706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("st", ARM_MB::ST) 1733032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("sh", ARM_MB::ISH) 1734706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ish", ARM_MB::ISH) 1735032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("shst", ARM_MB::ISHST) 1736706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("ishst", ARM_MB::ISHST) 1737706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nsh", ARM_MB::NSH) 1738032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("un", ARM_MB::NSH) 1739706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("nshst", ARM_MB::NSHST) 1740032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach .Case("unst", ARM_MB::NSHST) 1741706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("osh", ARM_MB::OSH) 1742706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Case("oshst", ARM_MB::OSHST) 1743706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes .Default(~0U); 1744706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1745706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes if (Opt == ~0U) 1746f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_NoMatch; 1747706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 1748706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1749706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); 1750f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return MatchOperand_Success; 1751706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes} 1752706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes 175343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction. 1754a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 175543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1756a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1757a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1758a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1759a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef IFlagsStr = Tok.getString(); 1760a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1761a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IFlags = 0; 1762a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes for (int i = 0, e = IFlagsStr.size(); i != e; ++i) { 1763a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1)) 1764a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("a", ARM_PROC::A) 1765a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("i", ARM_PROC::I) 1766a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("f", ARM_PROC::F) 1767a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 1768a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1769a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // If some specific iflag is already set, it means that some letter is 1770a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // present more than once, this is not acceptable. 1771a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Flag == ~0U || (IFlags & Flag)) 1772a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_NoMatch; 1773a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1774a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes IFlags |= Flag; 1775a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 1776a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1777a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1778a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S)); 1779a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes return MatchOperand_Success; 1780584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes} 1781584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 178243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction. 1783584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser:: 178443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1785584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes SMLoc S = Parser.getTok().getLoc(); 1786584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes const AsmToken &Tok = Parser.getTok(); 1787584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); 1788584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Mask = Tok.getString(); 1789584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1790584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf" 1791584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes size_t Start = 0, Next = Mask.find('_'); 1792584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes StringRef Flags = ""; 1793b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach std::string SpecReg = LowercaseString(Mask.slice(Start, Next)); 1794584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (Next != StringRef::npos) 1795584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Flags = Mask.slice(Next+1, Mask.size()); 1796584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1797584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // FlagsVal contains the complete mask: 1798584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 3-0: Mask 1799584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1800584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned FlagsVal = 0; 1801584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1802584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "apsr") { 1803584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = StringSwitch<unsigned>(Flags) 1804b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach .Case("nzcvq", 0x8) // same as CPSR_f 1805584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("g", 0x4) // same as CPSR_s 1806584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("nzcvqg", 0xc) // same as CPSR_fs 1807584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1808584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 18094b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger if (FlagsVal == ~0U) { 1810584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!Flags.empty()) 1811584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1812584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes else 1813584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0; // No flag 18144b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger } 1815584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else if (SpecReg == "cpsr" || SpecReg == "spsr") { 181656926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes if (Flags == "all") // cpsr_all is an alias for cpsr_fc 181756926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes Flags = "fc"; 1818584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes for (int i = 0, e = Flags.size(); i != e; ++i) { 1819584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1)) 1820584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("c", 1) 1821584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("x", 2) 1822584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("s", 4) 1823584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Case("f", 8) 1824584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes .Default(~0U); 1825584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1826584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // If some specific flag is already set, it means that some letter is 1827584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // present more than once, this is not acceptable. 1828584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (FlagsVal == ~0U || (FlagsVal & Flag)) 1829584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1830584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= Flag; 1831584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } 1832584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes } else // No match for special register. 1833584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_NoMatch; 1834584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1835584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Special register without flags are equivalent to "fc" flags. 1836584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (!FlagsVal) 1837584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal = 0x9; 1838584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1839584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1) 1840584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes if (SpecReg == "spsr") 1841584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes FlagsVal |= 16; 1842584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes 1843584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Parser.Lex(); // Eat identifier token. 1844584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); 1845584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes return MatchOperand_Success; 1846a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes} 1847a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 1848f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1849f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op, 1850f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Low, int High) { 1851f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1852f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1853f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1854f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1855f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1856f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach StringRef ShiftName = Tok.getString(); 1857f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string LowerOp = LowercaseString(Op); 1858f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach std::string UpperOp = UppercaseString(Op); 1859f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (ShiftName != LowerOp && ShiftName != UpperOp) { 1860f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), Op + " operand expected."); 1861f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1862f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1863f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat shift type token. 1864f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1865f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach // There must be a '#' and a shift amount. 1866f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1867f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1868f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1869f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1870f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Parser.Lex(); // Eat hash token. 1871f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1872f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCExpr *ShiftAmount; 1873f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 1874f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 1875f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "illegal expression"); 1876f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1877f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1878f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1879f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (!CE) { 1880f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "constant expression expected"); 1881f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1882f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1883f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach int Val = CE->getValue(); 1884f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach if (Val < Low || Val > High) { 1885f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Error(Loc, "immediate value out of range"); 1886f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_ParseFail; 1887f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach } 1888f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1889f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc())); 1890f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1891f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach return MatchOperand_Success; 1892f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach} 1893f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach 1894c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1895c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1896c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach const AsmToken &Tok = Parser.getTok(); 1897c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach SMLoc S = Tok.getLoc(); 1898c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1899c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1900c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 1901c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1902c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach int Val = StringSwitch<int>(Tok.getString()) 1903c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("be", 1) 1904c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Case("le", 0) 1905c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach .Default(-1); 1906c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.Lex(); // Eat the token. 1907c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1908c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (Val == -1) { 1909c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Error(Tok.getLoc(), "'be' or 'le' operand expected"); 1910c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_ParseFail; 1911c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 1912c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val, 1913c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach getContext()), 1914c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach S, Parser.getTok().getLoc())); 1915c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return MatchOperand_Success; 1916c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach} 1917c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach 1918580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT 1919580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are: 1920580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// lsl #n 'n' in [0,31] 1921580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// asr #n 'n' in [1,32] 1922580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// n == 32 encoded as n == 0. 1923580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 1924580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1925580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const AsmToken &Tok = Parser.getTok(); 1926580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc S = Tok.getLoc(); 1927580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 1928580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 1929580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1930580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1931580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach StringRef ShiftName = Tok.getString(); 1932580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach bool isASR; 1933580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (ShiftName == "lsl" || ShiftName == "LSL") 1934580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = false; 1935580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else if (ShiftName == "asr" || ShiftName == "ASR") 1936580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach isASR = true; 1937580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach else { 1938580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(S, "shift operator 'asr' or 'lsl' expected"); 1939580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1940580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1941580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat the operator. 1942580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1943580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // A '#' and a shift amount. 1944580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 1945580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 1946580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1947580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1948580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Parser.Lex(); // Eat hash token. 1949580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1950580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCExpr *ShiftAmount; 1951580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach SMLoc E = Parser.getTok().getLoc(); 1952580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 1953580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "malformed shift expression"); 1954580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1955580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1956580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 1957580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (!CE) { 1958580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "shift amount must be an immediate"); 1959580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1960580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1961580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1962580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach int64_t Val = CE->getValue(); 1963580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (isASR) { 1964580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 1965580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 1 || Val > 32) { 1966580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'asr' shift amount must be in range [1,32]"); 1967580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1968580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1969580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // asr #32 encoded as asr #0. 1970580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val == 32) Val = 0; 1971580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } else { 1972580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach // Shift amount must be in [1,32] 1973580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach if (Val < 0 || Val > 31) { 1974580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Error(E, "'lsr' shift amount must be in range [0,31]"); 1975580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_ParseFail; 1976580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1977580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach } 1978580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1979580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach E = Parser.getTok().getLoc(); 1980580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E)); 1981580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 1982580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach return MatchOperand_Success; 1983580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach} 1984580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach 19857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family 19867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are: 19877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// ror #n 'n' in {0, 8, 16, 24} 19887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 19897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 19907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const AsmToken &Tok = Parser.getTok(); 19917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc S = Tok.getLoc(); 19927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Tok.isNot(AsmToken::Identifier)) { 19937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(S, "rotate operator 'ror' expected"); 19947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 19957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 19967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach StringRef ShiftName = Tok.getString(); 19977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (ShiftName != "ror" && ShiftName != "ROR") { 19987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(S, "rotate operator 'ror' expected"); 19997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 20007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 20017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat the operator. 20027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 20037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // A '#' and a rotate amount. 20047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 20057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 20067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 20077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 20087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Parser.Lex(); // Eat hash token. 20097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 20107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCExpr *ShiftAmount; 20117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 20127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (getParser().ParseExpression(ShiftAmount)) { 20137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "malformed rotate expression"); 20147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 20157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 20167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount); 20177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (!CE) { 20187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "rotate amount must be an immediate"); 20197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 20207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 20217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 20227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach int64_t Val = CE->getValue(); 20237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension) 20247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // normally, zero is represented in asm by omitting the rotate operand 20257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach // entirely. 20267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach if (Val != 8 && Val != 16 && Val != 24 && Val != 0) { 20277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Error(E, "'ror' rotate amount must be 8, 16, or 24"); 20287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_ParseFail; 20297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach } 20307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 20317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach E = Parser.getTok().getLoc(); 20327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach Operands.push_back(ARMOperand::CreateRotImm(Val, S, E)); 20337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 20347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach return MatchOperand_Success; 20357e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach} 20367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach 2037293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2038293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2039293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc S = Parser.getTok().getLoc(); 2040293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The bitfield descriptor is really two operands, the LSB and the width. 2041293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2042293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2043293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2044293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2045293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2046293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2047293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *LSBExpr; 2048293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2049293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(LSBExpr)) { 2050293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2051293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2052293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2053293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr); 2054293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2055293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be an immediate"); 2056293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2057293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2058293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2059293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t LSB = CE->getValue(); 2060293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [0,31] 2061293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (LSB < 0 || LSB > 31) { 2062293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'lsb' operand must be in the range [0,31]"); 2063293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2064293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2065293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2066293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2067293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // Expect another immediate operand. 2068293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Comma)) { 2069293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "too few operands"); 2070293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2071293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2072293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2073293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Parser.getTok().isNot(AsmToken::Hash)) { 2074293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(Parser.getTok().getLoc(), "'#' expected"); 2075293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2076293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2077293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Parser.Lex(); // Eat hash token. 2078293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2079293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach const MCExpr *WidthExpr; 2080293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (getParser().ParseExpression(WidthExpr)) { 2081293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "malformed immediate expression"); 2082293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2083293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2084293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach CE = dyn_cast<MCConstantExpr>(WidthExpr); 2085293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (!CE) { 2086293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be an immediate"); 2087293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2088293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2089293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2090293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach int64_t Width = CE->getValue(); 2091293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach // The LSB must be in the range [1,32-lsb] 2092293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach if (Width < 1 || Width > 32 - LSB) { 2093293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Error(E, "'width' operand must be in the range [1,32-lsb]"); 2094293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_ParseFail; 2095293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach } 2096293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach E = Parser.getTok().getLoc(); 2097293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2098293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E)); 2099293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 2100293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach return MatchOperand_Success; 2101293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach} 2102293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach 21037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 21047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 21057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2106f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // postidx_reg := '+' register {, shift} 2107f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | '-' register {, shift} 2108f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // | register {, shift} 21097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 21107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 21117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // in the case where there is no match, as other alternatives take other 21127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // parse methods. 21137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach AsmToken Tok = Parser.getTok(); 21147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc S = Tok.getLoc(); 21157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool haveEaten = false; 211616578b50889329eb62774148091ba0f38b681a09Jim Grosbach bool isAdd = true; 21177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int Reg = -1; 21187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::Plus)) { 21197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+' token. 21207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 21217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 21227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-' token. 212316578b50889329eb62774148091ba0f38b681a09Jim Grosbach isAdd = false; 21247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach haveEaten = true; 21257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 21267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 21277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Reg = tryParseRegister(); 21287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Reg == -1) { 21297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!haveEaten) 21307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_NoMatch; 21317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 21327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_ParseFail; 21337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 21347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 21357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2136f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift; 2137f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach unsigned ShiftImm = 0; 21380d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 21390d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach Parser.Lex(); // Eat the ','. 21400d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftTy, ShiftImm)) 21410d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach return MatchOperand_ParseFail; 21420d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach } 2143f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach 2144f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy, 2145f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach ShiftImm, S, E)); 21467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 21477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return MatchOperand_Success; 21487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 21497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2150251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser:: 2151251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2152251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Check for a post-index addressing register operand. Specifically: 2153251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // am3offset := '+' register 2154251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | '-' register 2155251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | register 2156251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # imm 2157251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # + imm 2158251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // | # - imm 2159251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2160251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // This method must return MatchOperand_NoMatch without consuming any tokens 2161251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // in the case where there is no match, as other alternatives take other 2162251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // parse methods. 2163251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach AsmToken Tok = Parser.getTok(); 2164251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc S = Tok.getLoc(); 2165251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2166251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Do immediates first, as we always parse those if we have a '#'. 2167251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 2168251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '#'. 2169251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Explicitly look for a '-', as we need to encode negative zero 2170251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // differently. 2171251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isNegative = Parser.getTok().is(AsmToken::Minus); 2172251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCExpr *Offset; 2173251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (getParser().ParseExpression(Offset)) 2174251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2175251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 2176251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!CE) { 2177251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(S, "constant expression expected"); 2178251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2179251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2180251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Tok.getLoc(); 2181251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach // Negative zero is encoded as the flag value INT32_MIN. 2182251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int32_t Val = CE->getValue(); 2183251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (isNegative && Val == 0) 2184251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Val = INT32_MIN; 2185251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2186251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back( 2187251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E)); 2188251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2189251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2190251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2191251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2192251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2193251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool haveEaten = false; 2194251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach bool isAdd = true; 2195251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach int Reg = -1; 2196251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Tok.is(AsmToken::Plus)) { 2197251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '+' token. 2198251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2199251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } else if (Tok.is(AsmToken::Minus)) { 2200251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Parser.Lex(); // Eat the '-' token. 2201251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach isAdd = false; 2202251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach haveEaten = true; 2203251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2204251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Parser.getTok().is(AsmToken::Identifier)) 2205251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Reg = tryParseRegister(); 2206251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (Reg == -1) { 2207251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach if (!haveEaten) 2208251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_NoMatch; 2209251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Error(Parser.getTok().getLoc(), "register expected"); 2210251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_ParseFail; 2211251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach } 2212251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach SMLoc E = Parser.getTok().getLoc(); 2213251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2214251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift, 2215251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 0, S, E)); 2216251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 2217251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach return MatchOperand_Success; 2218251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach} 2219251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach 22201355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2221ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2222ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2223ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 22241355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2225ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2226ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2227ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 2228ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2229ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2230ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 22317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2232ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2233ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2234ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2235ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 2236548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst. 2237548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2238548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2239548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser:: 2240548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode, 2241548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2242548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach // Create a writeback register dummy placeholder. 2243548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2244548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2245548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2); 2246548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2247548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach return true; 2248548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach} 2249548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach 22501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst. 2251ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2252ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2253ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser:: 22541355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode, 2255ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2256ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes // Create a writeback register dummy placeholder. 2257ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 2258548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2259548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3); 2260548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 22617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 22627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 22637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 22647b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 22657b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 22667b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one. 22677b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser:: 22687b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 22697b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22707b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach // Create a writeback register dummy placeholder. 22717b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 22727b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 22737b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 22747b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 22757b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach return true; 22767b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach} 22777b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach 22787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst. 22797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 22807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 22817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 22827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 22837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 22847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2285ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 22867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 22877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 22887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 22897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 22907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 22917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 22927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2293ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2294ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes return true; 2295ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes} 2296ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes 22977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst. 2298ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2299ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2300ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 23017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 23027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 23037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2304aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2305ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2306ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 23077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 23087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 23097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 23107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 23117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 23127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 23137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 23147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach} 2315aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson 23167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst. 23177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 23187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one. 23197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser:: 23207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode, 23217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 23227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Create a writeback register dummy placeholder. 23237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 23247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 23257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 23267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 23277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 23287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 23297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1); 23307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2331ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2332ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2333ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2334ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 23357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst. 2336ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2337ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one. 2338ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser:: 23397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode, 23407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2341ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes // Create a writeback register dummy placeholder. 2342ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes Inst.addOperand(MCOperand::CreateImm(0)); 23437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Rt 2344ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 23457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // addr 23467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1); 23477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset 23487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2); 23497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // pred 2350ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2351ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes return true; 2352ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes} 2353ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes 23542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst. 23552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 23562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one. 23572fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser:: 23582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode, 23592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 23602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Rt, Rt2 23612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 23622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 23632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // Create a writeback register dummy placeholder. 23642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 23652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // addr 23662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 23672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach // pred 23682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 23692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach return true; 23702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach} 23712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach 237214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst. 237314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 237414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one. 237514605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser:: 237614605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode, 237714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 237814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Create a writeback register dummy placeholder. 237914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 238014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt, Rt2 238114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 238214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 238314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // addr 238414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3); 238514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // pred 238614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 238714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return true; 238814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach} 238914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach 2390623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst. 2391623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 2392623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one. 2393623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser:: 2394623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode, 2395623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2396623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1); 2397623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach // Create a writeback register dummy placeholder. 2398623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach Inst.addOperand(MCOperand::CreateImm(0)); 2399623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3); 2400623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2); 2401623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach return true; 2402623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach} 2403623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 240488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst. 240588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands 240688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one. 240788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser:: 240888ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode, 240988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 241088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The second source operand must be the same register as the destination 241188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // operand. 241288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach if (Operands.size() == 6 && 24137a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 24147a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->getReg()) && 24157a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach (((ARMOperand*)Operands[3])->getReg() != 24167a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[4])->getReg())) { 241788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach Error(Operands[3]->getStartLoc(), 24187a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach "destination register must match source register"); 241988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return false; 242088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach } 242188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1); 242288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1); 242388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1); 24247a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // If we have a three-operand form, use that, else the second source operand 24257a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach // is just the destination operand again. 24267a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach if (Operands.size() == 6) 24277a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1); 24287a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach else 24297a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach Inst.addOperand(Inst.getOperand(0)); 243088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2); 243188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach 243288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 243388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach} 2434623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach 2435e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true 24369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error. The first token must be a '[' when called. 243750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser:: 24387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2439762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 244018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan assert(Parser.getTok().is(AsmToken::LBrac) && 2441a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling "Token is not a Left Bracket"); 2442762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2443b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat left bracket token. 2444a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 244518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &BaseRegTok = Parser.getTok(); 24461355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach int BaseRegNum = tryParseRegister(); 24477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (BaseRegNum == -1) 24487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(BaseRegTok.getLoc(), "register expected"); 2449a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 24500571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar // The next token must either be a comma or a closing bracket. 24510571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar const AsmToken &Tok = Parser.getTok(); 24520571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac)) 24537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Tok.getLoc(), "malformed memory operand"); 24540571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar 24557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Tok.is(AsmToken::RBrac)) { 2456762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = Tok.getLoc(); 2457b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat right bracket token. 2458a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 24597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift, 24607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 0, false, S, E)); 246103f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach 24627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 24637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 246450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 24657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!"); 24667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the comma. 246750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 24687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If we have a '#' it's an immediate offset, else assume it's a register 24697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // offset. 24707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Hash)) { 24717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '#'. 24727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 247350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling 24747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // FIXME: Special case #-0 so we can correctly set the U bit. 2475e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby 24767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Offset; 24777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Offset)) 24787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 247905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 24807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The expression has to be a constant. Memory references with relocations 24817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // don't come through here, as they use the <label> forms of the relevant 24827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // instructions. 24837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset); 24847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 24857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error (E, "constant expression expected"); 24867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 24877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 24887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 24897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 24907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 24917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 249205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar 24937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Don't worry about range checking the value here. That's handled by 24947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // the is*() predicates. 24957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0, 24967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::no_shift, 0, false, S,E)); 2497a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 24987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 24997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // operand. 25007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 25017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 25027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '!'. 2503762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan } 25047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 25057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return false; 25069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 2507d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach 25087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // The register offset is optionally preceded by a '+' or '-' 25097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach bool isNegative = false; 25107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Minus)) { 25117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach isNegative = true; 25127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '-'. 25137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } else if (Parser.getTok().is(AsmToken::Plus)) { 25147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Nothing to do. 25157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the '+'. 25167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 25179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 25187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 25197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int OffsetRegNum = tryParseRegister(); 25207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (OffsetRegNum == -1) 25217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "register expected"); 25227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 25237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // If there's a shift operator, handle it. 25247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift; 25250d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach unsigned ShiftImm = 0; 25267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().is(AsmToken::Comma)) { 25277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat the ','. 25280d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach if (parseMemRegOffsetShift(ShiftType, ShiftImm)) 25297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 25309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby } 253116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 25327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Now we should have the closing ']' 25337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach E = Parser.getTok().getLoc(); 25347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Parser.getTok().isNot(AsmToken::RBrac)) 25357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(E, "']' expected"); 25367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat right bracket token. 25377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 25387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum, 25390d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach ShiftType, ShiftImm, isNegative, 25407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach S, E)); 25417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach 2542f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // If there's a pre-indexing writeback marker, '!', just add it as a token 2543f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach // operand. 2544f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach if (Parser.getTok().is(AsmToken::Exclaim)) { 2545f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc())); 2546f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach Parser.Lex(); // Eat the '!'. 2547f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach } 25489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 25499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby return false; 25509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby} 25519c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 25527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two: 2553a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ( lsl | lsr | asr | ror ) , # shift_amount 2554a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// rrx 25557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false. 25567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St, 25577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach unsigned &Amount) { 25587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach SMLoc Loc = Parser.getTok().getLoc(); 255918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 2560a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (Tok.isNot(AsmToken::Identifier)) 2561a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return true; 256238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef ShiftName = Tok.getString(); 2563a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby if (ShiftName == "lsl" || ShiftName == "LSL") 25640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsl; 2565a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "lsr" || ShiftName == "LSR") 25660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::lsr; 2567a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "asr" || ShiftName == "ASR") 25680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::asr; 2569a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "ror" || ShiftName == "ROR") 25700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::ror; 2571a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else if (ShiftName == "rrx" || ShiftName == "RRX") 25720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson St = ARM_AM::rrx; 2573a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby else 25747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "illegal shift operator"); 2575b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat shift type token. 2576a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 25777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // rrx stands alone. 25787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = 0; 25797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (St != ARM_AM::rrx) { 25807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Loc = Parser.getTok().getLoc(); 25817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // A '#' and a shift amount. 25827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const AsmToken &HashTok = Parser.getTok(); 25837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (HashTok.isNot(AsmToken::Hash)) 25847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(HashTok.getLoc(), "'#' expected"); 25857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Parser.Lex(); // Eat hash token. 25869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby 25877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCExpr *Expr; 25887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (getParser().ParseExpression(Expr)) 25897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return true; 25907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // Range check the immediate. 25917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsl, ror: 0 <= imm <= 31 25927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach // lsr, asr: 0 <= imm <= 32 25937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 25947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (!CE) 25957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "shift amount must be an immediate"); 25967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach int64_t Imm = CE->getValue(); 25977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach if (Imm < 0 || 25987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) || 25997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32)) 26007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach return Error(Loc, "immediate shift value out of range"); 26017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach Amount = Imm; 26027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach } 2603a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 2604a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby return false; 2605a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2606a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 26079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand. For now this parses the operand regardless 26089c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic. 26091355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 2610fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes StringRef Mnemonic) { 2611762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan SMLoc S, E; 2612fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2613fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // Check if the current operand has a custom associated parser, if so, try to 2614fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes // custom parse the operand, or fallback to the general approach. 2615f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 2616f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_Success) 2617fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes return false; 2618f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // If there wasn't a custom match, try the generic matcher below. Otherwise, 2619f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // there was a match, but an error occurred, in which case, just return that 2620f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach // the operand parsing failed. 2621f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach if (ResTy == MatchOperand_ParseFail) 2622f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach return true; 2623fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes 2624a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby switch (getLexer().getKind()) { 2625146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling default: 2626146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling Error(Parser.getTok().getLoc(), "unexpected token in operand"); 262750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 262819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach case AsmToken::Identifier: { 26291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (!tryParseRegisterWithWriteBack(Operands)) 263050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 26310d87ec21d79c8622733b8367aa41067169602480Jim Grosbach int Res = tryParseShiftRegister(Operands); 263219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach if (Res == 0) // success 26330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson return false; 263419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach else if (Res == -1) // irrecoverable error 263519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach return true; 2636e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson 2637e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // Fall though for the Identifier case that is not a register or a 2638e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson // special name. 263919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach } 264067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Integer: // things like 1f and 2b as a branch targets 264167b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby case AsmToken::Dot: { // . as a branch target 2642515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // This was not a register so parse other operands that start with an 2643515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // identifier (like labels) as expressions and create them as immediates. 2644515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *IdVal; 2645762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2646515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(IdVal)) 264750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2648762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 264950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(IdVal, S, E)); 265050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 265150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling } 2652a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby case AsmToken::LBrac: 26531355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseMemory(Operands); 2654d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::LCurly: 26551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseRegisterList(Operands); 2656d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby case AsmToken::Hash: 2657079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // #42 -> immediate. 2658079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate 2659762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan S = Parser.getTok().getLoc(); 2660b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 2661515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby const MCExpr *ImmVal; 2662515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getParser().ParseExpression(ImmVal)) 266350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return true; 2664762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 266550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E)); 266650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling return false; 26679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case AsmToken::Colon: { 26689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // ":lower16:" and ":upper16:" expression prefixes 26697597212abced110723f2fee985a7d60557c092ecEvan Cheng // FIXME: Check it's an expression prefix, 26707597212abced110723f2fee985a7d60557c092ecEvan Cheng // e.g. (FOO - :lower16:BAR) isn't legal. 26717597212abced110723f2fee985a7d60557c092ecEvan Cheng ARMMCExpr::VariantKind RefKind; 26721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parsePrefix(RefKind)) 26739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 26749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26757597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *SubExprVal; 26767597212abced110723f2fee985a7d60557c092ecEvan Cheng if (getParser().ParseExpression(SubExprVal)) 26779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 26789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26797597212abced110723f2fee985a7d60557c092ecEvan Cheng const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal, 26807597212abced110723f2fee985a7d60557c092ecEvan Cheng getContext()); 26819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 26827597212abced110723f2fee985a7d60557c092ecEvan Cheng Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E)); 26839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 26849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 2685a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 2686a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} 2687a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 26881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e. 26897597212abced110723f2fee985a7d60557c092ecEvan Cheng// :lower16: and :upper16:. 26901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) { 26917597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_None; 26929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // :lower16: and :upper16: modifiers 26948a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim assert(getLexer().is(AsmToken::Colon) && "expected a :"); 26959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat ':' 26969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 26979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Identifier)) { 26989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "expected prefix identifier in operand"); 26999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 27009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 27019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim StringRef IDVal = Parser.getTok().getIdentifier(); 27039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (IDVal == "lower16") { 27047597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_LO16; 27059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else if (IDVal == "upper16") { 27067597212abced110723f2fee985a7d60557c092ecEvan Cheng RefKind = ARMMCExpr::VK_ARM_HI16; 27079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } else { 27089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected prefix in operand"); 27099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 27109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 27119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); 27129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (getLexer().isNot(AsmToken::Colon)) { 27149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Error(Parser.getTok().getLoc(), "unexpected token after prefix"); 27159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return true; 27169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 27179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim Parser.Lex(); // Eat the last ':' 27189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return false; 27199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 27209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr * 27221355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachARMAsmParser::applyPrefixToExpr(const MCExpr *E, 27239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim MCSymbolRefExpr::VariantKind Variant) { 27249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // Recurse over the given expression, rebuilding it to apply the given variant 27259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim // to the leftmost symbol. 27269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (Variant == MCSymbolRefExpr::VK_None) 27279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return E; 27289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim switch (E->getKind()) { 27309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Target: 27319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle target expr yet"); 27329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Constant: 27339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle lower16/upper16 of constant yet"); 27349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::SymbolRef: { 27369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); 27379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (SRE->getKind() != MCSymbolRefExpr::VK_None) 27399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 27409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext()); 27429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 27439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Unary: 27459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim llvm_unreachable("Can't handle unary expressions yet"); 27469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim case MCExpr::Binary: { 27489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCBinaryExpr *BE = cast<MCBinaryExpr>(E); 27491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach const MCExpr *LHS = applyPrefixToExpr(BE->getLHS(), Variant); 27509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim const MCExpr *RHS = BE->getRHS(); 27519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim if (!LHS) 27529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 27539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext()); 27559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 27569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim } 27579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 27589081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim assert(0 && "Invalid expression kind!"); 27599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim return 0; 27609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim} 27619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim 2762352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry 2763352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags. 2764352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar// 2765badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this. 27661355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, 27675f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &PredicationCode, 27685f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach bool &CarrySetting, 27695f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach unsigned &ProcessorIMod) { 2770352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar PredicationCode = ARMCC::AL; 2771352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = false; 2772a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = 0; 2773352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2774badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Ignore some mnemonics we know aren't predicated forms. 2775352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // 2776352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // FIXME: Would be nice to autogen this. 27775f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach if ((Mnemonic == "movs" && isThumb()) || 27785f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "teq" || Mnemonic == "vceq" || Mnemonic == "svc" || 27795f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" || 27805f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmls" || Mnemonic == "vnmls" || Mnemonic == "vacge" || 27815f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcge" || Mnemonic == "vclt" || Mnemonic == "vacgt" || 27825f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" || 27835f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || 27845f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal") 2785352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2786badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 27873f00e317064560ad11168d22030416d853829f6eJim Grosbach // First, split out any predication code. Ignore mnemonics we know aren't 27883f00e317064560ad11168d22030416d853829f6eJim Grosbach // predicated but do have a carry-set and so weren't caught above. 2789ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && 279071725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && 279104d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && 279204d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach Mnemonic != "sbcs") { 27933f00e317064560ad11168d22030416d853829f6eJim Grosbach unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2)) 27943f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("eq", ARMCC::EQ) 27953f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ne", ARMCC::NE) 27963f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hs", ARMCC::HS) 27973f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cs", ARMCC::HS) 27983f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lo", ARMCC::LO) 27993f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("cc", ARMCC::LO) 28003f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("mi", ARMCC::MI) 28013f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("pl", ARMCC::PL) 28023f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vs", ARMCC::VS) 28033f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("vc", ARMCC::VC) 28043f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("hi", ARMCC::HI) 28053f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ls", ARMCC::LS) 28063f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("ge", ARMCC::GE) 28073f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("lt", ARMCC::LT) 28083f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("gt", ARMCC::GT) 28093f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("le", ARMCC::LE) 28103f00e317064560ad11168d22030416d853829f6eJim Grosbach .Case("al", ARMCC::AL) 28113f00e317064560ad11168d22030416d853829f6eJim Grosbach .Default(~0U); 28123f00e317064560ad11168d22030416d853829f6eJim Grosbach if (CC != ~0U) { 28133f00e317064560ad11168d22030416d853829f6eJim Grosbach Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); 28143f00e317064560ad11168d22030416d853829f6eJim Grosbach PredicationCode = CC; 28153f00e317064560ad11168d22030416d853829f6eJim Grosbach } 281652925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling } 2817345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 2818352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Next, determine if we have a carry setting bit. We explicitly ignore all 2819352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // the instructions we know end in 's'. 2820352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar if (Mnemonic.endswith("s") && 282100f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach !(Mnemonic == "cps" || Mnemonic == "mls" || 28225f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" || 28235f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" || 28245f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" || 2825e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach Mnemonic == "vrsqrts" || Mnemonic == "srs" || 2826e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach (Mnemonic == "movs" && isThumb()))) { 2827352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1); 2828352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar CarrySetting = true; 2829352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar } 2830352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar 2831a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // The "cps" instruction can have a interrupt mode operand which is glued into 2832a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // the mnemonic. Check if this is the case, split it and parse the imod op 2833a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (Mnemonic.startswith("cps")) { 2834a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Split out any imod code. 2835a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned IMod = 2836a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2)) 2837a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("ie", ARM_PROC::IE) 2838a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Case("id", ARM_PROC::ID) 2839a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes .Default(~0U); 2840a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (IMod != ~0U) { 2841a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2); 2842a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes ProcessorIMod = IMod; 2843a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2844a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 2845a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 2846352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar return Mnemonic; 2847352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar} 28483771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 28493771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows 28503771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands. 28513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// 28523771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this. 2853fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser:: 28541355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, 2855fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes bool &CanAcceptPredicationCode) { 2856eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" || 2857eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" || 2858eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" || 2859eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" || 2860be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" || 2861eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" || 2862eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" || 28632c3f70e5d4b4f179f21ed1b2ba14674f9d65c9b0Jim Grosbach Mnemonic == "eor" || Mnemonic == "smlal" || Mnemonic == "neg" || 2864194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // FIXME: We need a better way. This really confused Thumb2 2865194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // parsing for 'mov'. 2866ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng (Mnemonic == "mov" && !isThumbOne())) { 2867eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = true; 2868eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } else { 2869eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar CanAcceptCarrySet = false; 2870eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar } 28713771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 2872eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" || 2873eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" || 2874eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" || 2875eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" || 28765f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" || 2877c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Mnemonic == "setend" || 28780780b6303b99441fef04340b7a083006484f4743Jim Grosbach (Mnemonic == "nop" && isThumbOne()) || 287948c693ff564c422153733424ab845106161430acJim Grosbach ((Mnemonic == "pld" || Mnemonic == "pli") && !isThumb()) || 2880e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) 2881e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach && !isThumb()) || 28825f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) { 28833771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = false; 28843771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } else { 28853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar CanAcceptPredicationCode = true; 28863771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar } 2887fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes 2888ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (isThumb()) 2889fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" || 289063b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp") 2891fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes CanAcceptPredicationCode = false; 2892badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar} 2893badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2894d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic, 2895d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2896d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 2897d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // The 'mov' mnemonic is special. One variant has a cc_out operand, while 2898d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // another does not. Specifically, the MOVW instruction does not. So we 2899d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // special case it here and remove the defaulted (non-setting) cc_out 2900d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // operand if that's the instruction we're trying to match. 2901d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // 2902d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // We do this as post-processing of the explicit operands rather than just 2903d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // conditionally adding the cc_out in the first place because we need 2904d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // to check the type of the parsed immediate operand. 2905d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach if (Mnemonic == "mov" && Operands.size() > 4 && 2906d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() && 2907d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() && 2908d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 2909d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return true; 29103912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 29113912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 29123912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach // when there are only two register operands. 29133912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 5 && 29143912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 29153912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 29163912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 29173912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach return true; 291872f39f8436848885176943b0ba985a7171145423Jim Grosbach // Register-register 'add' for thumb does not have a cc_out operand 291972f39f8436848885176943b0ba985a7171145423Jim Grosbach // when it's an ADD Rdm, SP, {Rdm|#imm} instruction. 292072f39f8436848885176943b0ba985a7171145423Jim Grosbach if (isThumb() && Mnemonic == "add" && Operands.size() == 6 && 292172f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 292272f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->isReg() && 292372f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP && 292472f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 292572f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 2926f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // Register-register 'add/sub' for thumb does not have a cc_out operand 2927f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also 2928f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't 2929f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // right, this will result in better diagnostics (which operand is off) 2930f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach // anyway. 2931f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") && 2932f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach (Operands.size() == 5 || Operands.size() == 6) && 293372f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->isReg() && 293472f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP && 293572f39f8436848885176943b0ba985a7171145423Jim Grosbach static_cast<ARMOperand*>(Operands[1])->getReg() == 0) 293672f39f8436848885176943b0ba985a7171145423Jim Grosbach return true; 29373912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach 2938d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach return false; 2939d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach} 2940d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach 2941badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands. 2942badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, 2943badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 2944badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar // Create the leading tokens for the mnemonic, split by '.' characters. 2945badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar size_t Start = 0, Next = Name.find('.'); 2946ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach StringRef Mnemonic = Name.slice(Start, Next); 2947badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 2948352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar // Split out the predication code and carry setting flag from the mnemonic. 2949352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar unsigned PredicationCode; 2950a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes unsigned ProcessorIMod; 2951352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar bool CarrySetting; 29521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting, 2953c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach ProcessorIMod); 2954badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar 29550c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach // In Thumb1, only the branch (B) instruction can be predicated. 29560c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") { 29570c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach Parser.EatToEndOfStatement(); 29580c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach return Error(NameLoc, "conditional execution not supported in Thumb1"); 29590c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach } 29600c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach 2961ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc)); 2962ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 2963ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // FIXME: This is all a pretty gross hack. We should automatically handle 2964ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach // optional operands like this via tblgen. 29659717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling 29663771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Next, add the CCOut and ConditionCode operands, if needed. 29673771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 29683771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // For mnemonics which can ever incorporate a carry setting bit or predication 29693771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // code, our matching model involves us always generating CCOut and 29703771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // ConditionCode operands to match the mnemonic "as written" and then we let 29713771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // the matcher deal with finding the right instruction or generating an 29723771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // appropriate error. 29733771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar bool CanAcceptCarrySet, CanAcceptPredicationCode; 29741355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode); 29753771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 297633c16a27370939de39679245c3dff72383c210bdJim Grosbach // If we had a carry-set on an instruction that can't do that, issue an 297733c16a27370939de39679245c3dff72383c210bdJim Grosbach // error. 297833c16a27370939de39679245c3dff72383c210bdJim Grosbach if (!CanAcceptCarrySet && CarrySetting) { 297933c16a27370939de39679245c3dff72383c210bdJim Grosbach Parser.EatToEndOfStatement(); 2980ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 298133c16a27370939de39679245c3dff72383c210bdJim Grosbach "' can not set flags, but 's' suffix specified"); 298233c16a27370939de39679245c3dff72383c210bdJim Grosbach } 2983c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // If we had a predication code on an instruction that can't do that, issue an 2984c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach // error. 2985c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) { 2986c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach Parser.EatToEndOfStatement(); 2987c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach return Error(NameLoc, "instruction '" + Mnemonic + 2988c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach "' is not predicable, but condition code specified"); 2989c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach } 299033c16a27370939de39679245c3dff72383c210bdJim Grosbach 29913771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the carry setting operand, if necessary. 29923771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 29933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // FIXME: It would be awesome if we could somehow invent a location such that 29943771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // match errors on this operand would print a nice diagnostic about how the 29953771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // 's' character in the mnemonic resulted in a CCOut operand. 299633c16a27370939de39679245c3dff72383c210bdJim Grosbach if (CanAcceptCarrySet) 29973771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, 29983771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar NameLoc)); 29993771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar 30003771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar // Add the predication code operand, if necessary. 30013771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar if (CanAcceptPredicationCode) { 30023771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar Operands.push_back(ARMOperand::CreateCondCode( 30033771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar ARMCC::CondCodes(PredicationCode), NameLoc)); 3004badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar } 3005345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar 3006a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // Add the processor imod operand, if necessary. 3007a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes if (ProcessorIMod) { 3008a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes Operands.push_back(ARMOperand::CreateImm( 3009a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes MCConstantExpr::Create(ProcessorIMod, getContext()), 3010a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes NameLoc, NameLoc)); 3011a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } else { 3012a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // This mnemonic can't ever accept a imod, but the user wrote 3013a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // one (or misspelled another mnemonic). 3014a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 3015a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes // FIXME: Issue a nice error. 3016a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes } 3017a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes 3018345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar // Add the remaining tokens in the mnemonic. 30195747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar while (Next != StringRef::npos) { 30205747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Start = Next; 30215747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar Next = Name.find('.', Start + 1); 3022a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes StringRef ExtraToken = Name.slice(Start, Next); 3023a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 30244d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // For now, we're only parsing Thumb1 (for the most part), so 30254d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // just ignore ".n" qualifiers. We'll use them to restrict 30264d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach // matching when we do Thumb2. 30274d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach if (ExtraToken != ".n") 30284d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc)); 30295747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar } 30305747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar 30315747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar // Read the remaining operands. 30325747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) { 3033a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Read the first operand. 30341355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 3035cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 3036cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 3037cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3038a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3039a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby while (getLexer().is(AsmToken::Comma)) { 3040b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); // Eat the comma. 3041a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby 3042a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby // Parse and remember the operand. 30431355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach if (parseOperand(Operands, Mnemonic)) { 3044cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 3045cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner return true; 3046cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3047a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 3048a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby } 304916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3050cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner if (getLexer().isNot(AsmToken::EndOfStatement)) { 3051cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner Parser.EatToEndOfStatement(); 305234e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner return TokError("unexpected token in argument list"); 3053cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner } 3054146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling 305534e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner Parser.Lex(); // Consume the EndOfStatement 3056ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 3057d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // Some instructions, mostly Thumb, have forms for the same mnemonic that 3058d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // do and don't have a cc_out optional-def operand. With some spot-checks 3059d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // of the operand list, we can figure out which variant we're trying to 3060d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // parse and adjust accordingly before actually matching. Reason number 3061d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // #317 the table driven matcher doesn't fit well with the ARM instruction 3062d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach // set. 3063d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach if (shouldOmitCCOutOperand(Mnemonic, Operands)) { 3064ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 3065ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach Operands.erase(Operands.begin() + 1); 3066ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach delete Op; 3067ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach } 3068ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach 3069cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // ARM mode 'blx' need special handling, as the register operand version 3070cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // is predicable, but the label operand version is not. So, we can't rely 3071cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // on the Mnemonic based checking to correctly figure out when to put 3072cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // a CondCode operand in the list. If we're trying to match the label 3073cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach // version, remove the CondCode operand here. 3074cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 && 3075cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach static_cast<ARMOperand*>(Operands[2])->isImm()) { 3076cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]); 3077cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach Operands.erase(Operands.begin() + 1); 3078cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach delete Op; 3079cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach } 3080857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach 3081857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // The vector-compare-to-zero instructions have a literal token "#0" at 3082857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // the end that comes to here as an immediate operand. Convert it to a 3083857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach // token to play nicely with the matcher. 3084857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || 3085857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && 3086857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 3087857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 3088857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3089857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach if (CE && CE->getValue() == 0) { 3090857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.erase(Operands.begin() + 5); 3091857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3092857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach delete Op; 3093857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 3094857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach } 3095934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the 3096934755ac040c516eac7fdd974e87590543acd16aJim Grosbach // end. Convert it to a token here. 3097934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 && 3098934755ac040c516eac7fdd974e87590543acd16aJim Grosbach static_cast<ARMOperand*>(Operands[5])->isImm()) { 3099934755ac040c516eac7fdd974e87590543acd16aJim Grosbach ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); 3100934755ac040c516eac7fdd974e87590543acd16aJim Grosbach const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); 3101934755ac040c516eac7fdd974e87590543acd16aJim Grosbach if (CE && CE->getValue() == 0) { 3102934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.erase(Operands.begin() + 5); 3103934755ac040c516eac7fdd974e87590543acd16aJim Grosbach Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); 3104934755ac040c516eac7fdd974e87590543acd16aJim Grosbach delete Op; 3105934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 3106934755ac040c516eac7fdd974e87590543acd16aJim Grosbach } 3107934755ac040c516eac7fdd974e87590543acd16aJim Grosbach 31089898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner return false; 3109ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3110ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3111189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints. 3112aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 3113aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers, 3114aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set 3115aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true. 3116aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg, 3117aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned HiReg, bool &containsReg) { 3118aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = false; 3119aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) { 3120aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach unsigned OpReg = Inst.getOperand(i).getReg(); 3121aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (OpReg == Reg) 3122aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach containsReg = true; 3123aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach // Anything other than a low register isn't legal here. 3124aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg)) 3125aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return true; 3126aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach } 3127aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return false; 3128aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach} 3129aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach 3130189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this. 3131189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser:: 3132189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst, 3133189610f9466686a91fb7d847b572e1645c785323Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3134189610f9466686a91fb7d847b572e1645c785323Jim Grosbach switch (Inst.getOpcode()) { 31352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD: 31362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_PRE: 31372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach case ARM::LDRD_POST: 3138189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::LDREXD: { 3139189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 3140189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 3141189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 3142189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 3143189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return Error(Operands[3]->getStartLoc(), 3144189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "destination operands must be sequential"); 3145189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3146189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 314714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach case ARM::STRD: { 314814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach // Rt2 must be Rt + 1. 314914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg()); 315014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 315114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach if (Rt2 != Rt + 1) 315214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 315314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach "source operands must be sequential"); 315414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return false; 315514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach } 315653642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_PRE: 315753642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach case ARM::STRD_POST: 3158189610f9466686a91fb7d847b572e1645c785323Jim Grosbach case ARM::STREXD: { 3159189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Rt2 must be Rt + 1. 3160189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg()); 3161189610f9466686a91fb7d847b572e1645c785323Jim Grosbach unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg()); 3162189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (Rt2 != Rt + 1) 316314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach return Error(Operands[3]->getStartLoc(), 3164189610f9466686a91fb7d847b572e1645c785323Jim Grosbach "source operands must be sequential"); 3165189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3166189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 3167fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::SBFX: 3168fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach case ARM::UBFX: { 3169fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach // width must be in range [1, 32-lsb] 3170fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned lsb = Inst.getOperand(2).getImm(); 3171fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach unsigned widthm1 = Inst.getOperand(3).getImm(); 3172fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach if (widthm1 >= 32 - lsb) 3173fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach return Error(Operands[5]->getStartLoc(), 3174fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach "bitfield width must be in range [1,32-lsb]"); 317500c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach return false; 3176fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach } 317793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach case ARM::tLDMIA: { 317893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // Thumb LDM instructions are writeback iff the base register is not 317993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // in the register list. 318093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach unsigned Rn = Inst.getOperand(0).getReg(); 31817260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach bool hasWritebackToken = 31827260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach (static_cast<ARMOperand*>(Operands[3])->isToken() && 31837260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); 3184aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 3185aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase)) 3186aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[3 + hasWritebackToken]->getStartLoc(), 3187aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7"); 318893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach // If we should have writeback, then there should be a '!' token. 3189aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (!listContainsBase && !hasWritebackToken) 319093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach return Error(Operands[2]->getStartLoc(), 319193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach "writeback operator '!' expected"); 31927260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach // Likewise, if we should not have writeback, there must not be a '!' 3193aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (listContainsBase && hasWritebackToken) 31947260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach return Error(Operands[3]->getStartLoc(), 31957260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "writeback operator '!' not allowed when base register " 31967260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach "in register list"); 319793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach 319893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach break; 319993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach } 32006dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPOP: { 3201aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 3202aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase)) 3203aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 3204aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or pc"); 32056dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 32066dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 32076dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach case ARM::tPUSH: { 3208aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach bool listContainsBase; 3209aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase)) 3210aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach return Error(Operands[2]->getStartLoc(), 3211aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach "registers must be in range r0-r7 or lr"); 32126dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach break; 32136dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach } 32141e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach case ARM::tSTMIA_UPD: { 32151e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach bool listContainsBase; 3216f95aaf951b628621c9c74bed6c450b8a52a1ae1eJim Grosbach if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase)) 32171e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach return Error(Operands[4]->getStartLoc(), 32181e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach "registers must be in range r0-r7"); 32191e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach break; 32201e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach } 3221189610f9466686a91fb7d847b572e1645c785323Jim Grosbach } 3222189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3223189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return false; 3224189610f9466686a91fb7d847b572e1645c785323Jim Grosbach} 3225189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3226f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser:: 3227f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst, 3228f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach const SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 3229f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach switch (Inst.getOpcode()) { 3230f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach case ARM::LDMIA_UPD: 3231f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // If this is a load of a single register via a 'pop', then we should use 3232f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // a post-indexed LDR instruction instead, per the ARM ARM. 3233f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" && 3234f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst.getNumOperands() == 5) { 3235f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach MCInst TmpInst; 3236f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.setOpcode(ARM::LDR_POST_IMM); 3237f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 3238f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 3239f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // Rn 3240f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateReg(0)); // am2offset 3241f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(MCOperand::CreateImm(4)); 3242f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 3243f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 3244f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach Inst = TmpInst; 3245f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 3246f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach break; 3247f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach case ARM::STMDB_UPD: 3248f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // If this is a store of a single register via a 'push', then we should use 3249f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach // a pre-indexed STR instruction instead, per the ARM ARM. 3250f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" && 3251f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst.getNumOperands() == 5) { 3252f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach MCInst TmpInst; 3253f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.setOpcode(ARM::STR_PRE_IMM); 3254f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb 3255f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(4)); // Rt 3256f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12 3257f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(MCOperand::CreateImm(-4)); 3258f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(2)); // CondCode 3259f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach TmpInst.addOperand(Inst.getOperand(3)); 3260f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach Inst = TmpInst; 3261f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach } 3262f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach break; 326389e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach case ARM::tADDi8: 326489e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach // If the immediate is in the range 0-7, we really wanted tADDi3. 326589e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach if (Inst.getOperand(3).getImm() < 8) 326689e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach Inst.setOpcode(ARM::tADDi3); 326789e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach break; 3268395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach case ARM::tBcc: 3269395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach // If the conditional is AL, we really want tB. 3270395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach if (Inst.getOperand(1).getImm() == ARMCC::AL) 3271395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach Inst.setOpcode(ARM::tB); 32723ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach break; 3273f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach } 3274f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach} 3275f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 327647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around 327747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward 327847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach// API changes, though. Better way? 327947a0d52b69056250a1edaca8b28f705993094542Jim Grosbachnamespace llvm { 328047a0d52b69056250a1edaca8b28f705993094542Jim Grosbachextern MCInstrDesc ARMInsts[]; 328147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 328247a0d52b69056250a1edaca8b28f705993094542Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) { 328347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return ARMInsts[Opcode]; 328447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 328547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 328647a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 328747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // 16-bit thumb arithmetic instructions either require or preclude the 'S' 328847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // suffix depending on whether they're in an IT block or not. 3289194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach unsigned Opc = Inst.getOpcode(); 3290194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach MCInstrDesc &MCID = getInstDesc(Opc); 329147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) { 329247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.hasOptionalDef() && 329347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "optionally flag setting instruction missing optional def operand"); 329447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach assert(MCID.NumOperands == Inst.getNumOperands() && 329547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach "operand count mismatch!"); 329647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // Find the optional-def operand (cc_out). 329747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach unsigned OpNo; 329847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach for (OpNo = 0; 329947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands; 330047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ++OpNo) 330147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach ; 330247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb1, reject it completely. 330347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 330447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_MnemonicFail; 330547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // If we're parsing Thumb2, which form is legal depends on whether we're 330647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // in an IT block. 330747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // FIXME: We don't yet do IT blocks, so just always consider it to be 330847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach // that we aren't in one until we do. 330947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR) 331047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_RequiresITBlock; 331147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach } 3312194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Some high-register supporting Thumb1 encodings only allow both registers 3313194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // to be from r0-r7 when in Thumb2. 3314194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach else if (Opc == ARM::tADDhirr && isThumbOne() && 3315194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg()) && 3316194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(2).getReg())) 3317194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresThumb2; 3318194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach // Others only require ARMv6 or later. 33194ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() && 3320194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(0).getReg()) && 3321194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach isARMLowRegister(Inst.getOperand(1).getReg())) 3322194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Match_RequiresV6; 332347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Match_Success; 332447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach} 332547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach 3326fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser:: 3327fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc, 3328fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner SmallVectorImpl<MCParsedAsmOperand*> &Operands, 3329fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCStreamer &Out) { 3330fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner MCInst Inst; 3331fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner unsigned ErrorInfo; 333219cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach unsigned MatchResult; 3333193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); 3334193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby switch (MatchResult) { 333519cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach default: break; 3336e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_Success: 3337189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // Context sensitive operand constraints aren't handled by the matcher, 3338189610f9466686a91fb7d847b572e1645c785323Jim Grosbach // so check them here. 3339189610f9466686a91fb7d847b572e1645c785323Jim Grosbach if (validateInstruction(Inst, Operands)) 3340189610f9466686a91fb7d847b572e1645c785323Jim Grosbach return true; 3341189610f9466686a91fb7d847b572e1645c785323Jim Grosbach 3342f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // Some instructions need post-processing to, for example, tweak which 3343f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach // encoding is selected. 3344f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach processInstruction(Inst, Operands); 3345f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach 3346fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner Out.EmitInstruction(Inst); 3347fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner return false; 3348e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MissingFeature: 3349e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 3350e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return true; 3351e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_InvalidOperand: { 3352e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner SMLoc ErrorLoc = IDLoc; 3353e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo != ~0U) { 3354e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorInfo >= Operands.size()) 3355e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(IDLoc, "too few operands for instruction"); 335616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3357e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc(); 3358e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 3359e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 336016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3361e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner return Error(ErrorLoc, "invalid operand for instruction"); 3362e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner } 3363e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner case Match_MnemonicFail: 336447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "invalid instruction"); 3365b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar case Match_ConversionFail: 336688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach // The converter function will have already emited a diagnostic. 336788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach return true; 336847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach case Match_RequiresITBlock: 336947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach return Error(IDLoc, "instruction only valid inside IT block"); 3370194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresV6: 3371194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires ARMv6 or later"); 3372194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach case Match_RequiresThumb2: 3373194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach return Error(IDLoc, "instruction variant requires Thumb2"); 3374fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner } 337516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3376c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher llvm_unreachable("Implement any new match types added!"); 3377146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling return true; 3378fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner} 3379fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner 33801355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives 3381ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) { 3382ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby StringRef IDVal = DirectiveID.getIdentifier(); 3383ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (IDVal == ".word") 33841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveWord(4, DirectiveID.getLoc()); 3385515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb") 33861355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumb(DirectiveID.getLoc()); 3387515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".thumb_func") 33881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveThumbFunc(DirectiveID.getLoc()); 3389515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".code") 33901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveCode(DirectiveID.getLoc()); 3391515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else if (IDVal == ".syntax") 33921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach return parseDirectiveSyntax(DirectiveID.getLoc()); 3393ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 3394ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3395ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 33961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord 3397ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ::= .word [ expression (, expression)* ] 33981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 3399ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) { 3400ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby for (;;) { 3401ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby const MCExpr *Value; 3402ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getParser().ParseExpression(Value)) 3403ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return true; 3404ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3405aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); 3406ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3407ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().is(AsmToken::EndOfStatement)) 3408ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby break; 340916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach 3410ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby // FIXME: Improve diagnostic. 3411ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby if (getLexer().isNot(AsmToken::Comma)) 3412ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return Error(L, "unexpected token in directive"); 3413b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3414ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 3415ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby } 3416ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 3417b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3418ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby return false; 3419ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 3420ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby 34211355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb 3422515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumb 34231355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) { 3424515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 3425515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 3426b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3427515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3428515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: set thumb mode 3429515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO: tell the MC streamer the mode 3430515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 3431515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3432515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3433515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 34341355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc 3435515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .thumbfunc symbol_name 34361355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { 34376469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); 34386469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola bool isMachO = MAI.hasSubsectionsViaSymbols(); 34396469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola StringRef Name; 34406469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 34416469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // Darwin asm has function name after .thumb_func direction 34426469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // ELF doesn't 34436469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (isMachO) { 34446469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola const AsmToken &Tok = Parser.getTok(); 34456469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) 34466469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Error(L, "unexpected token in .thumb_func directive"); 34476469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Tok.getString(); 34486469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Parser.Lex(); // Consume the identifier token. 34496469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 34506469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 3451515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 3452515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in directive"); 3453b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3454515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 34556469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola // FIXME: assuming function name will be the line following .thumb_func 34566469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (!isMachO) { 34576469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola Name = Parser.getTok().getString(); 34586469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 34596469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 3460642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach // Mark symbol as a thumb symbol. 3461642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); 3462642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach getParser().getStreamer().EmitThumbFunc(Func); 3463515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3464515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3465515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 34661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax 3467515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .syntax unified | divided 34681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) { 346918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3470515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Identifier)) 3471515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .syntax directive"); 347238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer StringRef Mode = Tok.getString(); 347358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Mode == "unified" || Mode == "UNIFIED") 3474b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 347558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Mode == "divided" || Mode == "DIVIDED") 34769e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby return Error(L, "'.syntax divided' arm asssembly not supported"); 3477515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 3478515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unrecognized syntax mode in .syntax directive"); 3479515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3480515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 348118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 3482b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3483515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3484515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // TODO tell the MC streamer the mode 3485515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby // getParser().getStreamer().Emit???(); 3486515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3487515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3488515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 34891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode 3490515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ::= .code 16 | 32 34911355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) { 349218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan const AsmToken &Tok = Parser.getTok(); 3493515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (Tok.isNot(AsmToken::Integer)) 3494515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "unexpected token in .code directive"); 349518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan int64_t Val = Parser.getTok().getIntVal(); 349658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands if (Val == 16) 3497b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 349858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands else if (Val == 32) 3499b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3500515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby else 3501515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return Error(L, "invalid operand to .code directive"); 3502515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 3503515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby if (getLexer().isNot(AsmToken::EndOfStatement)) 350418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan return Error(Parser.getTok().getLoc(), "unexpected token in directive"); 3505b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan Parser.Lex(); 3506515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 350732869205052430f45d598fba25ab878d8b29da2dEvan Cheng if (Val == 16) { 3508bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (!isThumb()) { 3509ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 3510bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); 3511bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 351232869205052430f45d598fba25ab878d8b29da2dEvan Cheng } else { 3513bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng if (isThumb()) { 3514ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SwitchMode(); 3515bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); 3516bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng } 3517eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng } 35182a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach 3519515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby return false; 3520515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby} 3521515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby 352290b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer(); 352390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan 35249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization. 3525ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() { 352694b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget); 352794b9550a32d189704a8eae55505edf62662c0534Evan Cheng RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget); 352890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan LLVMInitializeARMAsmLexer(); 3529ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby} 35303483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar 35310692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER 35320692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION 35333483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc" 3534