MipsAsmParser.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
1//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "MCTargetDesc/MipsMCExpr.h" 11#include "MCTargetDesc/MipsMCTargetDesc.h" 12#include "MipsRegisterInfo.h" 13#include "MipsTargetStreamer.h" 14#include "llvm/ADT/APInt.h" 15#include "llvm/ADT/StringSwitch.h" 16#include "llvm/MC/MCContext.h" 17#include "llvm/MC/MCExpr.h" 18#include "llvm/MC/MCInst.h" 19#include "llvm/MC/MCInstBuilder.h" 20#include "llvm/MC/MCParser/MCAsmLexer.h" 21#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 22#include "llvm/MC/MCStreamer.h" 23#include "llvm/MC/MCSubtargetInfo.h" 24#include "llvm/MC/MCSymbol.h" 25#include "llvm/MC/MCTargetAsmParser.h" 26#include "llvm/Support/Debug.h" 27#include "llvm/Support/MathExtras.h" 28#include "llvm/Support/TargetRegistry.h" 29 30using namespace llvm; 31 32namespace llvm { 33class MCInstrInfo; 34} 35 36namespace { 37class MipsAssemblerOptions { 38public: 39 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {} 40 41 unsigned getATRegNum() { return aTReg; } 42 bool setATReg(unsigned Reg); 43 44 bool isReorder() { return reorder; } 45 void setReorder() { reorder = true; } 46 void setNoreorder() { reorder = false; } 47 48 bool isMacro() { return macro; } 49 void setMacro() { macro = true; } 50 void setNomacro() { macro = false; } 51 52private: 53 unsigned aTReg; 54 bool reorder; 55 bool macro; 56}; 57} 58 59namespace { 60class MipsAsmParser : public MCTargetAsmParser { 61 MipsTargetStreamer &getTargetStreamer() { 62 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer(); 63 return static_cast<MipsTargetStreamer &>(TS); 64 } 65 66 MCSubtargetInfo &STI; 67 MCAsmParser &Parser; 68 MipsAssemblerOptions Options; 69 70#define GET_ASSEMBLER_HEADER 71#include "MipsGenAsmMatcher.inc" 72 73 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 74 SmallVectorImpl<MCParsedAsmOperand *> &Operands, 75 MCStreamer &Out, unsigned &ErrorInfo, 76 bool MatchingInlineAsm); 77 78 /// Parse a register as used in CFI directives 79 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 80 81 bool ParseParenSuffix(StringRef Name, 82 SmallVectorImpl<MCParsedAsmOperand *> &Operands); 83 84 bool ParseBracketSuffix(StringRef Name, 85 SmallVectorImpl<MCParsedAsmOperand *> &Operands); 86 87 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 88 SMLoc NameLoc, 89 SmallVectorImpl<MCParsedAsmOperand *> &Operands); 90 91 bool ParseDirective(AsmToken DirectiveID); 92 93 MipsAsmParser::OperandMatchResultTy 94 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 95 96 MipsAsmParser::OperandMatchResultTy MatchAnyRegisterNameWithoutDollar( 97 SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier, 98 SMLoc S); 99 100 MipsAsmParser::OperandMatchResultTy 101 MatchAnyRegisterWithoutDollar(SmallVectorImpl<MCParsedAsmOperand *> &Operands, 102 SMLoc S); 103 104 MipsAsmParser::OperandMatchResultTy 105 ParseAnyRegister(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 106 107 MipsAsmParser::OperandMatchResultTy 108 ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 109 110 MipsAsmParser::OperandMatchResultTy 111 ParseJumpTarget(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 112 113 MipsAsmParser::OperandMatchResultTy 114 parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 115 116 MipsAsmParser::OperandMatchResultTy 117 ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 118 119 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 120 121 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &, 122 StringRef Mnemonic); 123 124 bool needsExpansion(MCInst &Inst); 125 126 void expandInstruction(MCInst &Inst, SMLoc IDLoc, 127 SmallVectorImpl<MCInst> &Instructions); 128 void expandLoadImm(MCInst &Inst, SMLoc IDLoc, 129 SmallVectorImpl<MCInst> &Instructions); 130 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 131 SmallVectorImpl<MCInst> &Instructions); 132 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 133 SmallVectorImpl<MCInst> &Instructions); 134 void expandMemInst(MCInst &Inst, SMLoc IDLoc, 135 SmallVectorImpl<MCInst> &Instructions, bool isLoad, 136 bool isImmOpnd); 137 bool reportParseError(StringRef ErrorMsg); 138 139 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); 140 bool parseRelocOperand(const MCExpr *&Res); 141 142 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); 143 144 bool isEvaluated(const MCExpr *Expr); 145 bool parseSetFeature(uint64_t Feature); 146 bool parseDirectiveCPSetup(); 147 bool parseDirectiveSet(); 148 bool parseDirectiveOption(); 149 150 bool parseSetAtDirective(); 151 bool parseSetNoAtDirective(); 152 bool parseSetMacroDirective(); 153 bool parseSetNoMacroDirective(); 154 bool parseSetReorderDirective(); 155 bool parseSetNoReorderDirective(); 156 bool parseSetNoMips16Directive(); 157 158 bool parseSetAssignment(); 159 160 bool parseDataDirective(unsigned Size, SMLoc L); 161 bool parseDirectiveGpWord(); 162 bool parseDirectiveGpDWord(); 163 164 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 165 166 bool isGP64() const { 167 return (STI.getFeatureBits() & Mips::FeatureGP64Bit) != 0; 168 } 169 170 bool isFP64() const { 171 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; 172 } 173 174 bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; } 175 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; } 176 177 bool isMicroMips() const { 178 return STI.getFeatureBits() & Mips::FeatureMicroMips; 179 } 180 181 bool parseRegister(unsigned &RegNum); 182 183 bool eatComma(StringRef ErrorStr); 184 185 int matchCPURegisterName(StringRef Symbol); 186 187 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 188 189 int matchFPURegisterName(StringRef Name); 190 191 int matchFCCRegisterName(StringRef Name); 192 193 int matchACRegisterName(StringRef Name); 194 195 int matchMSA128RegisterName(StringRef Name); 196 197 int matchMSA128CtrlRegisterName(StringRef Name); 198 199 unsigned getReg(int RC, int RegNo); 200 201 unsigned getGPR(int RegNo); 202 203 int getATReg(); 204 205 bool processInstruction(MCInst &Inst, SMLoc IDLoc, 206 SmallVectorImpl<MCInst> &Instructions); 207 208 // Helper function that checks if the value of a vector index is within the 209 // boundaries of accepted values for each RegisterKind 210 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0 211 bool validateMSAIndex(int Val, int RegKind); 212 213 void setFeatureBits(unsigned Feature, StringRef FeatureString) { 214 if (!(STI.getFeatureBits() & Feature)) { 215 setAvailableFeatures(ComputeAvailableFeatures( 216 STI.ToggleFeature(FeatureString))); 217 } 218 } 219 220 void clearFeatureBits(unsigned Feature, StringRef FeatureString) { 221 if (STI.getFeatureBits() & Feature) { 222 setAvailableFeatures(ComputeAvailableFeatures( 223 STI.ToggleFeature(FeatureString))); 224 } 225 } 226 227public: 228 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, 229 const MCInstrInfo &MII) 230 : MCTargetAsmParser(), STI(sti), Parser(parser) { 231 // Initialize the set of available features. 232 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 233 234 // Assert exactly one ABI was chosen. 235 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) + 236 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) + 237 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) + 238 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1); 239 } 240 241 MCAsmParser &getParser() const { return Parser; } 242 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 243 244 /// Warn if RegNo is the current assembler temporary. 245 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc); 246}; 247} 248 249namespace { 250 251/// MipsOperand - Instances of this class represent a parsed Mips machine 252/// instruction. 253class MipsOperand : public MCParsedAsmOperand { 254public: 255 /// Broad categories of register classes 256 /// The exact class is finalized by the render method. 257 enum RegKind { 258 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64()) 259 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and 260 /// isFP64()) 261 RegKind_FCC = 4, /// FCC 262 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which) 263 RegKind_MSACtrl = 16, /// MSA control registers 264 RegKind_COP2 = 32, /// COP2 265 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on 266 /// context). 267 RegKind_CCR = 128, /// CCR 268 RegKind_HWRegs = 256, /// HWRegs 269 270 /// Potentially any (e.g. $1) 271 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 | 272 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC | 273 RegKind_CCR | RegKind_HWRegs 274 }; 275 276private: 277 enum KindTy { 278 k_Immediate, /// An immediate (possibly involving symbol references) 279 k_Memory, /// Base + Offset Memory Address 280 k_PhysRegister, /// A physical register from the Mips namespace 281 k_RegisterIndex, /// A register index in one or more RegKind. 282 k_Token /// A simple token 283 } Kind; 284 285 MipsOperand(KindTy K, MipsAsmParser &Parser) 286 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {} 287 288 /// For diagnostics, and checking the assembler temporary 289 MipsAsmParser &AsmParser; 290 291 struct Token { 292 const char *Data; 293 unsigned Length; 294 }; 295 296 struct PhysRegOp { 297 unsigned Num; /// Register Number 298 }; 299 300 struct RegIdxOp { 301 unsigned Index; /// Index into the register class 302 RegKind Kind; /// Bitfield of the kinds it could possibly be 303 const MCRegisterInfo *RegInfo; 304 }; 305 306 struct ImmOp { 307 const MCExpr *Val; 308 }; 309 310 struct MemOp { 311 MipsOperand *Base; 312 const MCExpr *Off; 313 }; 314 315 union { 316 struct Token Tok; 317 struct PhysRegOp PhysReg; 318 struct RegIdxOp RegIdx; 319 struct ImmOp Imm; 320 struct MemOp Mem; 321 }; 322 323 SMLoc StartLoc, EndLoc; 324 325 /// Internal constructor for register kinds 326 static MipsOperand *CreateReg(unsigned Index, RegKind RegKind, 327 const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 328 MipsAsmParser &Parser) { 329 MipsOperand *Op = new MipsOperand(k_RegisterIndex, Parser); 330 Op->RegIdx.Index = Index; 331 Op->RegIdx.RegInfo = RegInfo; 332 Op->RegIdx.Kind = RegKind; 333 Op->StartLoc = S; 334 Op->EndLoc = E; 335 return Op; 336 } 337 338public: 339 /// Coerce the register to GPR32 and return the real register for the current 340 /// target. 341 unsigned getGPR32Reg() const { 342 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 343 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc); 344 unsigned ClassID = Mips::GPR32RegClassID; 345 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 346 } 347 348 /// Coerce the register to GPR64 and return the real register for the current 349 /// target. 350 unsigned getGPR64Reg() const { 351 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 352 unsigned ClassID = Mips::GPR64RegClassID; 353 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 354 } 355 356private: 357 /// Coerce the register to AFGR64 and return the real register for the current 358 /// target. 359 unsigned getAFGR64Reg() const { 360 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 361 if (RegIdx.Index % 2 != 0) 362 AsmParser.Warning(StartLoc, "Float register should be even."); 363 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID) 364 .getRegister(RegIdx.Index / 2); 365 } 366 367 /// Coerce the register to FGR64 and return the real register for the current 368 /// target. 369 unsigned getFGR64Reg() const { 370 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 371 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID) 372 .getRegister(RegIdx.Index); 373 } 374 375 /// Coerce the register to FGR32 and return the real register for the current 376 /// target. 377 unsigned getFGR32Reg() const { 378 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 379 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID) 380 .getRegister(RegIdx.Index); 381 } 382 383 /// Coerce the register to FGRH32 and return the real register for the current 384 /// target. 385 unsigned getFGRH32Reg() const { 386 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 387 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID) 388 .getRegister(RegIdx.Index); 389 } 390 391 /// Coerce the register to FCC and return the real register for the current 392 /// target. 393 unsigned getFCCReg() const { 394 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!"); 395 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID) 396 .getRegister(RegIdx.Index); 397 } 398 399 /// Coerce the register to MSA128 and return the real register for the current 400 /// target. 401 unsigned getMSA128Reg() const { 402 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!"); 403 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all 404 // identical 405 unsigned ClassID = Mips::MSA128BRegClassID; 406 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 407 } 408 409 /// Coerce the register to MSACtrl and return the real register for the 410 /// current target. 411 unsigned getMSACtrlReg() const { 412 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!"); 413 unsigned ClassID = Mips::MSACtrlRegClassID; 414 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 415 } 416 417 /// Coerce the register to COP2 and return the real register for the 418 /// current target. 419 unsigned getCOP2Reg() const { 420 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!"); 421 unsigned ClassID = Mips::COP2RegClassID; 422 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 423 } 424 425 /// Coerce the register to ACC64DSP and return the real register for the 426 /// current target. 427 unsigned getACC64DSPReg() const { 428 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 429 unsigned ClassID = Mips::ACC64DSPRegClassID; 430 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 431 } 432 433 /// Coerce the register to HI32DSP and return the real register for the 434 /// current target. 435 unsigned getHI32DSPReg() const { 436 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 437 unsigned ClassID = Mips::HI32DSPRegClassID; 438 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 439 } 440 441 /// Coerce the register to LO32DSP and return the real register for the 442 /// current target. 443 unsigned getLO32DSPReg() const { 444 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 445 unsigned ClassID = Mips::LO32DSPRegClassID; 446 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 447 } 448 449 /// Coerce the register to CCR and return the real register for the 450 /// current target. 451 unsigned getCCRReg() const { 452 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!"); 453 unsigned ClassID = Mips::CCRRegClassID; 454 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 455 } 456 457 /// Coerce the register to HWRegs and return the real register for the 458 /// current target. 459 unsigned getHWRegsReg() const { 460 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!"); 461 unsigned ClassID = Mips::HWRegsRegClassID; 462 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 463 } 464 465public: 466 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 467 // Add as immediate when possible. Null MCExpr = 0. 468 if (Expr == 0) 469 Inst.addOperand(MCOperand::CreateImm(0)); 470 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 471 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 472 else 473 Inst.addOperand(MCOperand::CreateExpr(Expr)); 474 } 475 476 void addRegOperands(MCInst &Inst, unsigned N) const { 477 llvm_unreachable("Use a custom parser instead"); 478 } 479 480 /// Render the operand to an MCInst as a GPR32 481 /// Asserts if the wrong number of operands are requested, or the operand 482 /// is not a k_RegisterIndex compatible with RegKind_GPR 483 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const { 484 assert(N == 1 && "Invalid number of operands!"); 485 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg())); 486 } 487 488 /// Render the operand to an MCInst as a GPR64 489 /// Asserts if the wrong number of operands are requested, or the operand 490 /// is not a k_RegisterIndex compatible with RegKind_GPR 491 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const { 492 assert(N == 1 && "Invalid number of operands!"); 493 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg())); 494 } 495 496 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 497 assert(N == 1 && "Invalid number of operands!"); 498 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg())); 499 } 500 501 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 502 assert(N == 1 && "Invalid number of operands!"); 503 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg())); 504 } 505 506 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const { 507 assert(N == 1 && "Invalid number of operands!"); 508 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg())); 509 } 510 511 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const { 512 assert(N == 1 && "Invalid number of operands!"); 513 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg())); 514 } 515 516 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const { 517 assert(N == 1 && "Invalid number of operands!"); 518 Inst.addOperand(MCOperand::CreateReg(getFCCReg())); 519 } 520 521 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const { 522 assert(N == 1 && "Invalid number of operands!"); 523 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg())); 524 } 525 526 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const { 527 assert(N == 1 && "Invalid number of operands!"); 528 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg())); 529 } 530 531 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const { 532 assert(N == 1 && "Invalid number of operands!"); 533 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg())); 534 } 535 536 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 537 assert(N == 1 && "Invalid number of operands!"); 538 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg())); 539 } 540 541 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 542 assert(N == 1 && "Invalid number of operands!"); 543 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg())); 544 } 545 546 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 547 assert(N == 1 && "Invalid number of operands!"); 548 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg())); 549 } 550 551 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const { 552 assert(N == 1 && "Invalid number of operands!"); 553 Inst.addOperand(MCOperand::CreateReg(getCCRReg())); 554 } 555 556 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const { 557 assert(N == 1 && "Invalid number of operands!"); 558 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg())); 559 } 560 561 void addImmOperands(MCInst &Inst, unsigned N) const { 562 assert(N == 1 && "Invalid number of operands!"); 563 const MCExpr *Expr = getImm(); 564 addExpr(Inst, Expr); 565 } 566 567 void addMemOperands(MCInst &Inst, unsigned N) const { 568 assert(N == 2 && "Invalid number of operands!"); 569 570 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg())); 571 572 const MCExpr *Expr = getMemOff(); 573 addExpr(Inst, Expr); 574 } 575 576 bool isReg() const { 577 // As a special case until we sort out the definition of div/divu, pretend 578 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 579 if (isGPRAsmReg() && RegIdx.Index == 0) 580 return true; 581 582 return Kind == k_PhysRegister; 583 } 584 bool isRegIdx() const { return Kind == k_RegisterIndex; } 585 bool isImm() const { return Kind == k_Immediate; } 586 bool isConstantImm() const { 587 return isImm() && dyn_cast<MCConstantExpr>(getImm()); 588 } 589 bool isToken() const { 590 // Note: It's not possible to pretend that other operand kinds are tokens. 591 // The matcher emitter checks tokens first. 592 return Kind == k_Token; 593 } 594 bool isMem() const { return Kind == k_Memory; } 595 bool isInvNum() const { return Kind == k_Immediate; } 596 bool isLSAImm() const { 597 if (!isConstantImm()) 598 return false; 599 int64_t Val = getConstantImm(); 600 return 1 <= Val && Val <= 4; 601 } 602 603 StringRef getToken() const { 604 assert(Kind == k_Token && "Invalid access!"); 605 return StringRef(Tok.Data, Tok.Length); 606 } 607 608 unsigned getReg() const { 609 // As a special case until we sort out the definition of div/divu, pretend 610 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 611 if (Kind == k_RegisterIndex && RegIdx.Index == 0 && 612 RegIdx.Kind & RegKind_GPR) 613 return getGPR32Reg(); // FIXME: GPR64 too 614 615 assert(Kind == k_PhysRegister && "Invalid access!"); 616 return PhysReg.Num; 617 } 618 619 const MCExpr *getImm() const { 620 assert((Kind == k_Immediate) && "Invalid access!"); 621 return Imm.Val; 622 } 623 624 int64_t getConstantImm() const { 625 const MCExpr *Val = getImm(); 626 return static_cast<const MCConstantExpr *>(Val)->getValue(); 627 } 628 629 MipsOperand *getMemBase() const { 630 assert((Kind == k_Memory) && "Invalid access!"); 631 return Mem.Base; 632 } 633 634 const MCExpr *getMemOff() const { 635 assert((Kind == k_Memory) && "Invalid access!"); 636 return Mem.Off; 637 } 638 639 static MipsOperand *CreateToken(StringRef Str, SMLoc S, 640 MipsAsmParser &Parser) { 641 MipsOperand *Op = new MipsOperand(k_Token, Parser); 642 Op->Tok.Data = Str.data(); 643 Op->Tok.Length = Str.size(); 644 Op->StartLoc = S; 645 Op->EndLoc = S; 646 return Op; 647 } 648 649 /// Create a numeric register (e.g. $1). The exact register remains 650 /// unresolved until an instruction successfully matches 651 static MipsOperand *CreateNumericReg(unsigned Index, 652 const MCRegisterInfo *RegInfo, SMLoc S, 653 SMLoc E, MipsAsmParser &Parser) { 654 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n"); 655 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser); 656 } 657 658 /// Create a register that is definitely a GPR. 659 /// This is typically only used for named registers such as $gp. 660 static MipsOperand *CreateGPRReg(unsigned Index, 661 const MCRegisterInfo *RegInfo, SMLoc S, 662 SMLoc E, MipsAsmParser &Parser) { 663 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser); 664 } 665 666 /// Create a register that is definitely a FGR. 667 /// This is typically only used for named registers such as $f0. 668 static MipsOperand *CreateFGRReg(unsigned Index, 669 const MCRegisterInfo *RegInfo, SMLoc S, 670 SMLoc E, MipsAsmParser &Parser) { 671 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser); 672 } 673 674 /// Create a register that is definitely an FCC. 675 /// This is typically only used for named registers such as $fcc0. 676 static MipsOperand *CreateFCCReg(unsigned Index, 677 const MCRegisterInfo *RegInfo, SMLoc S, 678 SMLoc E, MipsAsmParser &Parser) { 679 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser); 680 } 681 682 /// Create a register that is definitely an ACC. 683 /// This is typically only used for named registers such as $ac0. 684 static MipsOperand *CreateACCReg(unsigned Index, 685 const MCRegisterInfo *RegInfo, SMLoc S, 686 SMLoc E, MipsAsmParser &Parser) { 687 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser); 688 } 689 690 /// Create a register that is definitely an MSA128. 691 /// This is typically only used for named registers such as $w0. 692 static MipsOperand *CreateMSA128Reg(unsigned Index, 693 const MCRegisterInfo *RegInfo, SMLoc S, 694 SMLoc E, MipsAsmParser &Parser) { 695 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser); 696 } 697 698 /// Create a register that is definitely an MSACtrl. 699 /// This is typically only used for named registers such as $msaaccess. 700 static MipsOperand *CreateMSACtrlReg(unsigned Index, 701 const MCRegisterInfo *RegInfo, SMLoc S, 702 SMLoc E, MipsAsmParser &Parser) { 703 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser); 704 } 705 706 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, 707 MipsAsmParser &Parser) { 708 MipsOperand *Op = new MipsOperand(k_Immediate, Parser); 709 Op->Imm.Val = Val; 710 Op->StartLoc = S; 711 Op->EndLoc = E; 712 return Op; 713 } 714 715 static MipsOperand *CreateMem(MipsOperand *Base, const MCExpr *Off, SMLoc S, 716 SMLoc E, MipsAsmParser &Parser) { 717 MipsOperand *Op = new MipsOperand(k_Memory, Parser); 718 Op->Mem.Base = Base; 719 Op->Mem.Off = Off; 720 Op->StartLoc = S; 721 Op->EndLoc = E; 722 return Op; 723 } 724 725 bool isGPRAsmReg() const { 726 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31; 727 } 728 bool isFGRAsmReg() const { 729 // AFGR64 is $0-$15 but we handle this in getAFGR64() 730 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31; 731 } 732 bool isHWRegsAsmReg() const { 733 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31; 734 } 735 bool isCCRAsmReg() const { 736 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31; 737 } 738 bool isFCCAsmReg() const { 739 return isRegIdx() && RegIdx.Kind & RegKind_FCC && RegIdx.Index <= 7; 740 } 741 bool isACCAsmReg() const { 742 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3; 743 } 744 bool isCOP2AsmReg() const { 745 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31; 746 } 747 bool isMSA128AsmReg() const { 748 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31; 749 } 750 bool isMSACtrlAsmReg() const { 751 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7; 752 } 753 754 /// getStartLoc - Get the location of the first token of this operand. 755 SMLoc getStartLoc() const { return StartLoc; } 756 /// getEndLoc - Get the location of the last token of this operand. 757 SMLoc getEndLoc() const { return EndLoc; } 758 759 virtual void print(raw_ostream &OS) const { 760 switch (Kind) { 761 case k_Immediate: 762 OS << "Imm<"; 763 Imm.Val->print(OS); 764 OS << ">"; 765 break; 766 case k_Memory: 767 OS << "Mem<"; 768 Mem.Base->print(OS); 769 OS << ", "; 770 Mem.Off->print(OS); 771 OS << ">"; 772 break; 773 case k_PhysRegister: 774 OS << "PhysReg<" << PhysReg.Num << ">"; 775 break; 776 case k_RegisterIndex: 777 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">"; 778 break; 779 case k_Token: 780 OS << Tok.Data; 781 break; 782 } 783 } 784}; // class MipsOperand 785} // namespace 786 787namespace llvm { 788extern const MCInstrDesc MipsInsts[]; 789} 790static const MCInstrDesc &getInstDesc(unsigned Opcode) { 791 return MipsInsts[Opcode]; 792} 793 794bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 795 SmallVectorImpl<MCInst> &Instructions) { 796 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 797 798 Inst.setLoc(IDLoc); 799 800 if (MCID.isBranch() || MCID.isCall()) { 801 const unsigned Opcode = Inst.getOpcode(); 802 MCOperand Offset; 803 804 switch (Opcode) { 805 default: 806 break; 807 case Mips::BEQ: 808 case Mips::BNE: 809 case Mips::BEQ_MM: 810 case Mips::BNE_MM: 811 assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); 812 Offset = Inst.getOperand(2); 813 if (!Offset.isImm()) 814 break; // We'll deal with this situation later on when applying fixups. 815 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm())) 816 return Error(IDLoc, "branch target out of range"); 817 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2))) 818 return Error(IDLoc, "branch to misaligned address"); 819 break; 820 case Mips::BGEZ: 821 case Mips::BGTZ: 822 case Mips::BLEZ: 823 case Mips::BLTZ: 824 case Mips::BGEZAL: 825 case Mips::BLTZAL: 826 case Mips::BC1F: 827 case Mips::BC1T: 828 case Mips::BGEZ_MM: 829 case Mips::BGTZ_MM: 830 case Mips::BLEZ_MM: 831 case Mips::BLTZ_MM: 832 case Mips::BGEZAL_MM: 833 case Mips::BLTZAL_MM: 834 case Mips::BC1F_MM: 835 case Mips::BC1T_MM: 836 assert(MCID.getNumOperands() == 2 && "unexpected number of operands"); 837 Offset = Inst.getOperand(1); 838 if (!Offset.isImm()) 839 break; // We'll deal with this situation later on when applying fixups. 840 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm())) 841 return Error(IDLoc, "branch target out of range"); 842 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2))) 843 return Error(IDLoc, "branch to misaligned address"); 844 break; 845 } 846 } 847 848 if (MCID.hasDelaySlot() && Options.isReorder()) { 849 // If this instruction has a delay slot and .set reorder is active, 850 // emit a NOP after it. 851 Instructions.push_back(Inst); 852 MCInst NopInst; 853 NopInst.setOpcode(Mips::SLL); 854 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 855 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 856 NopInst.addOperand(MCOperand::CreateImm(0)); 857 Instructions.push_back(NopInst); 858 return false; 859 } 860 861 if (MCID.mayLoad() || MCID.mayStore()) { 862 // Check the offset of memory operand, if it is a symbol 863 // reference or immediate we may have to expand instructions. 864 for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 865 const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 866 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) || 867 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 868 MCOperand &Op = Inst.getOperand(i); 869 if (Op.isImm()) { 870 int MemOffset = Op.getImm(); 871 if (MemOffset < -32768 || MemOffset > 32767) { 872 // Offset can't exceed 16bit value. 873 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true); 874 return false; 875 } 876 } else if (Op.isExpr()) { 877 const MCExpr *Expr = Op.getExpr(); 878 if (Expr->getKind() == MCExpr::SymbolRef) { 879 const MCSymbolRefExpr *SR = 880 static_cast<const MCSymbolRefExpr *>(Expr); 881 if (SR->getKind() == MCSymbolRefExpr::VK_None) { 882 // Expand symbol. 883 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 884 return false; 885 } 886 } else if (!isEvaluated(Expr)) { 887 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 888 return false; 889 } 890 } 891 } 892 } // for 893 } // if load/store 894 895 if (needsExpansion(Inst)) 896 expandInstruction(Inst, IDLoc, Instructions); 897 else 898 Instructions.push_back(Inst); 899 900 return false; 901} 902 903bool MipsAsmParser::needsExpansion(MCInst &Inst) { 904 905 switch (Inst.getOpcode()) { 906 case Mips::LoadImm32Reg: 907 case Mips::LoadAddr32Imm: 908 case Mips::LoadAddr32Reg: 909 case Mips::SUBi: 910 case Mips::SUBiu: 911 case Mips::DSUBi: 912 case Mips::DSUBiu: 913 return true; 914 default: 915 return false; 916 } 917} 918 919void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 920 SmallVectorImpl<MCInst> &Instructions) { 921 switch (Inst.getOpcode()) { 922 case Mips::LoadImm32Reg: 923 return expandLoadImm(Inst, IDLoc, Instructions); 924 case Mips::LoadAddr32Imm: 925 return expandLoadAddressImm(Inst, IDLoc, Instructions); 926 case Mips::LoadAddr32Reg: 927 return expandLoadAddressReg(Inst, IDLoc, Instructions); 928 case Mips::SUBi: 929 Instructions.push_back(MCInstBuilder(Mips::ADDi) 930 .addReg(Inst.getOperand(0).getReg()) 931 .addReg(Inst.getOperand(1).getReg()) 932 .addImm(-Inst.getOperand(2).getImm())); 933 return; 934 case Mips::SUBiu: 935 Instructions.push_back(MCInstBuilder(Mips::ADDiu) 936 .addReg(Inst.getOperand(0).getReg()) 937 .addReg(Inst.getOperand(1).getReg()) 938 .addImm(-Inst.getOperand(2).getImm())); 939 return; 940 case Mips::DSUBi: 941 Instructions.push_back(MCInstBuilder(Mips::DADDi) 942 .addReg(Inst.getOperand(0).getReg()) 943 .addReg(Inst.getOperand(1).getReg()) 944 .addImm(-Inst.getOperand(2).getImm())); 945 return; 946 case Mips::DSUBiu: 947 Instructions.push_back(MCInstBuilder(Mips::DADDiu) 948 .addReg(Inst.getOperand(0).getReg()) 949 .addReg(Inst.getOperand(1).getReg()) 950 .addImm(-Inst.getOperand(2).getImm())); 951 return; 952 } 953} 954 955void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 956 SmallVectorImpl<MCInst> &Instructions) { 957 MCInst tmpInst; 958 const MCOperand &ImmOp = Inst.getOperand(1); 959 assert(ImmOp.isImm() && "expected immediate operand kind"); 960 const MCOperand &RegOp = Inst.getOperand(0); 961 assert(RegOp.isReg() && "expected register operand kind"); 962 963 int ImmValue = ImmOp.getImm(); 964 tmpInst.setLoc(IDLoc); 965 if (0 <= ImmValue && ImmValue <= 65535) { 966 // For 0 <= j <= 65535. 967 // li d,j => ori d,$zero,j 968 tmpInst.setOpcode(Mips::ORi); 969 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 970 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 971 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 972 Instructions.push_back(tmpInst); 973 } else if (ImmValue < 0 && ImmValue >= -32768) { 974 // For -32768 <= j < 0. 975 // li d,j => addiu d,$zero,j 976 tmpInst.setOpcode(Mips::ADDiu); 977 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 978 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 979 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 980 Instructions.push_back(tmpInst); 981 } else { 982 // For any other value of j that is representable as a 32-bit integer. 983 // li d,j => lui d,hi16(j) 984 // ori d,d,lo16(j) 985 tmpInst.setOpcode(Mips::LUi); 986 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 987 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 988 Instructions.push_back(tmpInst); 989 tmpInst.clear(); 990 tmpInst.setOpcode(Mips::ORi); 991 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 992 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 993 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 994 tmpInst.setLoc(IDLoc); 995 Instructions.push_back(tmpInst); 996 } 997} 998 999void 1000MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 1001 SmallVectorImpl<MCInst> &Instructions) { 1002 MCInst tmpInst; 1003 const MCOperand &ImmOp = Inst.getOperand(2); 1004 assert(ImmOp.isImm() && "expected immediate operand kind"); 1005 const MCOperand &SrcRegOp = Inst.getOperand(1); 1006 assert(SrcRegOp.isReg() && "expected register operand kind"); 1007 const MCOperand &DstRegOp = Inst.getOperand(0); 1008 assert(DstRegOp.isReg() && "expected register operand kind"); 1009 int ImmValue = ImmOp.getImm(); 1010 if (-32768 <= ImmValue && ImmValue <= 65535) { 1011 // For -32768 <= j <= 65535. 1012 // la d,j(s) => addiu d,s,j 1013 tmpInst.setOpcode(Mips::ADDiu); 1014 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1015 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 1016 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1017 Instructions.push_back(tmpInst); 1018 } else { 1019 // For any other value of j that is representable as a 32-bit integer. 1020 // la d,j(s) => lui d,hi16(j) 1021 // ori d,d,lo16(j) 1022 // addu d,d,s 1023 tmpInst.setOpcode(Mips::LUi); 1024 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1025 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 1026 Instructions.push_back(tmpInst); 1027 tmpInst.clear(); 1028 tmpInst.setOpcode(Mips::ORi); 1029 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1030 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1031 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 1032 Instructions.push_back(tmpInst); 1033 tmpInst.clear(); 1034 tmpInst.setOpcode(Mips::ADDu); 1035 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1036 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1037 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 1038 Instructions.push_back(tmpInst); 1039 } 1040} 1041 1042void 1043MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 1044 SmallVectorImpl<MCInst> &Instructions) { 1045 MCInst tmpInst; 1046 const MCOperand &ImmOp = Inst.getOperand(1); 1047 assert(ImmOp.isImm() && "expected immediate operand kind"); 1048 const MCOperand &RegOp = Inst.getOperand(0); 1049 assert(RegOp.isReg() && "expected register operand kind"); 1050 int ImmValue = ImmOp.getImm(); 1051 if (-32768 <= ImmValue && ImmValue <= 65535) { 1052 // For -32768 <= j <= 65535. 1053 // la d,j => addiu d,$zero,j 1054 tmpInst.setOpcode(Mips::ADDiu); 1055 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1056 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1057 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1058 Instructions.push_back(tmpInst); 1059 } else { 1060 // For any other value of j that is representable as a 32-bit integer. 1061 // la d,j => lui d,hi16(j) 1062 // ori d,d,lo16(j) 1063 tmpInst.setOpcode(Mips::LUi); 1064 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1065 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 1066 Instructions.push_back(tmpInst); 1067 tmpInst.clear(); 1068 tmpInst.setOpcode(Mips::ORi); 1069 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1070 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1071 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 1072 Instructions.push_back(tmpInst); 1073 } 1074} 1075 1076void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, 1077 SmallVectorImpl<MCInst> &Instructions, 1078 bool isLoad, bool isImmOpnd) { 1079 const MCSymbolRefExpr *SR; 1080 MCInst TempInst; 1081 unsigned ImmOffset, HiOffset, LoOffset; 1082 const MCExpr *ExprOffset; 1083 unsigned TmpRegNum; 1084 unsigned AtRegNum = getReg( 1085 (isGP64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg()); 1086 // 1st operand is either the source or destination register. 1087 assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 1088 unsigned RegOpNum = Inst.getOperand(0).getReg(); 1089 // 2nd operand is the base register. 1090 assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 1091 unsigned BaseRegNum = Inst.getOperand(1).getReg(); 1092 // 3rd operand is either an immediate or expression. 1093 if (isImmOpnd) { 1094 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); 1095 ImmOffset = Inst.getOperand(2).getImm(); 1096 LoOffset = ImmOffset & 0x0000ffff; 1097 HiOffset = (ImmOffset & 0xffff0000) >> 16; 1098 // If msb of LoOffset is 1(negative number) we must increment HiOffset. 1099 if (LoOffset & 0x8000) 1100 HiOffset++; 1101 } else 1102 ExprOffset = Inst.getOperand(2).getExpr(); 1103 // All instructions will have the same location. 1104 TempInst.setLoc(IDLoc); 1105 // 1st instruction in expansion is LUi. For load instruction we can use 1106 // the dst register as a temporary if base and dst are different, 1107 // but for stores we must use $at. 1108 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum; 1109 TempInst.setOpcode(Mips::LUi); 1110 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1111 if (isImmOpnd) 1112 TempInst.addOperand(MCOperand::CreateImm(HiOffset)); 1113 else { 1114 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 1115 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset); 1116 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 1117 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI, 1118 getContext()); 1119 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 1120 } else { 1121 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi"); 1122 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 1123 } 1124 } 1125 // Add the instruction to the list. 1126 Instructions.push_back(TempInst); 1127 // Prepare TempInst for next instruction. 1128 TempInst.clear(); 1129 // Add temp register to base. 1130 TempInst.setOpcode(Mips::ADDu); 1131 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1132 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1133 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum)); 1134 Instructions.push_back(TempInst); 1135 TempInst.clear(); 1136 // And finally, create original instruction with low part 1137 // of offset and new base. 1138 TempInst.setOpcode(Inst.getOpcode()); 1139 TempInst.addOperand(MCOperand::CreateReg(RegOpNum)); 1140 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1141 if (isImmOpnd) 1142 TempInst.addOperand(MCOperand::CreateImm(LoOffset)); 1143 else { 1144 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 1145 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 1146 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO, 1147 getContext()); 1148 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 1149 } else { 1150 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo"); 1151 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 1152 } 1153 } 1154 Instructions.push_back(TempInst); 1155 TempInst.clear(); 1156} 1157 1158bool MipsAsmParser::MatchAndEmitInstruction( 1159 SMLoc IDLoc, unsigned &Opcode, 1160 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out, 1161 unsigned &ErrorInfo, bool MatchingInlineAsm) { 1162 MCInst Inst; 1163 SmallVector<MCInst, 8> Instructions; 1164 unsigned MatchResult = 1165 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 1166 1167 switch (MatchResult) { 1168 default: 1169 break; 1170 case Match_Success: { 1171 if (processInstruction(Inst, IDLoc, Instructions)) 1172 return true; 1173 for (unsigned i = 0; i < Instructions.size(); i++) 1174 Out.EmitInstruction(Instructions[i], STI); 1175 return false; 1176 } 1177 case Match_MissingFeature: 1178 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1179 return true; 1180 case Match_InvalidOperand: { 1181 SMLoc ErrorLoc = IDLoc; 1182 if (ErrorInfo != ~0U) { 1183 if (ErrorInfo >= Operands.size()) 1184 return Error(IDLoc, "too few operands for instruction"); 1185 1186 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc(); 1187 if (ErrorLoc == SMLoc()) 1188 ErrorLoc = IDLoc; 1189 } 1190 1191 return Error(ErrorLoc, "invalid operand for instruction"); 1192 } 1193 case Match_MnemonicFail: 1194 return Error(IDLoc, "invalid instruction"); 1195 } 1196 return true; 1197} 1198 1199void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) { 1200 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) { 1201 if (RegIndex == 1) 1202 Warning(Loc, "Used $at without \".set noat\""); 1203 else 1204 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" + 1205 Twine(RegIndex) + "\""); 1206 } 1207} 1208 1209int MipsAsmParser::matchCPURegisterName(StringRef Name) { 1210 int CC; 1211 1212 CC = StringSwitch<unsigned>(Name) 1213 .Case("zero", 0) 1214 .Case("at", 1) 1215 .Case("a0", 4) 1216 .Case("a1", 5) 1217 .Case("a2", 6) 1218 .Case("a3", 7) 1219 .Case("v0", 2) 1220 .Case("v1", 3) 1221 .Case("s0", 16) 1222 .Case("s1", 17) 1223 .Case("s2", 18) 1224 .Case("s3", 19) 1225 .Case("s4", 20) 1226 .Case("s5", 21) 1227 .Case("s6", 22) 1228 .Case("s7", 23) 1229 .Case("k0", 26) 1230 .Case("k1", 27) 1231 .Case("gp", 28) 1232 .Case("sp", 29) 1233 .Case("fp", 30) 1234 .Case("s8", 30) 1235 .Case("ra", 31) 1236 .Case("t0", 8) 1237 .Case("t1", 9) 1238 .Case("t2", 10) 1239 .Case("t3", 11) 1240 .Case("t4", 12) 1241 .Case("t5", 13) 1242 .Case("t6", 14) 1243 .Case("t7", 15) 1244 .Case("t8", 24) 1245 .Case("t9", 25) 1246 .Default(-1); 1247 1248 if (isN32() || isN64()) { 1249 // Although SGI documentation just cuts out t0-t3 for n32/n64, 1250 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 1251 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 1252 if (8 <= CC && CC <= 11) 1253 CC += 4; 1254 1255 if (CC == -1) 1256 CC = StringSwitch<unsigned>(Name) 1257 .Case("a4", 8) 1258 .Case("a5", 9) 1259 .Case("a6", 10) 1260 .Case("a7", 11) 1261 .Case("kt0", 26) 1262 .Case("kt1", 27) 1263 .Default(-1); 1264 } 1265 1266 return CC; 1267} 1268 1269int MipsAsmParser::matchFPURegisterName(StringRef Name) { 1270 1271 if (Name[0] == 'f') { 1272 StringRef NumString = Name.substr(1); 1273 unsigned IntVal; 1274 if (NumString.getAsInteger(10, IntVal)) 1275 return -1; // This is not an integer. 1276 if (IntVal > 31) // Maximum index for fpu register. 1277 return -1; 1278 return IntVal; 1279 } 1280 return -1; 1281} 1282 1283int MipsAsmParser::matchFCCRegisterName(StringRef Name) { 1284 1285 if (Name.startswith("fcc")) { 1286 StringRef NumString = Name.substr(3); 1287 unsigned IntVal; 1288 if (NumString.getAsInteger(10, IntVal)) 1289 return -1; // This is not an integer. 1290 if (IntVal > 7) // There are only 8 fcc registers. 1291 return -1; 1292 return IntVal; 1293 } 1294 return -1; 1295} 1296 1297int MipsAsmParser::matchACRegisterName(StringRef Name) { 1298 1299 if (Name.startswith("ac")) { 1300 StringRef NumString = Name.substr(2); 1301 unsigned IntVal; 1302 if (NumString.getAsInteger(10, IntVal)) 1303 return -1; // This is not an integer. 1304 if (IntVal > 3) // There are only 3 acc registers. 1305 return -1; 1306 return IntVal; 1307 } 1308 return -1; 1309} 1310 1311int MipsAsmParser::matchMSA128RegisterName(StringRef Name) { 1312 unsigned IntVal; 1313 1314 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal)) 1315 return -1; 1316 1317 if (IntVal > 31) 1318 return -1; 1319 1320 return IntVal; 1321} 1322 1323int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) { 1324 int CC; 1325 1326 CC = StringSwitch<unsigned>(Name) 1327 .Case("msair", 0) 1328 .Case("msacsr", 1) 1329 .Case("msaaccess", 2) 1330 .Case("msasave", 3) 1331 .Case("msamodify", 4) 1332 .Case("msarequest", 5) 1333 .Case("msamap", 6) 1334 .Case("msaunmap", 7) 1335 .Default(-1); 1336 1337 return CC; 1338} 1339 1340bool MipsAssemblerOptions::setATReg(unsigned Reg) { 1341 if (Reg > 31) 1342 return false; 1343 1344 aTReg = Reg; 1345 return true; 1346} 1347 1348int MipsAsmParser::getATReg() { 1349 int AT = Options.getATRegNum(); 1350 if (AT == 0) 1351 TokError("Pseudo instruction requires $at, which is not available"); 1352 return AT; 1353} 1354 1355unsigned MipsAsmParser::getReg(int RC, int RegNo) { 1356 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 1357} 1358 1359unsigned MipsAsmParser::getGPR(int RegNo) { 1360 return getReg(isGP64() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, 1361 RegNo); 1362} 1363 1364int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 1365 if (RegNum > 1366 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1) 1367 return -1; 1368 1369 return getReg(RegClass, RegNum); 1370} 1371 1372bool 1373MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands, 1374 StringRef Mnemonic) { 1375 DEBUG(dbgs() << "ParseOperand\n"); 1376 1377 // Check if the current operand has a custom associated parser, if so, try to 1378 // custom parse the operand, or fallback to the general approach. 1379 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1380 if (ResTy == MatchOperand_Success) 1381 return false; 1382 // If there wasn't a custom match, try the generic matcher below. Otherwise, 1383 // there was a match, but an error occurred, in which case, just return that 1384 // the operand parsing failed. 1385 if (ResTy == MatchOperand_ParseFail) 1386 return true; 1387 1388 DEBUG(dbgs() << ".. Generic Parser\n"); 1389 1390 switch (getLexer().getKind()) { 1391 default: 1392 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 1393 return true; 1394 case AsmToken::Dollar: { 1395 // Parse the register. 1396 SMLoc S = Parser.getTok().getLoc(); 1397 1398 // Almost all registers have been parsed by custom parsers. There is only 1399 // one exception to this. $zero (and it's alias $0) will reach this point 1400 // for div, divu, and similar instructions because it is not an operand 1401 // to the instruction definition but an explicit register. Special case 1402 // this situation for now. 1403 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch) 1404 return false; 1405 1406 // Maybe it is a symbol reference. 1407 StringRef Identifier; 1408 if (Parser.parseIdentifier(Identifier)) 1409 return true; 1410 1411 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1412 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 1413 // Otherwise create a symbol reference. 1414 const MCExpr *Res = 1415 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1416 1417 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this)); 1418 return false; 1419 } 1420 // Else drop to expression parsing. 1421 case AsmToken::LParen: 1422 case AsmToken::Minus: 1423 case AsmToken::Plus: 1424 case AsmToken::Integer: 1425 case AsmToken::String: { 1426 DEBUG(dbgs() << ".. generic integer\n"); 1427 OperandMatchResultTy ResTy = ParseImm(Operands); 1428 return ResTy != MatchOperand_Success; 1429 } 1430 case AsmToken::Percent: { 1431 // It is a symbol reference or constant expression. 1432 const MCExpr *IdVal; 1433 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 1434 if (parseRelocOperand(IdVal)) 1435 return true; 1436 1437 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1438 1439 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 1440 return false; 1441 } // case AsmToken::Percent 1442 } // switch(getLexer().getKind()) 1443 return true; 1444} 1445 1446const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, 1447 StringRef RelocStr) { 1448 const MCExpr *Res; 1449 // Check the type of the expression. 1450 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) { 1451 // It's a constant, evaluate reloc value. 1452 int16_t Val; 1453 switch (getVariantKind(RelocStr)) { 1454 case MCSymbolRefExpr::VK_Mips_ABS_LO: 1455 // Get the 1st 16-bits. 1456 Val = MCE->getValue() & 0xffff; 1457 break; 1458 case MCSymbolRefExpr::VK_Mips_ABS_HI: 1459 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low 1460 // 16 bits being negative. 1461 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff; 1462 break; 1463 case MCSymbolRefExpr::VK_Mips_HIGHER: 1464 // Get the 3rd 16-bits. 1465 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff; 1466 break; 1467 case MCSymbolRefExpr::VK_Mips_HIGHEST: 1468 // Get the 4th 16-bits. 1469 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff; 1470 break; 1471 default: 1472 report_fatal_error("Unsupported reloc value!"); 1473 } 1474 return MCConstantExpr::Create(Val, getContext()); 1475 } 1476 1477 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) { 1478 // It's a symbol, create a symbolic expression from the symbol. 1479 StringRef Symbol = MSRE->getSymbol().getName(); 1480 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 1481 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext()); 1482 return Res; 1483 } 1484 1485 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 1486 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 1487 1488 // Try to create target expression. 1489 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE)) 1490 return MipsMCExpr::Create(VK, Expr, getContext()); 1491 1492 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr); 1493 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); 1494 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext()); 1495 return Res; 1496 } 1497 1498 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) { 1499 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr); 1500 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext()); 1501 return Res; 1502 } 1503 // Just return the original expression. 1504 return Expr; 1505} 1506 1507bool MipsAsmParser::isEvaluated(const MCExpr *Expr) { 1508 1509 switch (Expr->getKind()) { 1510 case MCExpr::Constant: 1511 return true; 1512 case MCExpr::SymbolRef: 1513 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None); 1514 case MCExpr::Binary: 1515 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 1516 if (!isEvaluated(BE->getLHS())) 1517 return false; 1518 return isEvaluated(BE->getRHS()); 1519 } 1520 case MCExpr::Unary: 1521 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr()); 1522 case MCExpr::Target: 1523 return true; 1524 } 1525 return false; 1526} 1527 1528bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 1529 Parser.Lex(); // Eat the % token. 1530 const AsmToken &Tok = Parser.getTok(); // Get next token, operation. 1531 if (Tok.isNot(AsmToken::Identifier)) 1532 return true; 1533 1534 std::string Str = Tok.getIdentifier().str(); 1535 1536 Parser.Lex(); // Eat the identifier. 1537 // Now make an expression from the rest of the operand. 1538 const MCExpr *IdVal; 1539 SMLoc EndLoc; 1540 1541 if (getLexer().getKind() == AsmToken::LParen) { 1542 while (1) { 1543 Parser.Lex(); // Eat the '(' token. 1544 if (getLexer().getKind() == AsmToken::Percent) { 1545 Parser.Lex(); // Eat the % token. 1546 const AsmToken &nextTok = Parser.getTok(); 1547 if (nextTok.isNot(AsmToken::Identifier)) 1548 return true; 1549 Str += "(%"; 1550 Str += nextTok.getIdentifier(); 1551 Parser.Lex(); // Eat the identifier. 1552 if (getLexer().getKind() != AsmToken::LParen) 1553 return true; 1554 } else 1555 break; 1556 } 1557 if (getParser().parseParenExpression(IdVal, EndLoc)) 1558 return true; 1559 1560 while (getLexer().getKind() == AsmToken::RParen) 1561 Parser.Lex(); // Eat the ')' token. 1562 1563 } else 1564 return true; // Parenthesis must follow the relocation operand. 1565 1566 Res = evaluateRelocExpr(IdVal, Str); 1567 return false; 1568} 1569 1570bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1571 SMLoc &EndLoc) { 1572 SmallVector<MCParsedAsmOperand *, 1> Operands; 1573 OperandMatchResultTy ResTy = ParseAnyRegister(Operands); 1574 if (ResTy == MatchOperand_Success) { 1575 assert(Operands.size() == 1); 1576 MipsOperand &Operand = *static_cast<MipsOperand *>(Operands.front()); 1577 StartLoc = Operand.getStartLoc(); 1578 EndLoc = Operand.getEndLoc(); 1579 1580 // AFAIK, we only support numeric registers and named GPR's in CFI 1581 // directives. 1582 // Don't worry about eating tokens before failing. Using an unrecognised 1583 // register is a parse error. 1584 if (Operand.isGPRAsmReg()) { 1585 // Resolve to GPR32 or GPR64 appropriately. 1586 RegNo = isGP64() ? Operand.getGPR64Reg() : Operand.getGPR32Reg(); 1587 } 1588 1589 return (RegNo == (unsigned)-1); 1590 } 1591 1592 assert(Operands.size() == 0); 1593 return (RegNo == (unsigned)-1); 1594} 1595 1596bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 1597 SMLoc S; 1598 bool Result = true; 1599 1600 while (getLexer().getKind() == AsmToken::LParen) 1601 Parser.Lex(); 1602 1603 switch (getLexer().getKind()) { 1604 default: 1605 return true; 1606 case AsmToken::Identifier: 1607 case AsmToken::LParen: 1608 case AsmToken::Integer: 1609 case AsmToken::Minus: 1610 case AsmToken::Plus: 1611 if (isParenExpr) 1612 Result = getParser().parseParenExpression(Res, S); 1613 else 1614 Result = (getParser().parseExpression(Res)); 1615 while (getLexer().getKind() == AsmToken::RParen) 1616 Parser.Lex(); 1617 break; 1618 case AsmToken::Percent: 1619 Result = parseRelocOperand(Res); 1620 } 1621 return Result; 1622} 1623 1624MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( 1625 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1626 DEBUG(dbgs() << "parseMemOperand\n"); 1627 const MCExpr *IdVal = 0; 1628 SMLoc S; 1629 bool isParenExpr = false; 1630 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch; 1631 // First operand is the offset. 1632 S = Parser.getTok().getLoc(); 1633 1634 if (getLexer().getKind() == AsmToken::LParen) { 1635 Parser.Lex(); 1636 isParenExpr = true; 1637 } 1638 1639 if (getLexer().getKind() != AsmToken::Dollar) { 1640 if (parseMemOffset(IdVal, isParenExpr)) 1641 return MatchOperand_ParseFail; 1642 1643 const AsmToken &Tok = Parser.getTok(); // Get the next token. 1644 if (Tok.isNot(AsmToken::LParen)) { 1645 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]); 1646 if (Mnemonic->getToken() == "la") { 1647 SMLoc E = 1648 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1649 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 1650 return MatchOperand_Success; 1651 } 1652 if (Tok.is(AsmToken::EndOfStatement)) { 1653 SMLoc E = 1654 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1655 1656 // Zero register assumed, add a memory operand with ZERO as its base. 1657 MipsOperand *Base = MipsOperand::CreateGPRReg( 1658 0, getContext().getRegisterInfo(), S, E, *this); 1659 Operands.push_back(MipsOperand::CreateMem(Base, IdVal, S, E, *this)); 1660 return MatchOperand_Success; 1661 } 1662 Error(Parser.getTok().getLoc(), "'(' expected"); 1663 return MatchOperand_ParseFail; 1664 } 1665 1666 Parser.Lex(); // Eat the '(' token. 1667 } 1668 1669 Res = ParseAnyRegister(Operands); 1670 if (Res != MatchOperand_Success) 1671 return Res; 1672 1673 if (Parser.getTok().isNot(AsmToken::RParen)) { 1674 Error(Parser.getTok().getLoc(), "')' expected"); 1675 return MatchOperand_ParseFail; 1676 } 1677 1678 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1679 1680 Parser.Lex(); // Eat the ')' token. 1681 1682 if (IdVal == 0) 1683 IdVal = MCConstantExpr::Create(0, getContext()); 1684 1685 // Replace the register operand with the memory operand. 1686 MipsOperand *op = static_cast<MipsOperand *>(Operands.back()); 1687 // Remove the register from the operands. 1688 Operands.pop_back(); 1689 // Add the memory operand. 1690 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 1691 int64_t Imm; 1692 if (IdVal->EvaluateAsAbsolute(Imm)) 1693 IdVal = MCConstantExpr::Create(Imm, getContext()); 1694 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 1695 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 1696 getContext()); 1697 } 1698 1699 Operands.push_back(MipsOperand::CreateMem(op, IdVal, S, E, *this)); 1700 return MatchOperand_Success; 1701} 1702 1703bool MipsAsmParser::searchSymbolAlias( 1704 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1705 1706 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 1707 if (Sym) { 1708 SMLoc S = Parser.getTok().getLoc(); 1709 const MCExpr *Expr; 1710 if (Sym->isVariable()) 1711 Expr = Sym->getVariableValue(); 1712 else 1713 return false; 1714 if (Expr->getKind() == MCExpr::SymbolRef) { 1715 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr); 1716 const StringRef DefSymbol = Ref->getSymbol().getName(); 1717 if (DefSymbol.startswith("$")) { 1718 OperandMatchResultTy ResTy = 1719 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S); 1720 if (ResTy == MatchOperand_Success) { 1721 Parser.Lex(); 1722 return true; 1723 } else if (ResTy == MatchOperand_ParseFail) 1724 llvm_unreachable("Should never ParseFail"); 1725 return false; 1726 } 1727 } else if (Expr->getKind() == MCExpr::Constant) { 1728 Parser.Lex(); 1729 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr); 1730 MipsOperand *op = 1731 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this); 1732 Operands.push_back(op); 1733 return true; 1734 } 1735 } 1736 return false; 1737} 1738 1739MipsAsmParser::OperandMatchResultTy 1740MipsAsmParser::MatchAnyRegisterNameWithoutDollar( 1741 SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier, 1742 SMLoc S) { 1743 int Index = matchCPURegisterName(Identifier); 1744 if (Index != -1) { 1745 Operands.push_back(MipsOperand::CreateGPRReg( 1746 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1747 return MatchOperand_Success; 1748 } 1749 1750 Index = matchFPURegisterName(Identifier); 1751 if (Index != -1) { 1752 Operands.push_back(MipsOperand::CreateFGRReg( 1753 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1754 return MatchOperand_Success; 1755 } 1756 1757 Index = matchFCCRegisterName(Identifier); 1758 if (Index != -1) { 1759 Operands.push_back(MipsOperand::CreateFCCReg( 1760 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1761 return MatchOperand_Success; 1762 } 1763 1764 Index = matchACRegisterName(Identifier); 1765 if (Index != -1) { 1766 Operands.push_back(MipsOperand::CreateACCReg( 1767 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1768 return MatchOperand_Success; 1769 } 1770 1771 Index = matchMSA128RegisterName(Identifier); 1772 if (Index != -1) { 1773 Operands.push_back(MipsOperand::CreateMSA128Reg( 1774 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1775 return MatchOperand_Success; 1776 } 1777 1778 Index = matchMSA128CtrlRegisterName(Identifier); 1779 if (Index != -1) { 1780 Operands.push_back(MipsOperand::CreateMSACtrlReg( 1781 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 1782 return MatchOperand_Success; 1783 } 1784 1785 return MatchOperand_NoMatch; 1786} 1787 1788MipsAsmParser::OperandMatchResultTy 1789MipsAsmParser::MatchAnyRegisterWithoutDollar( 1790 SmallVectorImpl<MCParsedAsmOperand *> &Operands, SMLoc S) { 1791 auto Token = Parser.getLexer().peekTok(false); 1792 1793 if (Token.is(AsmToken::Identifier)) { 1794 DEBUG(dbgs() << ".. identifier\n"); 1795 StringRef Identifier = Token.getIdentifier(); 1796 OperandMatchResultTy ResTy = 1797 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S); 1798 return ResTy; 1799 } else if (Token.is(AsmToken::Integer)) { 1800 DEBUG(dbgs() << ".. integer\n"); 1801 Operands.push_back(MipsOperand::CreateNumericReg( 1802 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(), 1803 *this)); 1804 return MatchOperand_Success; 1805 } 1806 1807 DEBUG(dbgs() << Parser.getTok().getKind() << "\n"); 1808 1809 return MatchOperand_NoMatch; 1810} 1811 1812MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseAnyRegister( 1813 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1814 DEBUG(dbgs() << "ParseAnyRegister\n"); 1815 1816 auto Token = Parser.getTok(); 1817 1818 SMLoc S = Token.getLoc(); 1819 1820 if (Token.isNot(AsmToken::Dollar)) { 1821 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n"); 1822 if (Token.is(AsmToken::Identifier)) { 1823 if (searchSymbolAlias(Operands)) 1824 return MatchOperand_Success; 1825 } 1826 DEBUG(dbgs() << ".. !symalias -> NoMatch\n"); 1827 return MatchOperand_NoMatch; 1828 } 1829 DEBUG(dbgs() << ".. $\n"); 1830 1831 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S); 1832 if (ResTy == MatchOperand_Success) { 1833 Parser.Lex(); // $ 1834 Parser.Lex(); // identifier 1835 } 1836 return ResTy; 1837} 1838 1839MipsAsmParser::OperandMatchResultTy 1840MipsAsmParser::ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1841 switch (getLexer().getKind()) { 1842 default: 1843 return MatchOperand_NoMatch; 1844 case AsmToken::LParen: 1845 case AsmToken::Minus: 1846 case AsmToken::Plus: 1847 case AsmToken::Integer: 1848 case AsmToken::String: 1849 break; 1850 } 1851 1852 const MCExpr *IdVal; 1853 SMLoc S = Parser.getTok().getLoc(); 1854 if (getParser().parseExpression(IdVal)) 1855 return MatchOperand_ParseFail; 1856 1857 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1858 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 1859 return MatchOperand_Success; 1860} 1861 1862MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseJumpTarget( 1863 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1864 DEBUG(dbgs() << "ParseJumpTarget\n"); 1865 1866 SMLoc S = getLexer().getLoc(); 1867 1868 // Integers and expressions are acceptable 1869 OperandMatchResultTy ResTy = ParseImm(Operands); 1870 if (ResTy != MatchOperand_NoMatch) 1871 return ResTy; 1872 1873 // Registers are a valid target and have priority over symbols. 1874 ResTy = ParseAnyRegister(Operands); 1875 if (ResTy != MatchOperand_NoMatch) 1876 return ResTy; 1877 1878 const MCExpr *Expr = nullptr; 1879 if (Parser.parseExpression(Expr)) { 1880 // We have no way of knowing if a symbol was consumed so we must ParseFail 1881 return MatchOperand_ParseFail; 1882 } 1883 Operands.push_back( 1884 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this)); 1885 return MatchOperand_Success; 1886} 1887 1888MipsAsmParser::OperandMatchResultTy 1889MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1890 const MCExpr *IdVal; 1891 // If the first token is '$' we may have register operand. 1892 if (Parser.getTok().is(AsmToken::Dollar)) 1893 return MatchOperand_NoMatch; 1894 SMLoc S = Parser.getTok().getLoc(); 1895 if (getParser().parseExpression(IdVal)) 1896 return MatchOperand_ParseFail; 1897 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal); 1898 assert(MCE && "Unexpected MCExpr type."); 1899 int64_t Val = MCE->getValue(); 1900 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1901 Operands.push_back(MipsOperand::CreateImm( 1902 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this)); 1903 return MatchOperand_Success; 1904} 1905 1906MipsAsmParser::OperandMatchResultTy 1907MipsAsmParser::ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1908 switch (getLexer().getKind()) { 1909 default: 1910 return MatchOperand_NoMatch; 1911 case AsmToken::LParen: 1912 case AsmToken::Plus: 1913 case AsmToken::Minus: 1914 case AsmToken::Integer: 1915 break; 1916 } 1917 1918 const MCExpr *Expr; 1919 SMLoc S = Parser.getTok().getLoc(); 1920 1921 if (getParser().parseExpression(Expr)) 1922 return MatchOperand_ParseFail; 1923 1924 int64_t Val; 1925 if (!Expr->EvaluateAsAbsolute(Val)) { 1926 Error(S, "expected immediate value"); 1927 return MatchOperand_ParseFail; 1928 } 1929 1930 // The LSA instruction allows a 2-bit unsigned immediate. For this reason 1931 // and because the CPU always adds one to the immediate field, the allowed 1932 // range becomes 1..4. We'll only check the range here and will deal 1933 // with the addition/subtraction when actually decoding/encoding 1934 // the instruction. 1935 if (Val < 1 || Val > 4) { 1936 Error(S, "immediate not in range (1..4)"); 1937 return MatchOperand_ParseFail; 1938 } 1939 1940 Operands.push_back( 1941 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this)); 1942 return MatchOperand_Success; 1943} 1944 1945MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 1946 1947 MCSymbolRefExpr::VariantKind VK = 1948 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 1949 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 1950 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 1951 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 1952 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 1953 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 1954 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 1955 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 1956 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 1957 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 1958 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 1959 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 1960 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 1961 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 1962 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 1963 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 1964 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 1965 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 1966 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16) 1967 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16) 1968 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16) 1969 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16) 1970 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER) 1971 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST) 1972 .Default(MCSymbolRefExpr::VK_None); 1973 1974 assert (VK != MCSymbolRefExpr::VK_None); 1975 1976 return VK; 1977} 1978 1979/// Sometimes (i.e. load/stores) the operand may be followed immediately by 1980/// either this. 1981/// ::= '(', register, ')' 1982/// handle it before we iterate so we don't get tripped up by the lack of 1983/// a comma. 1984bool MipsAsmParser::ParseParenSuffix( 1985 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1986 if (getLexer().is(AsmToken::LParen)) { 1987 Operands.push_back( 1988 MipsOperand::CreateToken("(", getLexer().getLoc(), *this)); 1989 Parser.Lex(); 1990 if (ParseOperand(Operands, Name)) { 1991 SMLoc Loc = getLexer().getLoc(); 1992 Parser.eatToEndOfStatement(); 1993 return Error(Loc, "unexpected token in argument list"); 1994 } 1995 if (Parser.getTok().isNot(AsmToken::RParen)) { 1996 SMLoc Loc = getLexer().getLoc(); 1997 Parser.eatToEndOfStatement(); 1998 return Error(Loc, "unexpected token, expected ')'"); 1999 } 2000 Operands.push_back( 2001 MipsOperand::CreateToken(")", getLexer().getLoc(), *this)); 2002 Parser.Lex(); 2003 } 2004 return false; 2005} 2006 2007/// Sometimes (i.e. in MSA) the operand may be followed immediately by 2008/// either one of these. 2009/// ::= '[', register, ']' 2010/// ::= '[', integer, ']' 2011/// handle it before we iterate so we don't get tripped up by the lack of 2012/// a comma. 2013bool MipsAsmParser::ParseBracketSuffix( 2014 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 2015 if (getLexer().is(AsmToken::LBrac)) { 2016 Operands.push_back( 2017 MipsOperand::CreateToken("[", getLexer().getLoc(), *this)); 2018 Parser.Lex(); 2019 if (ParseOperand(Operands, Name)) { 2020 SMLoc Loc = getLexer().getLoc(); 2021 Parser.eatToEndOfStatement(); 2022 return Error(Loc, "unexpected token in argument list"); 2023 } 2024 if (Parser.getTok().isNot(AsmToken::RBrac)) { 2025 SMLoc Loc = getLexer().getLoc(); 2026 Parser.eatToEndOfStatement(); 2027 return Error(Loc, "unexpected token, expected ']'"); 2028 } 2029 Operands.push_back( 2030 MipsOperand::CreateToken("]", getLexer().getLoc(), *this)); 2031 Parser.Lex(); 2032 } 2033 return false; 2034} 2035 2036bool MipsAsmParser::ParseInstruction( 2037 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 2038 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 2039 DEBUG(dbgs() << "ParseInstruction\n"); 2040 // Check if we have valid mnemonic 2041 if (!mnemonicIsValid(Name, 0)) { 2042 Parser.eatToEndOfStatement(); 2043 return Error(NameLoc, "Unknown instruction"); 2044 } 2045 // First operand in MCInst is instruction mnemonic. 2046 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this)); 2047 2048 // Read the remaining operands. 2049 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2050 // Read the first operand. 2051 if (ParseOperand(Operands, Name)) { 2052 SMLoc Loc = getLexer().getLoc(); 2053 Parser.eatToEndOfStatement(); 2054 return Error(Loc, "unexpected token in argument list"); 2055 } 2056 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands)) 2057 return true; 2058 // AFAIK, parenthesis suffixes are never on the first operand 2059 2060 while (getLexer().is(AsmToken::Comma)) { 2061 Parser.Lex(); // Eat the comma. 2062 // Parse and remember the operand. 2063 if (ParseOperand(Operands, Name)) { 2064 SMLoc Loc = getLexer().getLoc(); 2065 Parser.eatToEndOfStatement(); 2066 return Error(Loc, "unexpected token in argument list"); 2067 } 2068 // Parse bracket and parenthesis suffixes before we iterate 2069 if (getLexer().is(AsmToken::LBrac)) { 2070 if (ParseBracketSuffix(Name, Operands)) 2071 return true; 2072 } else if (getLexer().is(AsmToken::LParen) && 2073 ParseParenSuffix(Name, Operands)) 2074 return true; 2075 } 2076 } 2077 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2078 SMLoc Loc = getLexer().getLoc(); 2079 Parser.eatToEndOfStatement(); 2080 return Error(Loc, "unexpected token in argument list"); 2081 } 2082 Parser.Lex(); // Consume the EndOfStatement. 2083 return false; 2084} 2085 2086bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 2087 SMLoc Loc = getLexer().getLoc(); 2088 Parser.eatToEndOfStatement(); 2089 return Error(Loc, ErrorMsg); 2090} 2091 2092bool MipsAsmParser::parseSetNoAtDirective() { 2093 // Line should look like: ".set noat". 2094 // set at reg to 0. 2095 Options.setATReg(0); 2096 // eat noat 2097 Parser.Lex(); 2098 // If this is not the end of the statement, report an error. 2099 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2100 reportParseError("unexpected token in statement"); 2101 return false; 2102 } 2103 Parser.Lex(); // Consume the EndOfStatement. 2104 return false; 2105} 2106 2107bool MipsAsmParser::parseSetAtDirective() { 2108 // Line can be .set at - defaults to $1 2109 // or .set at=$reg 2110 int AtRegNo; 2111 getParser().Lex(); 2112 if (getLexer().is(AsmToken::EndOfStatement)) { 2113 Options.setATReg(1); 2114 Parser.Lex(); // Consume the EndOfStatement. 2115 return false; 2116 } else if (getLexer().is(AsmToken::Equal)) { 2117 getParser().Lex(); // Eat the '='. 2118 if (getLexer().isNot(AsmToken::Dollar)) { 2119 reportParseError("unexpected token in statement"); 2120 return false; 2121 } 2122 Parser.Lex(); // Eat the '$'. 2123 const AsmToken &Reg = Parser.getTok(); 2124 if (Reg.is(AsmToken::Identifier)) { 2125 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 2126 } else if (Reg.is(AsmToken::Integer)) { 2127 AtRegNo = Reg.getIntVal(); 2128 } else { 2129 reportParseError("unexpected token in statement"); 2130 return false; 2131 } 2132 2133 if (AtRegNo < 0 || AtRegNo > 31) { 2134 reportParseError("unexpected token in statement"); 2135 return false; 2136 } 2137 2138 if (!Options.setATReg(AtRegNo)) { 2139 reportParseError("unexpected token in statement"); 2140 return false; 2141 } 2142 getParser().Lex(); // Eat the register. 2143 2144 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2145 reportParseError("unexpected token in statement"); 2146 return false; 2147 } 2148 Parser.Lex(); // Consume the EndOfStatement. 2149 return false; 2150 } else { 2151 reportParseError("unexpected token in statement"); 2152 return false; 2153 } 2154} 2155 2156bool MipsAsmParser::parseSetReorderDirective() { 2157 Parser.Lex(); 2158 // If this is not the end of the statement, report an error. 2159 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2160 reportParseError("unexpected token in statement"); 2161 return false; 2162 } 2163 Options.setReorder(); 2164 getTargetStreamer().emitDirectiveSetReorder(); 2165 Parser.Lex(); // Consume the EndOfStatement. 2166 return false; 2167} 2168 2169bool MipsAsmParser::parseSetNoReorderDirective() { 2170 Parser.Lex(); 2171 // If this is not the end of the statement, report an error. 2172 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2173 reportParseError("unexpected token in statement"); 2174 return false; 2175 } 2176 Options.setNoreorder(); 2177 getTargetStreamer().emitDirectiveSetNoReorder(); 2178 Parser.Lex(); // Consume the EndOfStatement. 2179 return false; 2180} 2181 2182bool MipsAsmParser::parseSetMacroDirective() { 2183 Parser.Lex(); 2184 // If this is not the end of the statement, report an error. 2185 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2186 reportParseError("unexpected token in statement"); 2187 return false; 2188 } 2189 Options.setMacro(); 2190 Parser.Lex(); // Consume the EndOfStatement. 2191 return false; 2192} 2193 2194bool MipsAsmParser::parseSetNoMacroDirective() { 2195 Parser.Lex(); 2196 // If this is not the end of the statement, report an error. 2197 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2198 reportParseError("`noreorder' must be set before `nomacro'"); 2199 return false; 2200 } 2201 if (Options.isReorder()) { 2202 reportParseError("`noreorder' must be set before `nomacro'"); 2203 return false; 2204 } 2205 Options.setNomacro(); 2206 Parser.Lex(); // Consume the EndOfStatement. 2207 return false; 2208} 2209 2210bool MipsAsmParser::parseSetNoMips16Directive() { 2211 Parser.Lex(); 2212 // If this is not the end of the statement, report an error. 2213 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2214 reportParseError("unexpected token in statement"); 2215 return false; 2216 } 2217 // For now do nothing. 2218 Parser.Lex(); // Consume the EndOfStatement. 2219 return false; 2220} 2221 2222bool MipsAsmParser::parseSetAssignment() { 2223 StringRef Name; 2224 const MCExpr *Value; 2225 2226 if (Parser.parseIdentifier(Name)) 2227 reportParseError("expected identifier after .set"); 2228 2229 if (getLexer().isNot(AsmToken::Comma)) 2230 return reportParseError("unexpected token in .set directive"); 2231 Lex(); // Eat comma 2232 2233 if (Parser.parseExpression(Value)) 2234 return reportParseError("expected valid expression after comma"); 2235 2236 // Check if the Name already exists as a symbol. 2237 MCSymbol *Sym = getContext().LookupSymbol(Name); 2238 if (Sym) 2239 return reportParseError("symbol already defined"); 2240 Sym = getContext().GetOrCreateSymbol(Name); 2241 Sym->setVariableValue(Value); 2242 2243 return false; 2244} 2245 2246bool MipsAsmParser::parseSetFeature(uint64_t Feature) { 2247 Parser.Lex(); 2248 if (getLexer().isNot(AsmToken::EndOfStatement)) 2249 return reportParseError("unexpected token in .set directive"); 2250 2251 switch(Feature) { 2252 default: llvm_unreachable("Unimplemented feature"); 2253 case Mips::FeatureDSP: 2254 setFeatureBits(Mips::FeatureDSP, "dsp"); 2255 getTargetStreamer().emitDirectiveSetDsp(); 2256 break; 2257 case Mips::FeatureMicroMips: 2258 getTargetStreamer().emitDirectiveSetMicroMips(); 2259 break; 2260 case Mips::FeatureMips16: 2261 getTargetStreamer().emitDirectiveSetMips16(); 2262 break; 2263 case Mips::FeatureMips32r2: 2264 setFeatureBits(Mips::FeatureMips32r2, "mips32r2"); 2265 getTargetStreamer().emitDirectiveSetMips32R2(); 2266 break; 2267 case Mips::FeatureMips64: 2268 setFeatureBits(Mips::FeatureMips64, "mips64"); 2269 getTargetStreamer().emitDirectiveSetMips64(); 2270 break; 2271 case Mips::FeatureMips64r2: 2272 setFeatureBits(Mips::FeatureMips64r2, "mips64r2"); 2273 getTargetStreamer().emitDirectiveSetMips64R2(); 2274 break; 2275 } 2276 return false; 2277} 2278 2279bool MipsAsmParser::parseRegister(unsigned &RegNum) { 2280 if (!getLexer().is(AsmToken::Dollar)) 2281 return false; 2282 2283 Parser.Lex(); 2284 2285 const AsmToken &Reg = Parser.getTok(); 2286 if (Reg.is(AsmToken::Identifier)) { 2287 RegNum = matchCPURegisterName(Reg.getIdentifier()); 2288 } else if (Reg.is(AsmToken::Integer)) { 2289 RegNum = Reg.getIntVal(); 2290 } else { 2291 return false; 2292 } 2293 2294 Parser.Lex(); 2295 return true; 2296} 2297 2298bool MipsAsmParser::eatComma(StringRef ErrorStr) { 2299 if (getLexer().isNot(AsmToken::Comma)) { 2300 SMLoc Loc = getLexer().getLoc(); 2301 Parser.eatToEndOfStatement(); 2302 return Error(Loc, ErrorStr); 2303 } 2304 2305 Parser.Lex(); // Eat the comma. 2306 return true; 2307} 2308 2309bool MipsAsmParser::parseDirectiveCPSetup() { 2310 unsigned FuncReg; 2311 unsigned Save; 2312 bool SaveIsReg = true; 2313 2314 if (!parseRegister(FuncReg)) 2315 return reportParseError("expected register containing function address"); 2316 FuncReg = getGPR(FuncReg); 2317 2318 if (!eatComma("expected comma parsing directive")) 2319 return true; 2320 2321 if (!parseRegister(Save)) { 2322 const AsmToken &Tok = Parser.getTok(); 2323 if (Tok.is(AsmToken::Integer)) { 2324 Save = Tok.getIntVal(); 2325 SaveIsReg = false; 2326 Parser.Lex(); 2327 } else 2328 return reportParseError("expected save register or stack offset"); 2329 } else 2330 Save = getGPR(Save); 2331 2332 if (!eatComma("expected comma parsing directive")) 2333 return true; 2334 2335 StringRef Name; 2336 if (Parser.parseIdentifier(Name)) 2337 reportParseError("expected identifier"); 2338 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 2339 unsigned GPReg = getGPR(matchCPURegisterName("gp")); 2340 2341 // FIXME: The code below this point should be in the TargetStreamers. 2342 // Only N32 and N64 emit anything for .cpsetup 2343 // FIXME: We should only emit something for PIC mode too. 2344 if (!isN32() && !isN64()) 2345 return false; 2346 2347 MCStreamer &TS = getStreamer(); 2348 MCInst Inst; 2349 // Either store the old $gp in a register or on the stack 2350 if (SaveIsReg) { 2351 // move $save, $gpreg 2352 Inst.setOpcode(Mips::DADDu); 2353 Inst.addOperand(MCOperand::CreateReg(Save)); 2354 Inst.addOperand(MCOperand::CreateReg(GPReg)); 2355 Inst.addOperand(MCOperand::CreateReg(getGPR(0))); 2356 } else { 2357 // sd $gpreg, offset($sp) 2358 Inst.setOpcode(Mips::SD); 2359 Inst.addOperand(MCOperand::CreateReg(GPReg)); 2360 Inst.addOperand(MCOperand::CreateReg(getGPR(matchCPURegisterName("sp")))); 2361 Inst.addOperand(MCOperand::CreateImm(Save)); 2362 } 2363 TS.EmitInstruction(Inst, STI); 2364 Inst.clear(); 2365 2366 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 2367 Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI, 2368 getContext()); 2369 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 2370 Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO, 2371 getContext()); 2372 // lui $gp, %hi(%neg(%gp_rel(funcSym))) 2373 Inst.setOpcode(Mips::LUi); 2374 Inst.addOperand(MCOperand::CreateReg(GPReg)); 2375 Inst.addOperand(MCOperand::CreateExpr(HiExpr)); 2376 TS.EmitInstruction(Inst, STI); 2377 Inst.clear(); 2378 2379 // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym))) 2380 Inst.setOpcode(Mips::ADDiu); 2381 Inst.addOperand(MCOperand::CreateReg(GPReg)); 2382 Inst.addOperand(MCOperand::CreateReg(GPReg)); 2383 Inst.addOperand(MCOperand::CreateExpr(LoExpr)); 2384 TS.EmitInstruction(Inst, STI); 2385 Inst.clear(); 2386 2387 // daddu $gp, $gp, $funcreg 2388 Inst.setOpcode(Mips::DADDu); 2389 Inst.addOperand(MCOperand::CreateReg(GPReg)); 2390 Inst.addOperand(MCOperand::CreateReg(GPReg)); 2391 Inst.addOperand(MCOperand::CreateReg(FuncReg)); 2392 TS.EmitInstruction(Inst, STI); 2393 return false; 2394} 2395 2396bool MipsAsmParser::parseDirectiveSet() { 2397 2398 // Get the next token. 2399 const AsmToken &Tok = Parser.getTok(); 2400 2401 if (Tok.getString() == "noat") { 2402 return parseSetNoAtDirective(); 2403 } else if (Tok.getString() == "at") { 2404 return parseSetAtDirective(); 2405 } else if (Tok.getString() == "reorder") { 2406 return parseSetReorderDirective(); 2407 } else if (Tok.getString() == "noreorder") { 2408 return parseSetNoReorderDirective(); 2409 } else if (Tok.getString() == "macro") { 2410 return parseSetMacroDirective(); 2411 } else if (Tok.getString() == "nomacro") { 2412 return parseSetNoMacroDirective(); 2413 } else if (Tok.getString() == "mips16") { 2414 return parseSetFeature(Mips::FeatureMips16); 2415 } else if (Tok.getString() == "nomips16") { 2416 return parseSetNoMips16Directive(); 2417 } else if (Tok.getString() == "nomicromips") { 2418 getTargetStreamer().emitDirectiveSetNoMicroMips(); 2419 Parser.eatToEndOfStatement(); 2420 return false; 2421 } else if (Tok.getString() == "micromips") { 2422 return parseSetFeature(Mips::FeatureMicroMips); 2423 } else if (Tok.getString() == "mips32r2") { 2424 return parseSetFeature(Mips::FeatureMips32r2); 2425 } else if (Tok.getString() == "mips64") { 2426 return parseSetFeature(Mips::FeatureMips64); 2427 } else if (Tok.getString() == "mips64r2") { 2428 return parseSetFeature(Mips::FeatureMips64r2); 2429 } else if (Tok.getString() == "dsp") { 2430 return parseSetFeature(Mips::FeatureDSP); 2431 } else { 2432 // It is just an identifier, look for an assignment. 2433 parseSetAssignment(); 2434 return false; 2435 } 2436 2437 return true; 2438} 2439 2440/// parseDataDirective 2441/// ::= .word [ expression (, expression)* ] 2442bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) { 2443 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2444 for (;;) { 2445 const MCExpr *Value; 2446 if (getParser().parseExpression(Value)) 2447 return true; 2448 2449 getParser().getStreamer().EmitValue(Value, Size); 2450 2451 if (getLexer().is(AsmToken::EndOfStatement)) 2452 break; 2453 2454 // FIXME: Improve diagnostic. 2455 if (getLexer().isNot(AsmToken::Comma)) 2456 return Error(L, "unexpected token in directive"); 2457 Parser.Lex(); 2458 } 2459 } 2460 2461 Parser.Lex(); 2462 return false; 2463} 2464 2465/// parseDirectiveGpWord 2466/// ::= .gpword local_sym 2467bool MipsAsmParser::parseDirectiveGpWord() { 2468 const MCExpr *Value; 2469 // EmitGPRel32Value requires an expression, so we are using base class 2470 // method to evaluate the expression. 2471 if (getParser().parseExpression(Value)) 2472 return true; 2473 getParser().getStreamer().EmitGPRel32Value(Value); 2474 2475 if (getLexer().isNot(AsmToken::EndOfStatement)) 2476 return Error(getLexer().getLoc(), "unexpected token in directive"); 2477 Parser.Lex(); // Eat EndOfStatement token. 2478 return false; 2479} 2480 2481/// parseDirectiveGpDWord 2482/// ::= .gpdword local_sym 2483bool MipsAsmParser::parseDirectiveGpDWord() { 2484 const MCExpr *Value; 2485 // EmitGPRel64Value requires an expression, so we are using base class 2486 // method to evaluate the expression. 2487 if (getParser().parseExpression(Value)) 2488 return true; 2489 getParser().getStreamer().EmitGPRel64Value(Value); 2490 2491 if (getLexer().isNot(AsmToken::EndOfStatement)) 2492 return Error(getLexer().getLoc(), "unexpected token in directive"); 2493 Parser.Lex(); // Eat EndOfStatement token. 2494 return false; 2495} 2496 2497bool MipsAsmParser::parseDirectiveOption() { 2498 // Get the option token. 2499 AsmToken Tok = Parser.getTok(); 2500 // At the moment only identifiers are supported. 2501 if (Tok.isNot(AsmToken::Identifier)) { 2502 Error(Parser.getTok().getLoc(), "unexpected token in .option directive"); 2503 Parser.eatToEndOfStatement(); 2504 return false; 2505 } 2506 2507 StringRef Option = Tok.getIdentifier(); 2508 2509 if (Option == "pic0") { 2510 getTargetStreamer().emitDirectiveOptionPic0(); 2511 Parser.Lex(); 2512 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 2513 Error(Parser.getTok().getLoc(), 2514 "unexpected token in .option pic0 directive"); 2515 Parser.eatToEndOfStatement(); 2516 } 2517 return false; 2518 } 2519 2520 if (Option == "pic2") { 2521 getTargetStreamer().emitDirectiveOptionPic2(); 2522 Parser.Lex(); 2523 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 2524 Error(Parser.getTok().getLoc(), 2525 "unexpected token in .option pic2 directive"); 2526 Parser.eatToEndOfStatement(); 2527 } 2528 return false; 2529 } 2530 2531 // Unknown option. 2532 Warning(Parser.getTok().getLoc(), "unknown option in .option directive"); 2533 Parser.eatToEndOfStatement(); 2534 return false; 2535} 2536 2537bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 2538 StringRef IDVal = DirectiveID.getString(); 2539 2540 if (IDVal == ".dword") { 2541 parseDataDirective(8, DirectiveID.getLoc()); 2542 return false; 2543 } 2544 2545 if (IDVal == ".ent") { 2546 // Ignore this directive for now. 2547 Parser.Lex(); 2548 return false; 2549 } 2550 2551 if (IDVal == ".end") { 2552 // Ignore this directive for now. 2553 Parser.Lex(); 2554 return false; 2555 } 2556 2557 if (IDVal == ".frame") { 2558 // Ignore this directive for now. 2559 Parser.eatToEndOfStatement(); 2560 return false; 2561 } 2562 2563 if (IDVal == ".set") { 2564 return parseDirectiveSet(); 2565 } 2566 2567 if (IDVal == ".fmask") { 2568 // Ignore this directive for now. 2569 Parser.eatToEndOfStatement(); 2570 return false; 2571 } 2572 2573 if (IDVal == ".mask") { 2574 // Ignore this directive for now. 2575 Parser.eatToEndOfStatement(); 2576 return false; 2577 } 2578 2579 if (IDVal == ".gpword") { 2580 parseDirectiveGpWord(); 2581 return false; 2582 } 2583 2584 if (IDVal == ".gpdword") { 2585 parseDirectiveGpDWord(); 2586 return false; 2587 } 2588 2589 if (IDVal == ".word") { 2590 parseDataDirective(4, DirectiveID.getLoc()); 2591 return false; 2592 } 2593 2594 if (IDVal == ".option") 2595 return parseDirectiveOption(); 2596 2597 if (IDVal == ".abicalls") { 2598 getTargetStreamer().emitDirectiveAbiCalls(); 2599 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 2600 Error(Parser.getTok().getLoc(), "unexpected token in directive"); 2601 // Clear line 2602 Parser.eatToEndOfStatement(); 2603 } 2604 return false; 2605 } 2606 2607 if (IDVal == ".cpsetup") 2608 return parseDirectiveCPSetup(); 2609 2610 return true; 2611} 2612 2613extern "C" void LLVMInitializeMipsAsmParser() { 2614 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 2615 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 2616 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 2617 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 2618} 2619 2620#define GET_REGISTER_MATCHER 2621#define GET_MATCHER_IMPLEMENTATION 2622#include "MipsGenAsmMatcher.inc" 2623