MipsAsmParser.cpp revision e925f7dbbf497412cd0cc3f67b9b96fed0cc3712
11d23c4219527d9a2bc75f5cdb1ffcaefb8bcc61bDavid Blaikie//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===// 2695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson// 3695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson// The LLVM Compiler Infrastructure 4695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson// 5695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson// This file is distributed under the University of Illinois Open Source 6695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson// License. See LICENSE.TXT for details. 7695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson// 86a2b9261bf9c973c7122d9d1febce24a38fa862dChris Lattner//===----------------------------------------------------------------------===// 9695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson 10695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson#include "MCTargetDesc/MipsMCTargetDesc.h" 11695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson#include "MipsRegisterInfo.h" 12695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson#include "llvm/ADT/StringSwitch.h" 13695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson#include "llvm/MC/MCContext.h" 14695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson#include "llvm/MC/MCExpr.h" 156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/MC/MCInst.h" 166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/MC/MCParser/MCAsmLexer.h" 176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/MC/MCStreamer.h" 19695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson#include "llvm/MC/MCSubtargetInfo.h" 206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/MC/MCSymbol.h" 216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/MC/MCTargetAsmParser.h" 226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/Support/TargetRegistry.h" 236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/ADT/APInt.h" 24695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson 256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesusing namespace llvm; 266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace llvm { 286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass MCInstrInfo; 29695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson} 306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace { 326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass MipsAssemblerOptions { 336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic: 34695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson MipsAssemblerOptions(): 356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines aTReg(1), reorder(true), macro(true) { 366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines unsigned getATRegNum() {return aTReg;} 39695dbb697d78d4c507e12b0acc6129b9650d4c3eAnders Carlsson bool setATReg(unsigned Reg); 40a989def422d0dc8a13c705766202ee738fce237aChris Lattner 41a989def422d0dc8a13c705766202ee738fce237aChris Lattner bool isReorder() {return reorder;} 426a2b9261bf9c973c7122d9d1febce24a38fa862dChris Lattner void setReorder() {reorder = true;} 43a989def422d0dc8a13c705766202ee738fce237aChris Lattner void setNoreorder() {reorder = false;} 44a989def422d0dc8a13c705766202ee738fce237aChris Lattner 45a989def422d0dc8a13c705766202ee738fce237aChris Lattner bool isMacro() {return macro;} 466a2b9261bf9c973c7122d9d1febce24a38fa862dChris Lattner void setMacro() {macro = true;} 476a2b9261bf9c973c7122d9d1febce24a38fa862dChris Lattner void setNomacro() {macro = false;} 486a2b9261bf9c973c7122d9d1febce24a38fa862dChris Lattner 496a2b9261bf9c973c7122d9d1febce24a38fa862dChris Lattnerprivate: 50a41a8c5972c2632247ae7913cf6ce65d45f7e702Douglas Gregor unsigned aTReg; 516a2b9261bf9c973c7122d9d1febce24a38fa862dChris Lattner bool reorder; 5258f9e13e87e57236fee4b914eea9be6f92a1c345Chris Lattner bool macro; 536a2b9261bf9c973c7122d9d1febce24a38fa862dChris Lattner}; 54} 55 56namespace { 57class MipsAsmParser : public MCTargetAsmParser { 58 59 MCSubtargetInfo &STI; 60 MCAsmParser &Parser; 61 MipsAssemblerOptions Options; 62 bool hasConsumedDollar; 63 64#define GET_ASSEMBLER_HEADER 65#include "MipsGenAsmMatcher.inc" 66 67 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 68 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 69 MCStreamer &Out, unsigned &ErrorInfo, 70 bool MatchingInlineAsm); 71 72 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 73 74 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 75 SMLoc NameLoc, 76 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 77 78 bool ParseDirective(AsmToken DirectiveID); 79 80 MipsAsmParser::OperandMatchResultTy 81 parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 82 int RegKind); 83 84 MipsAsmParser::OperandMatchResultTy 85 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 86 87 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind); 88 89 MipsAsmParser::OperandMatchResultTy 90 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 91 92 MipsAsmParser::OperandMatchResultTy 93 parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 94 95 MipsAsmParser::OperandMatchResultTy 96 parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 97 98 MipsAsmParser::OperandMatchResultTy 99 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 100 101 MipsAsmParser::OperandMatchResultTy 102 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 103 104 MipsAsmParser::OperandMatchResultTy 105 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 106 107 MipsAsmParser::OperandMatchResultTy 108 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 109 110 MipsAsmParser::OperandMatchResultTy 111 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 112 113 MipsAsmParser::OperandMatchResultTy 114 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 115 116 MipsAsmParser::OperandMatchResultTy 117 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 118 119 MipsAsmParser::OperandMatchResultTy 120 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 121 122 MipsAsmParser::OperandMatchResultTy 123 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 124 125 MipsAsmParser::OperandMatchResultTy 126 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 127 128 MipsAsmParser::OperandMatchResultTy 129 parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 130 131 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 132 unsigned RegKind); 133 134 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, 135 StringRef Mnemonic); 136 137 int tryParseRegister(bool is64BitReg); 138 139 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 140 bool is64BitReg); 141 142 bool needsExpansion(MCInst &Inst); 143 144 void expandInstruction(MCInst &Inst, SMLoc IDLoc, 145 SmallVectorImpl<MCInst> &Instructions); 146 void expandLoadImm(MCInst &Inst, SMLoc IDLoc, 147 SmallVectorImpl<MCInst> &Instructions); 148 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 149 SmallVectorImpl<MCInst> &Instructions); 150 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 151 SmallVectorImpl<MCInst> &Instructions); 152 void expandMemInst(MCInst &Inst, SMLoc IDLoc, 153 SmallVectorImpl<MCInst> &Instructions, 154 bool isLoad,bool isImmOpnd); 155 bool reportParseError(StringRef ErrorMsg); 156 157 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); 158 bool parseRelocOperand(const MCExpr *&Res); 159 160 const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); 161 162 bool isEvaluated(const MCExpr *Expr); 163 bool parseDirectiveSet(); 164 165 bool parseSetAtDirective(); 166 bool parseSetNoAtDirective(); 167 bool parseSetMacroDirective(); 168 bool parseSetNoMacroDirective(); 169 bool parseSetReorderDirective(); 170 bool parseSetNoReorderDirective(); 171 172 bool parseSetAssignment(); 173 174 bool parseDirectiveWord(unsigned Size, SMLoc L); 175 176 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 177 178 bool isMips64() const { 179 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0; 180 } 181 182 bool isFP64() const { 183 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; 184 } 185 186 bool isN64() const { 187 return STI.getFeatureBits() & Mips::FeatureN64; 188 } 189 190 int matchRegisterName(StringRef Symbol, bool is64BitReg); 191 192 int matchCPURegisterName(StringRef Symbol); 193 194 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 195 196 int matchFPURegisterName(StringRef Name); 197 198 int matchFCCRegisterName(StringRef Name); 199 200 int matchACRegisterName(StringRef Name); 201 202 int regKindToRegClass(int RegKind); 203 204 unsigned getReg(int RC, int RegNo); 205 206 int getATReg(); 207 208 bool processInstruction(MCInst &Inst, SMLoc IDLoc, 209 SmallVectorImpl<MCInst> &Instructions); 210public: 211 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, 212 const MCInstrInfo &MII) 213 : MCTargetAsmParser(), STI(sti), Parser(parser), 214 hasConsumedDollar(false) { 215 // Initialize the set of available features. 216 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 217 } 218 219 MCAsmParser &getParser() const { return Parser; } 220 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 221 222}; 223} 224 225namespace { 226 227/// MipsOperand - Instances of this class represent a parsed Mips machine 228/// instruction. 229class MipsOperand : public MCParsedAsmOperand { 230 231public: 232 enum RegisterKind { 233 Kind_None, 234 Kind_GPR32, 235 Kind_GPR64, 236 Kind_HWRegs, 237 Kind_FGR32Regs, 238 Kind_FGRH32Regs, 239 Kind_FGR64Regs, 240 Kind_AFGR64Regs, 241 Kind_CCRRegs, 242 Kind_FCCRegs, 243 Kind_ACC64DSP, 244 Kind_LO32DSP, 245 Kind_HI32DSP, 246 Kind_COP2 247 }; 248 249private: 250 enum KindTy { 251 k_CondCode, 252 k_CoprocNum, 253 k_Immediate, 254 k_Memory, 255 k_PostIndexRegister, 256 k_Register, 257 k_PtrReg, 258 k_Token 259 } Kind; 260 261 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 262 263 struct Token { 264 const char *Data; 265 unsigned Length; 266 }; 267 268 struct RegOp { 269 unsigned RegNum; 270 RegisterKind Kind; 271 }; 272 273 struct ImmOp { 274 const MCExpr *Val; 275 }; 276 277 struct MemOp { 278 unsigned Base; 279 const MCExpr *Off; 280 }; 281 282 union { 283 struct Token Tok; 284 struct RegOp Reg; 285 struct ImmOp Imm; 286 struct MemOp Mem; 287 }; 288 289 SMLoc StartLoc, EndLoc; 290 291public: 292 void addRegOperands(MCInst &Inst, unsigned N) const { 293 assert(N == 1 && "Invalid number of operands!"); 294 Inst.addOperand(MCOperand::CreateReg(getReg())); 295 } 296 297 void addPtrRegOperands(MCInst &Inst, unsigned N) const { 298 assert(N == 1 && "Invalid number of operands!"); 299 Inst.addOperand(MCOperand::CreateReg(getPtrReg())); 300 } 301 302 void addExpr(MCInst &Inst, const MCExpr *Expr) const{ 303 // Add as immediate when possible. Null MCExpr = 0. 304 if (Expr == 0) 305 Inst.addOperand(MCOperand::CreateImm(0)); 306 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 307 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 308 else 309 Inst.addOperand(MCOperand::CreateExpr(Expr)); 310 } 311 312 void addImmOperands(MCInst &Inst, unsigned N) const { 313 assert(N == 1 && "Invalid number of operands!"); 314 const MCExpr *Expr = getImm(); 315 addExpr(Inst, Expr); 316 } 317 318 void addMemOperands(MCInst &Inst, unsigned N) const { 319 assert(N == 2 && "Invalid number of operands!"); 320 321 Inst.addOperand(MCOperand::CreateReg(getMemBase())); 322 323 const MCExpr *Expr = getMemOff(); 324 addExpr(Inst, Expr); 325 } 326 327 bool isReg() const { return Kind == k_Register; } 328 bool isImm() const { return Kind == k_Immediate; } 329 bool isToken() const { return Kind == k_Token; } 330 bool isMem() const { return Kind == k_Memory; } 331 bool isPtrReg() const { return Kind == k_PtrReg; } 332 333 StringRef getToken() const { 334 assert(Kind == k_Token && "Invalid access!"); 335 return StringRef(Tok.Data, Tok.Length); 336 } 337 338 unsigned getReg() const { 339 assert((Kind == k_Register) && "Invalid access!"); 340 return Reg.RegNum; 341 } 342 343 unsigned getPtrReg() const { 344 assert((Kind == k_PtrReg) && "Invalid access!"); 345 return Reg.RegNum; 346 } 347 348 void setRegKind(RegisterKind RegKind) { 349 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!"); 350 Reg.Kind = RegKind; 351 } 352 353 const MCExpr *getImm() const { 354 assert((Kind == k_Immediate) && "Invalid access!"); 355 return Imm.Val; 356 } 357 358 unsigned getMemBase() const { 359 assert((Kind == k_Memory) && "Invalid access!"); 360 return Mem.Base; 361 } 362 363 const MCExpr *getMemOff() const { 364 assert((Kind == k_Memory) && "Invalid access!"); 365 return Mem.Off; 366 } 367 368 static MipsOperand *CreateToken(StringRef Str, SMLoc S) { 369 MipsOperand *Op = new MipsOperand(k_Token); 370 Op->Tok.Data = Str.data(); 371 Op->Tok.Length = Str.size(); 372 Op->StartLoc = S; 373 Op->EndLoc = S; 374 return Op; 375 } 376 377 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 378 MipsOperand *Op = new MipsOperand(k_Register); 379 Op->Reg.RegNum = RegNum; 380 Op->StartLoc = S; 381 Op->EndLoc = E; 382 return Op; 383 } 384 385 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) { 386 MipsOperand *Op = new MipsOperand(k_PtrReg); 387 Op->Reg.RegNum = RegNum; 388 Op->StartLoc = S; 389 Op->EndLoc = E; 390 return Op; 391 } 392 393 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 394 MipsOperand *Op = new MipsOperand(k_Immediate); 395 Op->Imm.Val = Val; 396 Op->StartLoc = S; 397 Op->EndLoc = E; 398 return Op; 399 } 400 401 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, 402 SMLoc S, SMLoc E) { 403 MipsOperand *Op = new MipsOperand(k_Memory); 404 Op->Mem.Base = Base; 405 Op->Mem.Off = Off; 406 Op->StartLoc = S; 407 Op->EndLoc = E; 408 return Op; 409 } 410 411 bool isGPR32Asm() const { 412 return Kind == k_Register && Reg.Kind == Kind_GPR32; 413 } 414 void addRegAsmOperands(MCInst &Inst, unsigned N) const { 415 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 416 } 417 418 bool isGPR64Asm() const { 419 return Kind == k_Register && Reg.Kind == Kind_GPR64; 420 } 421 422 bool isHWRegsAsm() const { 423 assert((Kind == k_Register) && "Invalid access!"); 424 return Reg.Kind == Kind_HWRegs; 425 } 426 427 bool isCCRAsm() const { 428 assert((Kind == k_Register) && "Invalid access!"); 429 return Reg.Kind == Kind_CCRRegs; 430 } 431 432 bool isAFGR64Asm() const { 433 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs; 434 } 435 436 bool isFGR64Asm() const { 437 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs; 438 } 439 440 bool isFGR32Asm() const { 441 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs; 442 } 443 444 bool isFGRH32Asm() const { 445 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs; 446 } 447 448 bool isFCCRegsAsm() const { 449 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs; 450 } 451 452 bool isACC64DSPAsm() const { 453 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP; 454 } 455 456 bool isLO32DSPAsm() const { 457 return Kind == k_Register && Reg.Kind == Kind_LO32DSP; 458 } 459 460 bool isHI32DSPAsm() const { 461 return Kind == k_Register && Reg.Kind == Kind_HI32DSP; 462 } 463 464 bool isCOP2Asm() const { 465 return Kind == k_Register && Reg.Kind == Kind_COP2; 466 } 467 468 /// getStartLoc - Get the location of the first token of this operand. 469 SMLoc getStartLoc() const { 470 return StartLoc; 471 } 472 /// getEndLoc - Get the location of the last token of this operand. 473 SMLoc getEndLoc() const { 474 return EndLoc; 475 } 476 477 virtual void print(raw_ostream &OS) const { 478 llvm_unreachable("unimplemented!"); 479 } 480}; // class MipsOperand 481} // namespace 482 483namespace llvm { 484extern const MCInstrDesc MipsInsts[]; 485} 486static const MCInstrDesc &getInstDesc(unsigned Opcode) { 487 return MipsInsts[Opcode]; 488} 489 490bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 491 SmallVectorImpl<MCInst> &Instructions) { 492 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 493 Inst.setLoc(IDLoc); 494 if (MCID.hasDelaySlot() && Options.isReorder()) { 495 // If this instruction has a delay slot and .set reorder is active, 496 // emit a NOP after it. 497 Instructions.push_back(Inst); 498 MCInst NopInst; 499 NopInst.setOpcode(Mips::SLL); 500 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 501 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 502 NopInst.addOperand(MCOperand::CreateImm(0)); 503 Instructions.push_back(NopInst); 504 return false; 505 } 506 507 if (MCID.mayLoad() || MCID.mayStore()) { 508 // Check the offset of memory operand, if it is a symbol 509 // reference or immediate we may have to expand instructions. 510 for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 511 const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 512 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) 513 || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 514 MCOperand &Op = Inst.getOperand(i); 515 if (Op.isImm()) { 516 int MemOffset = Op.getImm(); 517 if (MemOffset < -32768 || MemOffset > 32767) { 518 // Offset can't exceed 16bit value. 519 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true); 520 return false; 521 } 522 } else if (Op.isExpr()) { 523 const MCExpr *Expr = Op.getExpr(); 524 if (Expr->getKind() == MCExpr::SymbolRef) { 525 const MCSymbolRefExpr *SR = 526 static_cast<const MCSymbolRefExpr*>(Expr); 527 if (SR->getKind() == MCSymbolRefExpr::VK_None) { 528 // Expand symbol. 529 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 530 return false; 531 } 532 } else if (!isEvaluated(Expr)) { 533 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 534 return false; 535 } 536 } 537 } 538 } // for 539 } // if load/store 540 541 if (needsExpansion(Inst)) 542 expandInstruction(Inst, IDLoc, Instructions); 543 else 544 Instructions.push_back(Inst); 545 546 return false; 547} 548 549bool MipsAsmParser::needsExpansion(MCInst &Inst) { 550 551 switch (Inst.getOpcode()) { 552 case Mips::LoadImm32Reg: 553 case Mips::LoadAddr32Imm: 554 case Mips::LoadAddr32Reg: 555 return true; 556 default: 557 return false; 558 } 559} 560 561void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 562 SmallVectorImpl<MCInst> &Instructions) { 563 switch (Inst.getOpcode()) { 564 case Mips::LoadImm32Reg: 565 return expandLoadImm(Inst, IDLoc, Instructions); 566 case Mips::LoadAddr32Imm: 567 return expandLoadAddressImm(Inst, IDLoc, Instructions); 568 case Mips::LoadAddr32Reg: 569 return expandLoadAddressReg(Inst, IDLoc, Instructions); 570 } 571} 572 573void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 574 SmallVectorImpl<MCInst> &Instructions) { 575 MCInst tmpInst; 576 const MCOperand &ImmOp = Inst.getOperand(1); 577 assert(ImmOp.isImm() && "expected immediate operand kind"); 578 const MCOperand &RegOp = Inst.getOperand(0); 579 assert(RegOp.isReg() && "expected register operand kind"); 580 581 int ImmValue = ImmOp.getImm(); 582 tmpInst.setLoc(IDLoc); 583 if (0 <= ImmValue && ImmValue <= 65535) { 584 // For 0 <= j <= 65535. 585 // li d,j => ori d,$zero,j 586 tmpInst.setOpcode(Mips::ORi); 587 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 588 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 589 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 590 Instructions.push_back(tmpInst); 591 } else if (ImmValue < 0 && ImmValue >= -32768) { 592 // For -32768 <= j < 0. 593 // li d,j => addiu d,$zero,j 594 tmpInst.setOpcode(Mips::ADDiu); 595 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 596 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 597 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 598 Instructions.push_back(tmpInst); 599 } else { 600 // For any other value of j that is representable as a 32-bit integer. 601 // li d,j => lui d,hi16(j) 602 // ori d,d,lo16(j) 603 tmpInst.setOpcode(Mips::LUi); 604 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 605 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 606 Instructions.push_back(tmpInst); 607 tmpInst.clear(); 608 tmpInst.setOpcode(Mips::ORi); 609 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 610 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 611 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 612 tmpInst.setLoc(IDLoc); 613 Instructions.push_back(tmpInst); 614 } 615} 616 617void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 618 SmallVectorImpl<MCInst> &Instructions) { 619 MCInst tmpInst; 620 const MCOperand &ImmOp = Inst.getOperand(2); 621 assert(ImmOp.isImm() && "expected immediate operand kind"); 622 const MCOperand &SrcRegOp = Inst.getOperand(1); 623 assert(SrcRegOp.isReg() && "expected register operand kind"); 624 const MCOperand &DstRegOp = Inst.getOperand(0); 625 assert(DstRegOp.isReg() && "expected register operand kind"); 626 int ImmValue = ImmOp.getImm(); 627 if (-32768 <= ImmValue && ImmValue <= 65535) { 628 // For -32768 <= j <= 65535. 629 // la d,j(s) => addiu d,s,j 630 tmpInst.setOpcode(Mips::ADDiu); 631 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 632 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 633 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 634 Instructions.push_back(tmpInst); 635 } else { 636 // For any other value of j that is representable as a 32-bit integer. 637 // la d,j(s) => lui d,hi16(j) 638 // ori d,d,lo16(j) 639 // addu d,d,s 640 tmpInst.setOpcode(Mips::LUi); 641 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 642 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 643 Instructions.push_back(tmpInst); 644 tmpInst.clear(); 645 tmpInst.setOpcode(Mips::ORi); 646 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 647 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 648 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 649 Instructions.push_back(tmpInst); 650 tmpInst.clear(); 651 tmpInst.setOpcode(Mips::ADDu); 652 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 653 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 654 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 655 Instructions.push_back(tmpInst); 656 } 657} 658 659void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 660 SmallVectorImpl<MCInst> &Instructions) { 661 MCInst tmpInst; 662 const MCOperand &ImmOp = Inst.getOperand(1); 663 assert(ImmOp.isImm() && "expected immediate operand kind"); 664 const MCOperand &RegOp = Inst.getOperand(0); 665 assert(RegOp.isReg() && "expected register operand kind"); 666 int ImmValue = ImmOp.getImm(); 667 if (-32768 <= ImmValue && ImmValue <= 65535) { 668 // For -32768 <= j <= 65535. 669 // la d,j => addiu d,$zero,j 670 tmpInst.setOpcode(Mips::ADDiu); 671 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 672 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 673 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 674 Instructions.push_back(tmpInst); 675 } else { 676 // For any other value of j that is representable as a 32-bit integer. 677 // la d,j => lui d,hi16(j) 678 // ori d,d,lo16(j) 679 tmpInst.setOpcode(Mips::LUi); 680 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 681 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 682 Instructions.push_back(tmpInst); 683 tmpInst.clear(); 684 tmpInst.setOpcode(Mips::ORi); 685 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 686 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 687 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 688 Instructions.push_back(tmpInst); 689 } 690} 691 692void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, 693 SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) { 694 const MCSymbolRefExpr *SR; 695 MCInst TempInst; 696 unsigned ImmOffset, HiOffset, LoOffset; 697 const MCExpr *ExprOffset; 698 unsigned TmpRegNum; 699 unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID 700 : Mips::GPR32RegClassID, getATReg()); 701 // 1st operand is either the source or destination register. 702 assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 703 unsigned RegOpNum = Inst.getOperand(0).getReg(); 704 // 2nd operand is the base register. 705 assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 706 unsigned BaseRegNum = Inst.getOperand(1).getReg(); 707 // 3rd operand is either an immediate or expression. 708 if (isImmOpnd) { 709 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); 710 ImmOffset = Inst.getOperand(2).getImm(); 711 LoOffset = ImmOffset & 0x0000ffff; 712 HiOffset = (ImmOffset & 0xffff0000) >> 16; 713 // If msb of LoOffset is 1(negative number) we must increment HiOffset. 714 if (LoOffset & 0x8000) 715 HiOffset++; 716 } else 717 ExprOffset = Inst.getOperand(2).getExpr(); 718 // All instructions will have the same location. 719 TempInst.setLoc(IDLoc); 720 // 1st instruction in expansion is LUi. For load instruction we can use 721 // the dst register as a temporary if base and dst are different, 722 // but for stores we must use $at. 723 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum; 724 TempInst.setOpcode(Mips::LUi); 725 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 726 if (isImmOpnd) 727 TempInst.addOperand(MCOperand::CreateImm(HiOffset)); 728 else { 729 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 730 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset); 731 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 732 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI, 733 getContext()); 734 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 735 } else { 736 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi"); 737 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 738 } 739 } 740 // Add the instruction to the list. 741 Instructions.push_back(TempInst); 742 // Prepare TempInst for next instruction. 743 TempInst.clear(); 744 // Add temp register to base. 745 TempInst.setOpcode(Mips::ADDu); 746 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 747 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 748 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum)); 749 Instructions.push_back(TempInst); 750 TempInst.clear(); 751 // And finaly, create original instruction with low part 752 // of offset and new base. 753 TempInst.setOpcode(Inst.getOpcode()); 754 TempInst.addOperand(MCOperand::CreateReg(RegOpNum)); 755 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 756 if (isImmOpnd) 757 TempInst.addOperand(MCOperand::CreateImm(LoOffset)); 758 else { 759 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 760 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 761 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO, 762 getContext()); 763 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 764 } else { 765 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo"); 766 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 767 } 768 } 769 Instructions.push_back(TempInst); 770 TempInst.clear(); 771} 772 773bool MipsAsmParser:: 774MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 775 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 776 MCStreamer &Out, unsigned &ErrorInfo, 777 bool MatchingInlineAsm) { 778 MCInst Inst; 779 SmallVector<MCInst, 8> Instructions; 780 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, 781 MatchingInlineAsm); 782 783 switch (MatchResult) { 784 default: 785 break; 786 case Match_Success: { 787 if (processInstruction(Inst, IDLoc, Instructions)) 788 return true; 789 for (unsigned i = 0; i < Instructions.size(); i++) 790 Out.EmitInstruction(Instructions[i]); 791 return false; 792 } 793 case Match_MissingFeature: 794 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 795 return true; 796 case Match_InvalidOperand: { 797 SMLoc ErrorLoc = IDLoc; 798 if (ErrorInfo != ~0U) { 799 if (ErrorInfo >= Operands.size()) 800 return Error(IDLoc, "too few operands for instruction"); 801 802 ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc(); 803 if (ErrorLoc == SMLoc()) 804 ErrorLoc = IDLoc; 805 } 806 807 return Error(ErrorLoc, "invalid operand for instruction"); 808 } 809 case Match_MnemonicFail: 810 return Error(IDLoc, "invalid instruction"); 811 } 812 return true; 813} 814 815int MipsAsmParser::matchCPURegisterName(StringRef Name) { 816 int CC; 817 818 if (Name == "at") 819 return getATReg(); 820 821 CC = StringSwitch<unsigned>(Name) 822 .Case("zero", 0) 823 .Case("a0", 4) 824 .Case("a1", 5) 825 .Case("a2", 6) 826 .Case("a3", 7) 827 .Case("v0", 2) 828 .Case("v1", 3) 829 .Case("s0", 16) 830 .Case("s1", 17) 831 .Case("s2", 18) 832 .Case("s3", 19) 833 .Case("s4", 20) 834 .Case("s5", 21) 835 .Case("s6", 22) 836 .Case("s7", 23) 837 .Case("k0", 26) 838 .Case("k1", 27) 839 .Case("sp", 29) 840 .Case("fp", 30) 841 .Case("gp", 28) 842 .Case("ra", 31) 843 .Case("t0", 8) 844 .Case("t1", 9) 845 .Case("t2", 10) 846 .Case("t3", 11) 847 .Case("t4", 12) 848 .Case("t5", 13) 849 .Case("t6", 14) 850 .Case("t7", 15) 851 .Case("t8", 24) 852 .Case("t9", 25) 853 .Default(-1); 854 855 // Although SGI documentation just cuts out t0-t3 for n32/n64, 856 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 857 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 858 if (isMips64() && 8 <= CC && CC <= 11) 859 CC += 4; 860 861 if (CC == -1 && isMips64()) 862 CC = StringSwitch<unsigned>(Name) 863 .Case("a4", 8) 864 .Case("a5", 9) 865 .Case("a6", 10) 866 .Case("a7", 11) 867 .Case("kt0", 26) 868 .Case("kt1", 27) 869 .Case("s8", 30) 870 .Default(-1); 871 872 return CC; 873} 874 875int MipsAsmParser::matchFPURegisterName(StringRef Name) { 876 877 if (Name[0] == 'f') { 878 StringRef NumString = Name.substr(1); 879 unsigned IntVal; 880 if (NumString.getAsInteger(10, IntVal)) 881 return -1; // This is not an integer. 882 if (IntVal > 31) // Maximum index for fpu register. 883 return -1; 884 return IntVal; 885 } 886 return -1; 887} 888 889int MipsAsmParser::matchFCCRegisterName(StringRef Name) { 890 891 if (Name.startswith("fcc")) { 892 StringRef NumString = Name.substr(3); 893 unsigned IntVal; 894 if (NumString.getAsInteger(10, IntVal)) 895 return -1; // This is not an integer. 896 if (IntVal > 7) // There are only 8 fcc registers. 897 return -1; 898 return IntVal; 899 } 900 return -1; 901} 902 903int MipsAsmParser::matchACRegisterName(StringRef Name) { 904 905 if (Name.startswith("ac")) { 906 StringRef NumString = Name.substr(2); 907 unsigned IntVal; 908 if (NumString.getAsInteger(10, IntVal)) 909 return -1; // This is not an integer. 910 if (IntVal > 3) // There are only 3 acc registers. 911 return -1; 912 return IntVal; 913 } 914 return -1; 915} 916 917int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) { 918 919 int CC; 920 CC = matchCPURegisterName(Name); 921 if (CC != -1) 922 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID 923 : Mips::GPR32RegClassID); 924 CC= matchFPURegisterName(Name); 925 //TODO: decide about fpu register class 926 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID 927 : Mips::FGR32RegClassID); 928} 929 930int MipsAsmParser::regKindToRegClass(int RegKind) { 931 932 switch (RegKind) { 933 case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID; 934 case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID; 935 case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID; 936 case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID; 937 case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID; 938 case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID; 939 case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID; 940 case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID; 941 case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID; 942 case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID; 943 default :return -1; 944 } 945 946} 947 948bool MipsAssemblerOptions::setATReg(unsigned Reg) { 949 if (Reg > 31) 950 return false; 951 952 aTReg = Reg; 953 return true; 954} 955 956int MipsAsmParser::getATReg() { 957 return Options.getATRegNum(); 958} 959 960unsigned MipsAsmParser::getReg(int RC, int RegNo) { 961 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 962} 963 964int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 965 if (RegNum > 966 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs()) 967 return -1; 968 969 return getReg(RegClass, RegNum); 970} 971 972int MipsAsmParser::tryParseRegister(bool is64BitReg) { 973 const AsmToken &Tok = Parser.getTok(); 974 int RegNum = -1; 975 976 if (Tok.is(AsmToken::Identifier)) { 977 std::string lowerCase = Tok.getString().lower(); 978 RegNum = matchRegisterName(lowerCase, is64BitReg); 979 } else if (Tok.is(AsmToken::Integer)) 980 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()), 981 is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID); 982 return RegNum; 983} 984 985bool MipsAsmParser::tryParseRegisterOperand( 986 SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) { 987 988 SMLoc S = Parser.getTok().getLoc(); 989 int RegNo = -1; 990 991 RegNo = tryParseRegister(is64BitReg); 992 if (RegNo == -1) 993 return true; 994 995 Operands.push_back(MipsOperand::CreateReg(RegNo, S, 996 Parser.getTok().getLoc())); 997 Parser.Lex(); // Eat register token. 998 return false; 999} 1000 1001bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands, 1002 StringRef Mnemonic) { 1003 // Check if the current operand has a custom associated parser, if so, try to 1004 // custom parse the operand, or fallback to the general approach. 1005 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1006 if (ResTy == MatchOperand_Success) 1007 return false; 1008 // If there wasn't a custom match, try the generic matcher below. Otherwise, 1009 // there was a match, but an error occurred, in which case, just return that 1010 // the operand parsing failed. 1011 if (ResTy == MatchOperand_ParseFail) 1012 return true; 1013 1014 switch (getLexer().getKind()) { 1015 default: 1016 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 1017 return true; 1018 case AsmToken::Dollar: { 1019 // Parse the register. 1020 SMLoc S = Parser.getTok().getLoc(); 1021 Parser.Lex(); // Eat dollar token. 1022 // Parse the register operand. 1023 if (!tryParseRegisterOperand(Operands, isMips64())) { 1024 if (getLexer().is(AsmToken::LParen)) { 1025 // Check if it is indexed addressing operand. 1026 Operands.push_back(MipsOperand::CreateToken("(", S)); 1027 Parser.Lex(); // Eat the parenthesis. 1028 if (getLexer().isNot(AsmToken::Dollar)) 1029 return true; 1030 1031 Parser.Lex(); // Eat the dollar 1032 if (tryParseRegisterOperand(Operands, isMips64())) 1033 return true; 1034 1035 if (!getLexer().is(AsmToken::RParen)) 1036 return true; 1037 1038 S = Parser.getTok().getLoc(); 1039 Operands.push_back(MipsOperand::CreateToken(")", S)); 1040 Parser.Lex(); 1041 } 1042 return false; 1043 } 1044 // Maybe it is a symbol reference. 1045 StringRef Identifier; 1046 if (Parser.parseIdentifier(Identifier)) 1047 return true; 1048 1049 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1050 1051 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 1052 1053 // Otherwise create a symbol reference. 1054 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 1055 getContext()); 1056 1057 Operands.push_back(MipsOperand::CreateImm(Res, S, E)); 1058 return false; 1059 } 1060 case AsmToken::Identifier: 1061 // Look for the existing symbol, we should check if 1062 // we need to assigne the propper RegisterKind. 1063 if (searchSymbolAlias(Operands, MipsOperand::Kind_None)) 1064 return false; 1065 // Else drop to expression parsing. 1066 case AsmToken::LParen: 1067 case AsmToken::Minus: 1068 case AsmToken::Plus: 1069 case AsmToken::Integer: 1070 case AsmToken::String: { 1071 // Quoted label names. 1072 const MCExpr *IdVal; 1073 SMLoc S = Parser.getTok().getLoc(); 1074 if (getParser().parseExpression(IdVal)) 1075 return true; 1076 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1077 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 1078 return false; 1079 } 1080 case AsmToken::Percent: { 1081 // It is a symbol reference or constant expression. 1082 const MCExpr *IdVal; 1083 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 1084 if (parseRelocOperand(IdVal)) 1085 return true; 1086 1087 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1088 1089 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 1090 return false; 1091 } // case AsmToken::Percent 1092 } // switch(getLexer().getKind()) 1093 return true; 1094} 1095 1096const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, 1097 StringRef RelocStr) { 1098 const MCExpr *Res; 1099 // Check the type of the expression. 1100 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) { 1101 // It's a constant, evaluate lo or hi value. 1102 if (RelocStr == "lo") { 1103 short Val = MCE->getValue(); 1104 Res = MCConstantExpr::Create(Val, getContext()); 1105 } else if (RelocStr == "hi") { 1106 int Val = MCE->getValue(); 1107 int LoSign = Val & 0x8000; 1108 Val = (Val & 0xffff0000) >> 16; 1109 // Lower part is treated as a signed int, so if it is negative 1110 // we must add 1 to the hi part to compensate. 1111 if (LoSign) 1112 Val++; 1113 Res = MCConstantExpr::Create(Val, getContext()); 1114 } else { 1115 llvm_unreachable("Invalid RelocStr value"); 1116 } 1117 return Res; 1118 } 1119 1120 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) { 1121 // It's a symbol, create a symbolic expression from the symbol. 1122 StringRef Symbol = MSRE->getSymbol().getName(); 1123 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 1124 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext()); 1125 return Res; 1126 } 1127 1128 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 1129 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr); 1130 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); 1131 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext()); 1132 return Res; 1133 } 1134 1135 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) { 1136 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr); 1137 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext()); 1138 return Res; 1139 } 1140 // Just return the original expression. 1141 return Expr; 1142} 1143 1144bool MipsAsmParser::isEvaluated(const MCExpr *Expr) { 1145 1146 switch (Expr->getKind()) { 1147 case MCExpr::Constant: 1148 return true; 1149 case MCExpr::SymbolRef: 1150 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None); 1151 case MCExpr::Binary: 1152 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 1153 if (!isEvaluated(BE->getLHS())) 1154 return false; 1155 return isEvaluated(BE->getRHS()); 1156 } 1157 case MCExpr::Unary: 1158 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr()); 1159 default: 1160 return false; 1161 } 1162 return false; 1163} 1164 1165bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 1166 Parser.Lex(); // Eat the % token. 1167 const AsmToken &Tok = Parser.getTok(); // Get next token, operation. 1168 if (Tok.isNot(AsmToken::Identifier)) 1169 return true; 1170 1171 std::string Str = Tok.getIdentifier().str(); 1172 1173 Parser.Lex(); // Eat the identifier. 1174 // Now make an expression from the rest of the operand. 1175 const MCExpr *IdVal; 1176 SMLoc EndLoc; 1177 1178 if (getLexer().getKind() == AsmToken::LParen) { 1179 while (1) { 1180 Parser.Lex(); // Eat the '(' token. 1181 if (getLexer().getKind() == AsmToken::Percent) { 1182 Parser.Lex(); // Eat the % token. 1183 const AsmToken &nextTok = Parser.getTok(); 1184 if (nextTok.isNot(AsmToken::Identifier)) 1185 return true; 1186 Str += "(%"; 1187 Str += nextTok.getIdentifier(); 1188 Parser.Lex(); // Eat the identifier. 1189 if (getLexer().getKind() != AsmToken::LParen) 1190 return true; 1191 } else 1192 break; 1193 } 1194 if (getParser().parseParenExpression(IdVal, EndLoc)) 1195 return true; 1196 1197 while (getLexer().getKind() == AsmToken::RParen) 1198 Parser.Lex(); // Eat the ')' token. 1199 1200 } else 1201 return true; // Parenthesis must follow the relocation operand. 1202 1203 Res = evaluateRelocExpr(IdVal, Str); 1204 return false; 1205} 1206 1207bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1208 SMLoc &EndLoc) { 1209 StartLoc = Parser.getTok().getLoc(); 1210 RegNo = tryParseRegister(isMips64()); 1211 EndLoc = Parser.getTok().getLoc(); 1212 return (RegNo == (unsigned) -1); 1213} 1214 1215bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 1216 SMLoc S; 1217 bool Result = true; 1218 1219 while (getLexer().getKind() == AsmToken::LParen) 1220 Parser.Lex(); 1221 1222 switch (getLexer().getKind()) { 1223 default: 1224 return true; 1225 case AsmToken::Identifier: 1226 case AsmToken::LParen: 1227 case AsmToken::Integer: 1228 case AsmToken::Minus: 1229 case AsmToken::Plus: 1230 if (isParenExpr) 1231 Result = getParser().parseParenExpression(Res, S); 1232 else 1233 Result = (getParser().parseExpression(Res)); 1234 while (getLexer().getKind() == AsmToken::RParen) 1235 Parser.Lex(); 1236 break; 1237 case AsmToken::Percent: 1238 Result = parseRelocOperand(Res); 1239 } 1240 return Result; 1241} 1242 1243MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( 1244 SmallVectorImpl<MCParsedAsmOperand*>&Operands) { 1245 1246 const MCExpr *IdVal = 0; 1247 SMLoc S; 1248 bool isParenExpr = false; 1249 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch; 1250 // First operand is the offset. 1251 S = Parser.getTok().getLoc(); 1252 1253 if (getLexer().getKind() == AsmToken::LParen) { 1254 Parser.Lex(); 1255 isParenExpr = true; 1256 } 1257 1258 if (getLexer().getKind() != AsmToken::Dollar) { 1259 if (parseMemOffset(IdVal, isParenExpr)) 1260 return MatchOperand_ParseFail; 1261 1262 const AsmToken &Tok = Parser.getTok(); // Get the next token. 1263 if (Tok.isNot(AsmToken::LParen)) { 1264 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]); 1265 if (Mnemonic->getToken() == "la") { 1266 SMLoc E = SMLoc::getFromPointer( 1267 Parser.getTok().getLoc().getPointer() - 1); 1268 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 1269 return MatchOperand_Success; 1270 } 1271 if (Tok.is(AsmToken::EndOfStatement)) { 1272 SMLoc E = SMLoc::getFromPointer( 1273 Parser.getTok().getLoc().getPointer() - 1); 1274 1275 // Zero register assumed, add a memory operand with ZERO as its base. 1276 Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64 1277 : Mips::ZERO, 1278 IdVal, S, E)); 1279 return MatchOperand_Success; 1280 } 1281 Error(Parser.getTok().getLoc(), "'(' expected"); 1282 return MatchOperand_ParseFail; 1283 } 1284 1285 Parser.Lex(); // Eat the '(' token. 1286 } 1287 1288 Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64: 1289 (int) MipsOperand::Kind_GPR32); 1290 if (Res != MatchOperand_Success) 1291 return Res; 1292 1293 if (Parser.getTok().isNot(AsmToken::RParen)) { 1294 Error(Parser.getTok().getLoc(), "')' expected"); 1295 return MatchOperand_ParseFail; 1296 } 1297 1298 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1299 1300 Parser.Lex(); // Eat the ')' token. 1301 1302 if (IdVal == 0) 1303 IdVal = MCConstantExpr::Create(0, getContext()); 1304 1305 // Replace the register operand with the memory operand. 1306 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1307 int RegNo = op->getReg(); 1308 // Remove the register from the operands. 1309 Operands.pop_back(); 1310 // Add the memory operand. 1311 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 1312 int64_t Imm; 1313 if (IdVal->EvaluateAsAbsolute(Imm)) 1314 IdVal = MCConstantExpr::Create(Imm, getContext()); 1315 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 1316 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 1317 getContext()); 1318 } 1319 1320 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E)); 1321 delete op; 1322 return MatchOperand_Success; 1323} 1324 1325bool 1326MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1327 int RegKind) { 1328 // If the first token is not '$' we have an error. 1329 if (Parser.getTok().isNot(AsmToken::Dollar)) 1330 return false; 1331 1332 SMLoc S = Parser.getTok().getLoc(); 1333 Parser.Lex(); 1334 AsmToken::TokenKind TkKind = getLexer().getKind(); 1335 int Reg; 1336 1337 if (TkKind == AsmToken::Integer) { 1338 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(), 1339 regKindToRegClass(RegKind)); 1340 if (Reg == -1) 1341 return false; 1342 } else if (TkKind == AsmToken::Identifier) { 1343 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1) 1344 return false; 1345 Reg = getReg(regKindToRegClass(RegKind), Reg); 1346 } else { 1347 return false; 1348 } 1349 1350 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc()); 1351 Op->setRegKind((MipsOperand::RegisterKind)RegKind); 1352 Operands.push_back(Op); 1353 Parser.Lex(); 1354 return true; 1355} 1356 1357MipsAsmParser::OperandMatchResultTy 1358MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1359 MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 : 1360 MipsOperand::Kind_GPR32; 1361 1362 // Parse index register. 1363 if (!parsePtrReg(Operands, RegKind)) 1364 return MatchOperand_NoMatch; 1365 1366 // Parse '('. 1367 if (Parser.getTok().isNot(AsmToken::LParen)) 1368 return MatchOperand_NoMatch; 1369 1370 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc())); 1371 Parser.Lex(); 1372 1373 // Parse base register. 1374 if (!parsePtrReg(Operands, RegKind)) 1375 return MatchOperand_NoMatch; 1376 1377 // Parse ')'. 1378 if (Parser.getTok().isNot(AsmToken::RParen)) 1379 return MatchOperand_NoMatch; 1380 1381 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc())); 1382 Parser.Lex(); 1383 1384 return MatchOperand_Success; 1385} 1386 1387MipsAsmParser::OperandMatchResultTy 1388MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1389 int RegKind) { 1390 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind; 1391 if (getLexer().getKind() == AsmToken::Identifier 1392 && !hasConsumedDollar) { 1393 if (searchSymbolAlias(Operands, Kind)) 1394 return MatchOperand_Success; 1395 return MatchOperand_NoMatch; 1396 } 1397 SMLoc S = Parser.getTok().getLoc(); 1398 // If the first token is not '$', we have an error. 1399 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar) 1400 return MatchOperand_NoMatch; 1401 if (!hasConsumedDollar) { 1402 Parser.Lex(); // Eat the '$' 1403 hasConsumedDollar = true; 1404 } 1405 if (getLexer().getKind() == AsmToken::Identifier) { 1406 int RegNum = -1; 1407 std::string RegName = Parser.getTok().getString().lower(); 1408 // Match register by name 1409 switch (RegKind) { 1410 case MipsOperand::Kind_GPR32: 1411 case MipsOperand::Kind_GPR64: 1412 RegNum = matchCPURegisterName(RegName); 1413 break; 1414 case MipsOperand::Kind_AFGR64Regs: 1415 case MipsOperand::Kind_FGR64Regs: 1416 case MipsOperand::Kind_FGR32Regs: 1417 case MipsOperand::Kind_FGRH32Regs: 1418 RegNum = matchFPURegisterName(RegName); 1419 if (RegKind == MipsOperand::Kind_AFGR64Regs) 1420 RegNum /= 2; 1421 else if (RegKind == MipsOperand::Kind_FGRH32Regs 1422 && !isFP64()) 1423 if (RegNum != -1 && RegNum %2 != 0) 1424 Warning(S, "Float register should be even."); 1425 break; 1426 case MipsOperand::Kind_FCCRegs: 1427 RegNum = matchFCCRegisterName(RegName); 1428 break; 1429 case MipsOperand::Kind_ACC64DSP: 1430 RegNum = matchACRegisterName(RegName); 1431 break; 1432 default: break; // No match, value is set to -1. 1433 } 1434 // No match found, return _NoMatch to give a chance to other round. 1435 if (RegNum < 0) 1436 return MatchOperand_NoMatch; 1437 1438 int RegVal = getReg(regKindToRegClass(Kind), RegNum); 1439 if (RegVal == -1) 1440 return MatchOperand_NoMatch; 1441 1442 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, 1443 Parser.getTok().getLoc()); 1444 Op->setRegKind(Kind); 1445 Operands.push_back(Op); 1446 hasConsumedDollar = false; 1447 Parser.Lex(); // Eat the register name. 1448 return MatchOperand_Success; 1449 } else if (getLexer().getKind() == AsmToken::Integer) { 1450 unsigned RegNum = Parser.getTok().getIntVal(); 1451 if (Kind == MipsOperand::Kind_HWRegs) { 1452 if (RegNum != 29) 1453 return MatchOperand_NoMatch; 1454 // Only hwreg 29 is supported, found at index 0. 1455 RegNum = 0; 1456 } 1457 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind)); 1458 if (Reg == -1) 1459 return MatchOperand_NoMatch; 1460 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1461 Op->setRegKind(Kind); 1462 Operands.push_back(Op); 1463 hasConsumedDollar = false; 1464 Parser.Lex(); // Eat the register number. 1465 if ((RegKind == MipsOperand::Kind_GPR32) 1466 && (getLexer().is(AsmToken::LParen))) { 1467 // Check if it is indexed addressing operand. 1468 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc())); 1469 Parser.Lex(); // Eat the parenthesis. 1470 if (parseRegs(Operands,RegKind) != MatchOperand_Success) 1471 return MatchOperand_NoMatch; 1472 if (getLexer().isNot(AsmToken::RParen)) 1473 return MatchOperand_NoMatch; 1474 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc())); 1475 Parser.Lex(); 1476 } 1477 return MatchOperand_Success; 1478 } 1479 return MatchOperand_NoMatch; 1480} 1481 1482MipsAsmParser::OperandMatchResultTy 1483MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1484 1485 if (!isMips64()) 1486 return MatchOperand_NoMatch; 1487 return parseRegs(Operands, (int) MipsOperand::Kind_GPR64); 1488} 1489 1490MipsAsmParser::OperandMatchResultTy 1491MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1492 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32); 1493} 1494 1495MipsAsmParser::OperandMatchResultTy 1496MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1497 1498 if (isFP64()) 1499 return MatchOperand_NoMatch; 1500 return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs); 1501} 1502 1503MipsAsmParser::OperandMatchResultTy 1504MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1505 if (!isFP64()) 1506 return MatchOperand_NoMatch; 1507 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs); 1508} 1509 1510MipsAsmParser::OperandMatchResultTy 1511MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1512 return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs); 1513} 1514 1515MipsAsmParser::OperandMatchResultTy 1516MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1517 return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs); 1518} 1519 1520MipsAsmParser::OperandMatchResultTy 1521MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1522 return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs); 1523} 1524 1525MipsAsmParser::OperandMatchResultTy 1526MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1527 return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP); 1528} 1529 1530MipsAsmParser::OperandMatchResultTy 1531MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1532 // If the first token is not '$' we have an error. 1533 if (Parser.getTok().isNot(AsmToken::Dollar)) 1534 return MatchOperand_NoMatch; 1535 1536 SMLoc S = Parser.getTok().getLoc(); 1537 Parser.Lex(); // Eat the '$' 1538 1539 const AsmToken &Tok = Parser.getTok(); // Get next token. 1540 1541 if (Tok.isNot(AsmToken::Identifier)) 1542 return MatchOperand_NoMatch; 1543 1544 if (!Tok.getIdentifier().startswith("ac")) 1545 return MatchOperand_NoMatch; 1546 1547 StringRef NumString = Tok.getIdentifier().substr(2); 1548 1549 unsigned IntVal; 1550 if (NumString.getAsInteger(10, IntVal)) 1551 return MatchOperand_NoMatch; 1552 1553 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID); 1554 1555 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1556 Op->setRegKind(MipsOperand::Kind_LO32DSP); 1557 Operands.push_back(Op); 1558 1559 Parser.Lex(); // Eat the register number. 1560 return MatchOperand_Success; 1561} 1562 1563MipsAsmParser::OperandMatchResultTy 1564MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1565 // If the first token is not '$' we have an error. 1566 if (Parser.getTok().isNot(AsmToken::Dollar)) 1567 return MatchOperand_NoMatch; 1568 1569 SMLoc S = Parser.getTok().getLoc(); 1570 Parser.Lex(); // Eat the '$' 1571 1572 const AsmToken &Tok = Parser.getTok(); // Get next token. 1573 1574 if (Tok.isNot(AsmToken::Identifier)) 1575 return MatchOperand_NoMatch; 1576 1577 if (!Tok.getIdentifier().startswith("ac")) 1578 return MatchOperand_NoMatch; 1579 1580 StringRef NumString = Tok.getIdentifier().substr(2); 1581 1582 unsigned IntVal; 1583 if (NumString.getAsInteger(10, IntVal)) 1584 return MatchOperand_NoMatch; 1585 1586 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID); 1587 1588 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1589 Op->setRegKind(MipsOperand::Kind_HI32DSP); 1590 Operands.push_back(Op); 1591 1592 Parser.Lex(); // Eat the register number. 1593 return MatchOperand_Success; 1594} 1595 1596MipsAsmParser::OperandMatchResultTy 1597MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1598 // If the first token is not '$' we have an error. 1599 if (Parser.getTok().isNot(AsmToken::Dollar)) 1600 return MatchOperand_NoMatch; 1601 1602 SMLoc S = Parser.getTok().getLoc(); 1603 Parser.Lex(); // Eat the '$' 1604 1605 const AsmToken &Tok = Parser.getTok(); // Get next token. 1606 1607 if (Tok.isNot(AsmToken::Integer)) 1608 return MatchOperand_NoMatch; 1609 1610 unsigned IntVal = Tok.getIntVal(); 1611 1612 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID); 1613 1614 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1615 Op->setRegKind(MipsOperand::Kind_COP2); 1616 Operands.push_back(Op); 1617 1618 Parser.Lex(); // Eat the register number. 1619 return MatchOperand_Success; 1620} 1621 1622bool MipsAsmParser::searchSymbolAlias( 1623 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) { 1624 1625 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 1626 if (Sym) { 1627 SMLoc S = Parser.getTok().getLoc(); 1628 const MCExpr *Expr; 1629 if (Sym->isVariable()) 1630 Expr = Sym->getVariableValue(); 1631 else 1632 return false; 1633 if (Expr->getKind() == MCExpr::SymbolRef) { 1634 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind; 1635 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 1636 const StringRef DefSymbol = Ref->getSymbol().getName(); 1637 if (DefSymbol.startswith("$")) { 1638 int RegNum = -1; 1639 APInt IntVal(32, -1); 1640 if (!DefSymbol.substr(1).getAsInteger(10, IntVal)) 1641 RegNum = matchRegisterByNumber(IntVal.getZExtValue(), 1642 isMips64() 1643 ? Mips::GPR64RegClassID 1644 : Mips::GPR32RegClassID); 1645 else { 1646 // Lookup for the register with the corresponding name. 1647 switch (Kind) { 1648 case MipsOperand::Kind_AFGR64Regs: 1649 case MipsOperand::Kind_FGR64Regs: 1650 RegNum = matchFPURegisterName(DefSymbol.substr(1)); 1651 break; 1652 case MipsOperand::Kind_FGR32Regs: 1653 RegNum = matchFPURegisterName(DefSymbol.substr(1)); 1654 break; 1655 case MipsOperand::Kind_GPR64: 1656 case MipsOperand::Kind_GPR32: 1657 default: 1658 RegNum = matchCPURegisterName(DefSymbol.substr(1)); 1659 break; 1660 } 1661 if (RegNum > -1) 1662 RegNum = getReg(regKindToRegClass(Kind), RegNum); 1663 } 1664 if (RegNum > -1) { 1665 Parser.Lex(); 1666 MipsOperand *op = MipsOperand::CreateReg(RegNum, S, 1667 Parser.getTok().getLoc()); 1668 op->setRegKind(Kind); 1669 Operands.push_back(op); 1670 return true; 1671 } 1672 } 1673 } else if (Expr->getKind() == MCExpr::Constant) { 1674 Parser.Lex(); 1675 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr); 1676 MipsOperand *op = MipsOperand::CreateImm(Const, S, 1677 Parser.getTok().getLoc()); 1678 Operands.push_back(op); 1679 return true; 1680 } 1681 } 1682 return false; 1683} 1684 1685MipsAsmParser::OperandMatchResultTy 1686MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1687 return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs); 1688} 1689 1690MipsAsmParser::OperandMatchResultTy 1691MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1692 return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs); 1693} 1694 1695MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 1696 1697 MCSymbolRefExpr::VariantKind VK 1698 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 1699 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 1700 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 1701 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 1702 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 1703 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 1704 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 1705 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 1706 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 1707 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 1708 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 1709 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 1710 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 1711 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 1712 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 1713 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 1714 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 1715 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 1716 .Default(MCSymbolRefExpr::VK_None); 1717 1718 return VK; 1719} 1720 1721bool MipsAsmParser:: 1722ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 1723 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1724 // Check if we have valid mnemonic 1725 if (!mnemonicIsValid(Name, 0)) { 1726 Parser.eatToEndOfStatement(); 1727 return Error(NameLoc, "Unknown instruction"); 1728 } 1729 // First operand in MCInst is instruction mnemonic. 1730 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 1731 1732 // Read the remaining operands. 1733 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1734 // Read the first operand. 1735 if (ParseOperand(Operands, Name)) { 1736 SMLoc Loc = getLexer().getLoc(); 1737 Parser.eatToEndOfStatement(); 1738 return Error(Loc, "unexpected token in argument list"); 1739 } 1740 1741 while (getLexer().is(AsmToken::Comma)) { 1742 Parser.Lex(); // Eat the comma. 1743 // Parse and remember the operand. 1744 if (ParseOperand(Operands, Name)) { 1745 SMLoc Loc = getLexer().getLoc(); 1746 Parser.eatToEndOfStatement(); 1747 return Error(Loc, "unexpected token in argument list"); 1748 } 1749 } 1750 } 1751 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1752 SMLoc Loc = getLexer().getLoc(); 1753 Parser.eatToEndOfStatement(); 1754 return Error(Loc, "unexpected token in argument list"); 1755 } 1756 Parser.Lex(); // Consume the EndOfStatement. 1757 return false; 1758} 1759 1760bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 1761 SMLoc Loc = getLexer().getLoc(); 1762 Parser.eatToEndOfStatement(); 1763 return Error(Loc, ErrorMsg); 1764} 1765 1766bool MipsAsmParser::parseSetNoAtDirective() { 1767 // Line should look like: ".set noat". 1768 // set at reg to 0. 1769 Options.setATReg(0); 1770 // eat noat 1771 Parser.Lex(); 1772 // If this is not the end of the statement, report an error. 1773 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1774 reportParseError("unexpected token in statement"); 1775 return false; 1776 } 1777 Parser.Lex(); // Consume the EndOfStatement. 1778 return false; 1779} 1780 1781bool MipsAsmParser::parseSetAtDirective() { 1782 // Line can be .set at - defaults to $1 1783 // or .set at=$reg 1784 int AtRegNo; 1785 getParser().Lex(); 1786 if (getLexer().is(AsmToken::EndOfStatement)) { 1787 Options.setATReg(1); 1788 Parser.Lex(); // Consume the EndOfStatement. 1789 return false; 1790 } else if (getLexer().is(AsmToken::Equal)) { 1791 getParser().Lex(); // Eat the '='. 1792 if (getLexer().isNot(AsmToken::Dollar)) { 1793 reportParseError("unexpected token in statement"); 1794 return false; 1795 } 1796 Parser.Lex(); // Eat the '$'. 1797 const AsmToken &Reg = Parser.getTok(); 1798 if (Reg.is(AsmToken::Identifier)) { 1799 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 1800 } else if (Reg.is(AsmToken::Integer)) { 1801 AtRegNo = Reg.getIntVal(); 1802 } else { 1803 reportParseError("unexpected token in statement"); 1804 return false; 1805 } 1806 1807 if (AtRegNo < 1 || AtRegNo > 31) { 1808 reportParseError("unexpected token in statement"); 1809 return false; 1810 } 1811 1812 if (!Options.setATReg(AtRegNo)) { 1813 reportParseError("unexpected token in statement"); 1814 return false; 1815 } 1816 getParser().Lex(); // Eat the register. 1817 1818 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1819 reportParseError("unexpected token in statement"); 1820 return false; 1821 } 1822 Parser.Lex(); // Consume the EndOfStatement. 1823 return false; 1824 } else { 1825 reportParseError("unexpected token in statement"); 1826 return false; 1827 } 1828} 1829 1830bool MipsAsmParser::parseSetReorderDirective() { 1831 Parser.Lex(); 1832 // If this is not the end of the statement, report an error. 1833 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1834 reportParseError("unexpected token in statement"); 1835 return false; 1836 } 1837 Options.setReorder(); 1838 Parser.Lex(); // Consume the EndOfStatement. 1839 return false; 1840} 1841 1842bool MipsAsmParser::parseSetNoReorderDirective() { 1843 Parser.Lex(); 1844 // If this is not the end of the statement, report an error. 1845 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1846 reportParseError("unexpected token in statement"); 1847 return false; 1848 } 1849 Options.setNoreorder(); 1850 Parser.Lex(); // Consume the EndOfStatement. 1851 return false; 1852} 1853 1854bool MipsAsmParser::parseSetMacroDirective() { 1855 Parser.Lex(); 1856 // If this is not the end of the statement, report an error. 1857 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1858 reportParseError("unexpected token in statement"); 1859 return false; 1860 } 1861 Options.setMacro(); 1862 Parser.Lex(); // Consume the EndOfStatement. 1863 return false; 1864} 1865 1866bool MipsAsmParser::parseSetNoMacroDirective() { 1867 Parser.Lex(); 1868 // If this is not the end of the statement, report an error. 1869 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1870 reportParseError("`noreorder' must be set before `nomacro'"); 1871 return false; 1872 } 1873 if (Options.isReorder()) { 1874 reportParseError("`noreorder' must be set before `nomacro'"); 1875 return false; 1876 } 1877 Options.setNomacro(); 1878 Parser.Lex(); // Consume the EndOfStatement. 1879 return false; 1880} 1881 1882bool MipsAsmParser::parseSetAssignment() { 1883 StringRef Name; 1884 const MCExpr *Value; 1885 1886 if (Parser.parseIdentifier(Name)) 1887 reportParseError("expected identifier after .set"); 1888 1889 if (getLexer().isNot(AsmToken::Comma)) 1890 return reportParseError("unexpected token in .set directive"); 1891 Lex(); // Eat comma 1892 1893 if (getLexer().is(AsmToken::Dollar)) { 1894 MCSymbol *Symbol; 1895 SMLoc DollarLoc = getLexer().getLoc(); 1896 // Consume the dollar sign, and check for a following identifier. 1897 Parser.Lex(); 1898 // We have a '$' followed by something, make sure they are adjacent. 1899 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer()) 1900 return true; 1901 StringRef Res = StringRef(DollarLoc.getPointer(), 1902 getTok().getEndLoc().getPointer() - DollarLoc.getPointer()); 1903 Symbol = getContext().GetOrCreateSymbol(Res); 1904 Parser.Lex(); 1905 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, 1906 getContext()); 1907 } else if (Parser.parseExpression(Value)) 1908 return reportParseError("expected valid expression after comma"); 1909 1910 // Check if the Name already exists as a symbol. 1911 MCSymbol *Sym = getContext().LookupSymbol(Name); 1912 if (Sym) 1913 return reportParseError("symbol already defined"); 1914 Sym = getContext().GetOrCreateSymbol(Name); 1915 Sym->setVariableValue(Value); 1916 1917 return false; 1918} 1919 1920bool MipsAsmParser::parseDirectiveSet() { 1921 1922 // Get the next token. 1923 const AsmToken &Tok = Parser.getTok(); 1924 1925 if (Tok.getString() == "noat") { 1926 return parseSetNoAtDirective(); 1927 } else if (Tok.getString() == "at") { 1928 return parseSetAtDirective(); 1929 } else if (Tok.getString() == "reorder") { 1930 return parseSetReorderDirective(); 1931 } else if (Tok.getString() == "noreorder") { 1932 return parseSetNoReorderDirective(); 1933 } else if (Tok.getString() == "macro") { 1934 return parseSetMacroDirective(); 1935 } else if (Tok.getString() == "nomacro") { 1936 return parseSetNoMacroDirective(); 1937 } else if (Tok.getString() == "nomips16") { 1938 // Ignore this directive for now. 1939 Parser.eatToEndOfStatement(); 1940 return false; 1941 } else if (Tok.getString() == "nomicromips") { 1942 // Ignore this directive for now. 1943 Parser.eatToEndOfStatement(); 1944 return false; 1945 } else { 1946 // It is just an identifier, look for an assignment. 1947 parseSetAssignment(); 1948 return false; 1949 } 1950 1951 return true; 1952} 1953 1954/// parseDirectiveWord 1955/// ::= .word [ expression (, expression)* ] 1956bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 1957 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1958 for (;;) { 1959 const MCExpr *Value; 1960 if (getParser().parseExpression(Value)) 1961 return true; 1962 1963 getParser().getStreamer().EmitValue(Value, Size); 1964 1965 if (getLexer().is(AsmToken::EndOfStatement)) 1966 break; 1967 1968 // FIXME: Improve diagnostic. 1969 if (getLexer().isNot(AsmToken::Comma)) 1970 return Error(L, "unexpected token in directive"); 1971 Parser.Lex(); 1972 } 1973 } 1974 1975 Parser.Lex(); 1976 return false; 1977} 1978 1979bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 1980 1981 StringRef IDVal = DirectiveID.getString(); 1982 1983 if (IDVal == ".ent") { 1984 // Ignore this directive for now. 1985 Parser.Lex(); 1986 return false; 1987 } 1988 1989 if (IDVal == ".end") { 1990 // Ignore this directive for now. 1991 Parser.Lex(); 1992 return false; 1993 } 1994 1995 if (IDVal == ".frame") { 1996 // Ignore this directive for now. 1997 Parser.eatToEndOfStatement(); 1998 return false; 1999 } 2000 2001 if (IDVal == ".set") { 2002 return parseDirectiveSet(); 2003 } 2004 2005 if (IDVal == ".fmask") { 2006 // Ignore this directive for now. 2007 Parser.eatToEndOfStatement(); 2008 return false; 2009 } 2010 2011 if (IDVal == ".mask") { 2012 // Ignore this directive for now. 2013 Parser.eatToEndOfStatement(); 2014 return false; 2015 } 2016 2017 if (IDVal == ".gpword") { 2018 // Ignore this directive for now. 2019 Parser.eatToEndOfStatement(); 2020 return false; 2021 } 2022 2023 if (IDVal == ".word") { 2024 parseDirectiveWord(4, DirectiveID.getLoc()); 2025 return false; 2026 } 2027 2028 return true; 2029} 2030 2031extern "C" void LLVMInitializeMipsAsmParser() { 2032 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 2033 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 2034 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 2035 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 2036} 2037 2038#define GET_REGISTER_MATCHER 2039#define GET_MATCHER_IMPLEMENTATION 2040#include "MipsGenAsmMatcher.inc" 2041