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