MipsAsmParser.cpp revision b8145e3881872fffbac15693c94536446f060330
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 if (Name.equals("fcc0")) 782 return Mips::FCC0; 783 784 int CC; 785 CC = matchCPURegisterName(Name); 786 if (CC != -1) 787 return matchRegisterByNumber(CC,is64BitReg?Mips::CPU64RegsRegClassID: 788 Mips::CPURegsRegClassID); 789 790 if (Name[0] == 'f') { 791 StringRef NumString = Name.substr(1); 792 unsigned IntVal; 793 if( NumString.getAsInteger(10, IntVal)) 794 return -1; // not integer 795 if (IntVal > 31) 796 return -1; 797 798 FpFormatTy Format = getFpFormat(); 799 800 if (Format == FP_FORMAT_S || Format == FP_FORMAT_W) 801 return getReg(Mips::FGR32RegClassID, IntVal); 802 if (Format == FP_FORMAT_D) { 803 if(isFP64()) { 804 return getReg(Mips::FGR64RegClassID, IntVal); 805 } 806 // only even numbers available as register pairs 807 if (( IntVal > 31) || (IntVal%2 != 0)) 808 return -1; 809 return getReg(Mips::AFGR64RegClassID, IntVal/2); 810 } 811 } 812 813 return -1; 814} 815void MipsAsmParser::setDefaultFpFormat() { 816 817 if (isMips64() || isFP64()) 818 FpFormat = FP_FORMAT_D; 819 else 820 FpFormat = FP_FORMAT_S; 821} 822 823bool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){ 824 825 bool IsDouble = StringSwitch<bool>(Mnemonic.lower()) 826 .Case("ldxc1", true) 827 .Case("ldc1", true) 828 .Case("sdxc1", true) 829 .Case("sdc1", true) 830 .Default(false); 831 832 return IsDouble; 833} 834void MipsAsmParser::setFpFormat(StringRef Format) { 835 836 FpFormat = StringSwitch<FpFormatTy>(Format.lower()) 837 .Case(".s", FP_FORMAT_S) 838 .Case(".d", FP_FORMAT_D) 839 .Case(".l", FP_FORMAT_L) 840 .Case(".w", FP_FORMAT_W) 841 .Default(FP_FORMAT_NONE); 842} 843 844bool MipsAssemblerOptions::setATReg(unsigned Reg) { 845 if (Reg > 31) 846 return false; 847 848 aTReg = Reg; 849 return true; 850} 851 852int MipsAsmParser::getATReg() { 853 return Options.getATRegNum(); 854} 855 856unsigned MipsAsmParser::getReg(int RC,int RegNo) { 857 return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo); 858} 859 860int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 861 862 if (RegNum > 31) 863 return -1; 864 865 return getReg(RegClass, RegNum); 866} 867 868int MipsAsmParser::tryParseRegister(bool is64BitReg) { 869 const AsmToken &Tok = Parser.getTok(); 870 int RegNum = -1; 871 872 if (Tok.is(AsmToken::Identifier)) { 873 std::string lowerCase = Tok.getString().lower(); 874 RegNum = matchRegisterName(lowerCase, is64BitReg); 875 } else if (Tok.is(AsmToken::Integer)) 876 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()), 877 is64BitReg ? Mips::CPU64RegsRegClassID 878 : Mips::CPURegsRegClassID); 879 return RegNum; 880} 881 882bool MipsAsmParser:: 883 tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 884 bool is64BitReg){ 885 886 SMLoc S = Parser.getTok().getLoc(); 887 int RegNo = -1; 888 889 RegNo = tryParseRegister(is64BitReg); 890 if (RegNo == -1) 891 return true; 892 893 Operands.push_back(MipsOperand::CreateReg(RegNo, S, 894 Parser.getTok().getLoc())); 895 Parser.Lex(); // Eat register token. 896 return false; 897} 898 899bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands, 900 StringRef Mnemonic) { 901 // Check if the current operand has a custom associated parser, if so, try to 902 // custom parse the operand, or fallback to the general approach. 903 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 904 if (ResTy == MatchOperand_Success) 905 return false; 906 // If there wasn't a custom match, try the generic matcher below. Otherwise, 907 // there was a match, but an error occurred, in which case, just return that 908 // the operand parsing failed. 909 if (ResTy == MatchOperand_ParseFail) 910 return true; 911 912 switch (getLexer().getKind()) { 913 default: 914 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 915 return true; 916 case AsmToken::Dollar: { 917 // parse register 918 SMLoc S = Parser.getTok().getLoc(); 919 Parser.Lex(); // Eat dollar token. 920 // parse register operand 921 if (!tryParseRegisterOperand(Operands, isMips64())) { 922 if (getLexer().is(AsmToken::LParen)) { 923 // check if it is indexed addressing operand 924 Operands.push_back(MipsOperand::CreateToken("(", S)); 925 Parser.Lex(); // eat parenthesis 926 if (getLexer().isNot(AsmToken::Dollar)) 927 return true; 928 929 Parser.Lex(); // eat dollar 930 if (tryParseRegisterOperand(Operands, isMips64())) 931 return true; 932 933 if (!getLexer().is(AsmToken::RParen)) 934 return true; 935 936 S = Parser.getTok().getLoc(); 937 Operands.push_back(MipsOperand::CreateToken(")", S)); 938 Parser.Lex(); 939 } 940 return false; 941 } 942 // maybe it is a symbol reference 943 StringRef Identifier; 944 if (Parser.parseIdentifier(Identifier)) 945 return true; 946 947 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 948 949 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 950 951 // Otherwise create a symbol ref. 952 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 953 getContext()); 954 955 Operands.push_back(MipsOperand::CreateImm(Res, S, E)); 956 return false; 957 } 958 case AsmToken::Identifier: 959 // Look for the existing symbol, we should check if 960 // we need to assigne the propper RegisterKind 961 if (searchSymbolAlias(Operands,MipsOperand::Kind_None)) 962 return false; 963 //else drop to expression parsing 964 case AsmToken::LParen: 965 case AsmToken::Minus: 966 case AsmToken::Plus: 967 case AsmToken::Integer: 968 case AsmToken::String: { 969 // quoted label names 970 const MCExpr *IdVal; 971 SMLoc S = Parser.getTok().getLoc(); 972 if (getParser().parseExpression(IdVal)) 973 return true; 974 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 975 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 976 return false; 977 } 978 case AsmToken::Percent: { 979 // it is a symbol reference or constant expression 980 const MCExpr *IdVal; 981 SMLoc S = Parser.getTok().getLoc(); // start location of the operand 982 if (parseRelocOperand(IdVal)) 983 return true; 984 985 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 986 987 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 988 return false; 989 } // case AsmToken::Percent 990 } // switch(getLexer().getKind()) 991 return true; 992} 993 994bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 995 996 Parser.Lex(); // eat % token 997 const AsmToken &Tok = Parser.getTok(); // get next token, operation 998 if (Tok.isNot(AsmToken::Identifier)) 999 return true; 1000 1001 std::string Str = Tok.getIdentifier().str(); 1002 1003 Parser.Lex(); // eat identifier 1004 // now make expression from the rest of the operand 1005 const MCExpr *IdVal; 1006 SMLoc EndLoc; 1007 1008 if (getLexer().getKind() == AsmToken::LParen) { 1009 while (1) { 1010 Parser.Lex(); // eat '(' token 1011 if (getLexer().getKind() == AsmToken::Percent) { 1012 Parser.Lex(); // eat % token 1013 const AsmToken &nextTok = Parser.getTok(); 1014 if (nextTok.isNot(AsmToken::Identifier)) 1015 return true; 1016 Str += "(%"; 1017 Str += nextTok.getIdentifier(); 1018 Parser.Lex(); // eat identifier 1019 if (getLexer().getKind() != AsmToken::LParen) 1020 return true; 1021 } else 1022 break; 1023 } 1024 if (getParser().parseParenExpression(IdVal,EndLoc)) 1025 return true; 1026 1027 while (getLexer().getKind() == AsmToken::RParen) 1028 Parser.Lex(); // eat ')' token 1029 1030 } else 1031 return true; // parenthesis must follow reloc operand 1032 1033 // Check the type of the expression 1034 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) { 1035 // It's a constant, evaluate lo or hi value 1036 if (Str == "lo") { 1037 short Val = MCE->getValue(); 1038 Res = MCConstantExpr::Create(Val, getContext()); 1039 } else if (Str == "hi") { 1040 int Val = MCE->getValue(); 1041 int LoSign = Val & 0x8000; 1042 Val = (Val & 0xffff0000) >> 16; 1043 // Lower part is treated as a signed int, so if it is negative 1044 // we must add 1 to the hi part to compensate 1045 if (LoSign) 1046 Val++; 1047 Res = MCConstantExpr::Create(Val, getContext()); 1048 } 1049 return false; 1050 } 1051 1052 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) { 1053 // It's a symbol, create symbolic expression from symbol 1054 StringRef Symbol = MSRE->getSymbol().getName(); 1055 MCSymbolRefExpr::VariantKind VK = getVariantKind(Str); 1056 Res = MCSymbolRefExpr::Create(Symbol,VK,getContext()); 1057 return false; 1058 } 1059 return true; 1060} 1061 1062bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1063 SMLoc &EndLoc) { 1064 1065 StartLoc = Parser.getTok().getLoc(); 1066 RegNo = tryParseRegister(isMips64()); 1067 EndLoc = Parser.getTok().getLoc(); 1068 return (RegNo == (unsigned)-1); 1069} 1070 1071bool MipsAsmParser::parseMemOffset(const MCExpr *&Res) { 1072 1073 SMLoc S; 1074 1075 switch(getLexer().getKind()) { 1076 default: 1077 return true; 1078 case AsmToken::Identifier: 1079 case AsmToken::Integer: 1080 case AsmToken::Minus: 1081 case AsmToken::Plus: 1082 return (getParser().parseExpression(Res)); 1083 case AsmToken::Percent: 1084 return parseRelocOperand(Res); 1085 case AsmToken::LParen: 1086 return false; // it's probably assuming 0 1087 } 1088 return true; 1089} 1090 1091MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( 1092 SmallVectorImpl<MCParsedAsmOperand*>&Operands) { 1093 1094 const MCExpr *IdVal = 0; 1095 SMLoc S; 1096 // first operand is the offset 1097 S = Parser.getTok().getLoc(); 1098 1099 if (parseMemOffset(IdVal)) 1100 return MatchOperand_ParseFail; 1101 1102 const AsmToken &Tok = Parser.getTok(); // get next token 1103 if (Tok.isNot(AsmToken::LParen)) { 1104 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]); 1105 if (Mnemonic->getToken() == "la") { 1106 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() -1); 1107 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 1108 return MatchOperand_Success; 1109 } 1110 Error(Parser.getTok().getLoc(), "'(' expected"); 1111 return MatchOperand_ParseFail; 1112 } 1113 1114 Parser.Lex(); // Eat '(' token. 1115 1116 const AsmToken &Tok1 = Parser.getTok(); // get next token 1117 if (Tok1.is(AsmToken::Dollar)) { 1118 Parser.Lex(); // Eat '$' token. 1119 if (tryParseRegisterOperand(Operands, isMips64())) { 1120 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 1121 return MatchOperand_ParseFail; 1122 } 1123 1124 } else { 1125 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 1126 return MatchOperand_ParseFail; 1127 } 1128 1129 const AsmToken &Tok2 = Parser.getTok(); // get next token 1130 if (Tok2.isNot(AsmToken::RParen)) { 1131 Error(Parser.getTok().getLoc(), "')' expected"); 1132 return MatchOperand_ParseFail; 1133 } 1134 1135 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1136 1137 Parser.Lex(); // Eat ')' token. 1138 1139 if (IdVal == 0) 1140 IdVal = MCConstantExpr::Create(0, getContext()); 1141 1142 // now replace register operand with the mem operand 1143 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1144 int RegNo = op->getReg(); 1145 // remove register from operands 1146 Operands.pop_back(); 1147 // and add memory operand 1148 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E)); 1149 delete op; 1150 return MatchOperand_Success; 1151} 1152 1153MipsAsmParser::OperandMatchResultTy 1154MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1155 1156 if (!isMips64()) 1157 return MatchOperand_NoMatch; 1158 if (getLexer().getKind() == AsmToken::Identifier) { 1159 if (searchSymbolAlias(Operands,MipsOperand::Kind_CPU64Regs)) 1160 return MatchOperand_Success; 1161 return MatchOperand_NoMatch; 1162 } 1163 // if the first token is not '$' we have an error 1164 if (Parser.getTok().isNot(AsmToken::Dollar)) 1165 return MatchOperand_NoMatch; 1166 1167 Parser.Lex(); // Eat $ 1168 if(!tryParseRegisterOperand(Operands, true)) { 1169 // set the proper register kind 1170 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1171 op->setRegKind(MipsOperand::Kind_CPU64Regs); 1172 return MatchOperand_Success; 1173 } 1174 return MatchOperand_NoMatch; 1175} 1176 1177bool MipsAsmParser:: 1178searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 1179 unsigned RegisterKind) { 1180 1181 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 1182 if (Sym) { 1183 SMLoc S = Parser.getTok().getLoc(); 1184 const MCExpr *Expr; 1185 if (Sym->isVariable()) 1186 Expr = Sym->getVariableValue(); 1187 else 1188 return false; 1189 if (Expr->getKind() == MCExpr::SymbolRef) { 1190 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 1191 const StringRef DefSymbol = Ref->getSymbol().getName(); 1192 if (DefSymbol.startswith("$")) { 1193 // Lookup for the register with corresponding name 1194 int RegNum = matchRegisterName(DefSymbol.substr(1),isMips64()); 1195 if (RegNum > -1) { 1196 Parser.Lex(); 1197 MipsOperand *op = MipsOperand::CreateReg(RegNum,S, 1198 Parser.getTok().getLoc()); 1199 op->setRegKind((MipsOperand::RegisterKind)RegisterKind); 1200 Operands.push_back(op); 1201 return true; 1202 } 1203 } 1204 } else if (Expr->getKind() == MCExpr::Constant) { 1205 Parser.Lex(); 1206 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr); 1207 MipsOperand *op = MipsOperand::CreateImm(Const,S, 1208 Parser.getTok().getLoc()); 1209 Operands.push_back(op); 1210 return true; 1211 } 1212 } 1213 return false; 1214} 1215MipsAsmParser::OperandMatchResultTy 1216MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1217 1218 if (getLexer().getKind() == AsmToken::Identifier) { 1219 if (searchSymbolAlias(Operands,MipsOperand::Kind_CPURegs)) 1220 return MatchOperand_Success; 1221 return MatchOperand_NoMatch; 1222 } 1223 // if the first token is not '$' we have an error 1224 if (Parser.getTok().isNot(AsmToken::Dollar)) 1225 return MatchOperand_NoMatch; 1226 1227 Parser.Lex(); // Eat $ 1228 if(!tryParseRegisterOperand(Operands, false)) { 1229 // set the propper register kind 1230 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1231 op->setRegKind(MipsOperand::Kind_CPURegs); 1232 return MatchOperand_Success; 1233 } 1234 return MatchOperand_NoMatch; 1235} 1236 1237MipsAsmParser::OperandMatchResultTy 1238MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1239 1240 if (isMips64()) 1241 return MatchOperand_NoMatch; 1242 1243 // if the first token is not '$' we have error 1244 if (Parser.getTok().isNot(AsmToken::Dollar)) 1245 return MatchOperand_NoMatch; 1246 SMLoc S = Parser.getTok().getLoc(); 1247 Parser.Lex(); // Eat $ 1248 1249 const AsmToken &Tok = Parser.getTok(); // get next token 1250 if (Tok.isNot(AsmToken::Integer)) 1251 return MatchOperand_NoMatch; 1252 1253 unsigned RegNum = Tok.getIntVal(); 1254 // at the moment only hwreg29 is supported 1255 if (RegNum != 29) 1256 return MatchOperand_ParseFail; 1257 1258 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S, 1259 Parser.getTok().getLoc()); 1260 op->setRegKind(MipsOperand::Kind_HWRegs); 1261 Operands.push_back(op); 1262 1263 Parser.Lex(); // Eat reg number 1264 return MatchOperand_Success; 1265} 1266 1267MipsAsmParser::OperandMatchResultTy 1268MipsAsmParser::parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1269 1270 if (!isMips64()) 1271 return MatchOperand_NoMatch; 1272 //if the first token is not '$' we have error 1273 if (Parser.getTok().isNot(AsmToken::Dollar)) 1274 return MatchOperand_NoMatch; 1275 SMLoc S = Parser.getTok().getLoc(); 1276 Parser.Lex(); // Eat $ 1277 1278 const AsmToken &Tok = Parser.getTok(); // get next token 1279 if (Tok.isNot(AsmToken::Integer)) 1280 return MatchOperand_NoMatch; 1281 1282 unsigned RegNum = Tok.getIntVal(); 1283 // at the moment only hwreg29 is supported 1284 if (RegNum != 29) 1285 return MatchOperand_ParseFail; 1286 1287 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S, 1288 Parser.getTok().getLoc()); 1289 op->setRegKind(MipsOperand::Kind_HW64Regs); 1290 Operands.push_back(op); 1291 1292 Parser.Lex(); // Eat reg number 1293 return MatchOperand_Success; 1294} 1295 1296MipsAsmParser::OperandMatchResultTy 1297MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1298 unsigned RegNum; 1299 //if the first token is not '$' we have error 1300 if (Parser.getTok().isNot(AsmToken::Dollar)) 1301 return MatchOperand_NoMatch; 1302 SMLoc S = Parser.getTok().getLoc(); 1303 Parser.Lex(); // Eat $ 1304 1305 const AsmToken &Tok = Parser.getTok(); // get next token 1306 if (Tok.is(AsmToken::Integer)) { 1307 RegNum = Tok.getIntVal(); 1308 // at the moment only fcc0 is supported 1309 if (RegNum != 0) 1310 return MatchOperand_ParseFail; 1311 } else if (Tok.is(AsmToken::Identifier)) { 1312 // at the moment only fcc0 is supported 1313 if (Tok.getIdentifier() != "fcc0") 1314 return MatchOperand_ParseFail; 1315 } else 1316 return MatchOperand_NoMatch; 1317 1318 MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S, 1319 Parser.getTok().getLoc()); 1320 op->setRegKind(MipsOperand::Kind_CCRRegs); 1321 Operands.push_back(op); 1322 1323 Parser.Lex(); // Eat reg number 1324 return MatchOperand_Success; 1325} 1326 1327MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 1328 1329 MCSymbolRefExpr::VariantKind VK 1330 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 1331 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 1332 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 1333 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 1334 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 1335 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 1336 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 1337 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 1338 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 1339 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 1340 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 1341 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 1342 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 1343 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 1344 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 1345 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 1346 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 1347 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 1348 .Default(MCSymbolRefExpr::VK_None); 1349 1350 return VK; 1351} 1352 1353static int ConvertCcString(StringRef CondString) { 1354 int CC = StringSwitch<unsigned>(CondString) 1355 .Case(".f", 0) 1356 .Case(".un", 1) 1357 .Case(".eq", 2) 1358 .Case(".ueq", 3) 1359 .Case(".olt", 4) 1360 .Case(".ult", 5) 1361 .Case(".ole", 6) 1362 .Case(".ule", 7) 1363 .Case(".sf", 8) 1364 .Case(".ngle", 9) 1365 .Case(".seq", 10) 1366 .Case(".ngl", 11) 1367 .Case(".lt", 12) 1368 .Case(".nge", 13) 1369 .Case(".le", 14) 1370 .Case(".ngt", 15) 1371 .Default(-1); 1372 1373 return CC; 1374} 1375 1376bool MipsAsmParser:: 1377parseMathOperation(StringRef Name, SMLoc NameLoc, 1378 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1379 // split the format 1380 size_t Start = Name.find('.'), Next = Name.rfind('.'); 1381 StringRef Format1 = Name.slice(Start, Next); 1382 // and add the first format to the operands 1383 Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc)); 1384 // now for the second format 1385 StringRef Format2 = Name.slice(Next, StringRef::npos); 1386 Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc)); 1387 1388 // set the format for the first register 1389 setFpFormat(Format1); 1390 1391 // Read the remaining operands. 1392 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1393 // Read the first operand. 1394 if (ParseOperand(Operands, Name)) { 1395 SMLoc Loc = getLexer().getLoc(); 1396 Parser.eatToEndOfStatement(); 1397 return Error(Loc, "unexpected token in argument list"); 1398 } 1399 1400 if (getLexer().isNot(AsmToken::Comma)) { 1401 SMLoc Loc = getLexer().getLoc(); 1402 Parser.eatToEndOfStatement(); 1403 return Error(Loc, "unexpected token in argument list"); 1404 1405 } 1406 Parser.Lex(); // Eat the comma. 1407 1408 //set the format for the first register 1409 setFpFormat(Format2); 1410 1411 // Parse and remember the operand. 1412 if (ParseOperand(Operands, Name)) { 1413 SMLoc Loc = getLexer().getLoc(); 1414 Parser.eatToEndOfStatement(); 1415 return Error(Loc, "unexpected token in argument list"); 1416 } 1417 } 1418 1419 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1420 SMLoc Loc = getLexer().getLoc(); 1421 Parser.eatToEndOfStatement(); 1422 return Error(Loc, "unexpected token in argument list"); 1423 } 1424 1425 Parser.Lex(); // Consume the EndOfStatement 1426 return false; 1427} 1428 1429bool MipsAsmParser:: 1430ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 1431 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1432 StringRef Mnemonic; 1433 // floating point instructions: should register be treated as double? 1434 if (requestsDoubleOperand(Name)) { 1435 setFpFormat(FP_FORMAT_D); 1436 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 1437 Mnemonic = Name; 1438 } 1439 else { 1440 setDefaultFpFormat(); 1441 // Create the leading tokens for the mnemonic, split by '.' characters. 1442 size_t Start = 0, Next = Name.find('.'); 1443 Mnemonic = Name.slice(Start, Next); 1444 1445 Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc)); 1446 1447 if (Next != StringRef::npos) { 1448 // there is a format token in mnemonic 1449 // StringRef Rest = Name.slice(Next, StringRef::npos); 1450 size_t Dot = Name.find('.', Next+1); 1451 StringRef Format = Name.slice(Next, Dot); 1452 if (Dot == StringRef::npos) //only one '.' in a string, it's a format 1453 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1454 else { 1455 if (Name.startswith("c.")){ 1456 // floating point compare, add '.' and immediate represent for cc 1457 Operands.push_back(MipsOperand::CreateToken(".", NameLoc)); 1458 int Cc = ConvertCcString(Format); 1459 if (Cc == -1) { 1460 return Error(NameLoc, "Invalid conditional code"); 1461 } 1462 SMLoc E = SMLoc::getFromPointer( 1463 Parser.getTok().getLoc().getPointer() -1 ); 1464 Operands.push_back(MipsOperand::CreateImm( 1465 MCConstantExpr::Create(Cc, getContext()), NameLoc, E)); 1466 } else { 1467 // trunc, ceil, floor ... 1468 return parseMathOperation(Name, NameLoc, Operands); 1469 } 1470 1471 // the rest is a format 1472 Format = Name.slice(Dot, StringRef::npos); 1473 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1474 } 1475 1476 setFpFormat(Format); 1477 } 1478 } 1479 1480 // Read the remaining operands. 1481 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1482 // Read the first operand. 1483 if (ParseOperand(Operands, Mnemonic)) { 1484 SMLoc Loc = getLexer().getLoc(); 1485 Parser.eatToEndOfStatement(); 1486 return Error(Loc, "unexpected token in argument list"); 1487 } 1488 1489 while (getLexer().is(AsmToken::Comma) ) { 1490 Parser.Lex(); // Eat the comma. 1491 1492 // Parse and remember the operand. 1493 if (ParseOperand(Operands, Name)) { 1494 SMLoc Loc = getLexer().getLoc(); 1495 Parser.eatToEndOfStatement(); 1496 return Error(Loc, "unexpected token in argument list"); 1497 } 1498 } 1499 } 1500 1501 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1502 SMLoc Loc = getLexer().getLoc(); 1503 Parser.eatToEndOfStatement(); 1504 return Error(Loc, "unexpected token in argument list"); 1505 } 1506 1507 Parser.Lex(); // Consume the EndOfStatement 1508 return false; 1509} 1510 1511bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 1512 SMLoc Loc = getLexer().getLoc(); 1513 Parser.eatToEndOfStatement(); 1514 return Error(Loc, ErrorMsg); 1515} 1516 1517bool MipsAsmParser::parseSetNoAtDirective() { 1518 // Line should look like: 1519 // .set noat 1520 // set at reg to 0 1521 Options.setATReg(0); 1522 // eat noat 1523 Parser.Lex(); 1524 // If this is not the end of the statement, report error 1525 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1526 reportParseError("unexpected token in statement"); 1527 return false; 1528 } 1529 Parser.Lex(); // Consume the EndOfStatement 1530 return false; 1531} 1532bool MipsAsmParser::parseSetAtDirective() { 1533 // line can be 1534 // .set at - defaults to $1 1535 // or .set at=$reg 1536 int AtRegNo; 1537 getParser().Lex(); 1538 if (getLexer().is(AsmToken::EndOfStatement)) { 1539 Options.setATReg(1); 1540 Parser.Lex(); // Consume the EndOfStatement 1541 return false; 1542 } else if (getLexer().is(AsmToken::Equal)) { 1543 getParser().Lex(); // eat '=' 1544 if (getLexer().isNot(AsmToken::Dollar)) { 1545 reportParseError("unexpected token in statement"); 1546 return false; 1547 } 1548 Parser.Lex(); // Eat '$' 1549 const AsmToken &Reg = Parser.getTok(); 1550 if (Reg.is(AsmToken::Identifier)) { 1551 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 1552 } else if (Reg.is(AsmToken::Integer)) { 1553 AtRegNo = Reg.getIntVal(); 1554 } else { 1555 reportParseError("unexpected token in statement"); 1556 return false; 1557 } 1558 1559 if ( AtRegNo < 1 || AtRegNo > 31) { 1560 reportParseError("unexpected token in statement"); 1561 return false; 1562 } 1563 1564 if (!Options.setATReg(AtRegNo)) { 1565 reportParseError("unexpected token in statement"); 1566 return false; 1567 } 1568 getParser().Lex(); // Eat reg 1569 1570 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1571 reportParseError("unexpected token in statement"); 1572 return false; 1573 } 1574 Parser.Lex(); // Consume the EndOfStatement 1575 return false; 1576 } else { 1577 reportParseError("unexpected token in statement"); 1578 return false; 1579 } 1580} 1581 1582bool MipsAsmParser::parseSetReorderDirective() { 1583 Parser.Lex(); 1584 // If this is not the end of the statement, report error 1585 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1586 reportParseError("unexpected token in statement"); 1587 return false; 1588 } 1589 Options.setReorder(); 1590 Parser.Lex(); // Consume the EndOfStatement 1591 return false; 1592} 1593 1594bool MipsAsmParser::parseSetNoReorderDirective() { 1595 Parser.Lex(); 1596 // if this is not the end of the statement, report error 1597 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1598 reportParseError("unexpected token in statement"); 1599 return false; 1600 } 1601 Options.setNoreorder(); 1602 Parser.Lex(); // Consume the EndOfStatement 1603 return false; 1604} 1605 1606bool MipsAsmParser::parseSetMacroDirective() { 1607 Parser.Lex(); 1608 // if this is not the end of the statement, report error 1609 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1610 reportParseError("unexpected token in statement"); 1611 return false; 1612 } 1613 Options.setMacro(); 1614 Parser.Lex(); // Consume the EndOfStatement 1615 return false; 1616} 1617 1618bool MipsAsmParser::parseSetNoMacroDirective() { 1619 Parser.Lex(); 1620 // if this is not the end of the statement, report error 1621 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1622 reportParseError("`noreorder' must be set before `nomacro'"); 1623 return false; 1624 } 1625 if (Options.isReorder()) { 1626 reportParseError("`noreorder' must be set before `nomacro'"); 1627 return false; 1628 } 1629 Options.setNomacro(); 1630 Parser.Lex(); // Consume the EndOfStatement 1631 return false; 1632} 1633 1634bool MipsAsmParser::parseSetAssignment() { 1635 StringRef Name; 1636 const MCExpr *Value; 1637 1638 if (Parser.parseIdentifier(Name)) 1639 reportParseError("expected identifier after .set"); 1640 1641 if (getLexer().isNot(AsmToken::Comma)) 1642 return reportParseError("unexpected token in .set directive"); 1643 Lex(); //eat comma 1644 1645 if (Parser.parseExpression(Value)) 1646 reportParseError("expected valid expression after comma"); 1647 1648 // check if the Name already exists as a symbol 1649 MCSymbol *Sym = getContext().LookupSymbol(Name); 1650 if (Sym) { 1651 return reportParseError("symbol already defined"); 1652 } 1653 Sym = getContext().GetOrCreateSymbol(Name); 1654 Sym->setVariableValue(Value); 1655 1656 return false; 1657} 1658bool MipsAsmParser::parseDirectiveSet() { 1659 1660 // get next token 1661 const AsmToken &Tok = Parser.getTok(); 1662 1663 if (Tok.getString() == "noat") { 1664 return parseSetNoAtDirective(); 1665 } else if (Tok.getString() == "at") { 1666 return parseSetAtDirective(); 1667 } else if (Tok.getString() == "reorder") { 1668 return parseSetReorderDirective(); 1669 } else if (Tok.getString() == "noreorder") { 1670 return parseSetNoReorderDirective(); 1671 } else if (Tok.getString() == "macro") { 1672 return parseSetMacroDirective(); 1673 } else if (Tok.getString() == "nomacro") { 1674 return parseSetNoMacroDirective(); 1675 } else if (Tok.getString() == "nomips16") { 1676 // ignore this directive for now 1677 Parser.eatToEndOfStatement(); 1678 return false; 1679 } else if (Tok.getString() == "nomicromips") { 1680 // ignore this directive for now 1681 Parser.eatToEndOfStatement(); 1682 return false; 1683 } else { 1684 // it is just an identifier, look for assignment 1685 parseSetAssignment(); 1686 return false; 1687 } 1688 1689 return true; 1690} 1691 1692/// parseDirectiveWord 1693/// ::= .word [ expression (, expression)* ] 1694bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 1695 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1696 for (;;) { 1697 const MCExpr *Value; 1698 if (getParser().parseExpression(Value)) 1699 return true; 1700 1701 getParser().getStreamer().EmitValue(Value, Size); 1702 1703 if (getLexer().is(AsmToken::EndOfStatement)) 1704 break; 1705 1706 // FIXME: Improve diagnostic. 1707 if (getLexer().isNot(AsmToken::Comma)) 1708 return Error(L, "unexpected token in directive"); 1709 Parser.Lex(); 1710 } 1711 } 1712 1713 Parser.Lex(); 1714 return false; 1715} 1716 1717bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 1718 1719 StringRef IDVal = DirectiveID.getString(); 1720 1721 if ( IDVal == ".ent") { 1722 // ignore this directive for now 1723 Parser.Lex(); 1724 return false; 1725 } 1726 1727 if (IDVal == ".end") { 1728 // ignore this directive for now 1729 Parser.Lex(); 1730 return false; 1731 } 1732 1733 if (IDVal == ".frame") { 1734 // ignore this directive for now 1735 Parser.eatToEndOfStatement(); 1736 return false; 1737 } 1738 1739 if (IDVal == ".set") { 1740 return parseDirectiveSet(); 1741 } 1742 1743 if (IDVal == ".fmask") { 1744 // ignore this directive for now 1745 Parser.eatToEndOfStatement(); 1746 return false; 1747 } 1748 1749 if (IDVal == ".mask") { 1750 // ignore this directive for now 1751 Parser.eatToEndOfStatement(); 1752 return false; 1753 } 1754 1755 if (IDVal == ".gpword") { 1756 // ignore this directive for now 1757 Parser.eatToEndOfStatement(); 1758 return false; 1759 } 1760 1761 if (IDVal == ".word") { 1762 parseDirectiveWord(4, DirectiveID.getLoc()); 1763 return false; 1764 } 1765 1766 return true; 1767} 1768 1769extern "C" void LLVMInitializeMipsAsmParser() { 1770 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 1771 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 1772 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 1773 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 1774} 1775 1776#define GET_REGISTER_MATCHER 1777#define GET_MATCHER_IMPLEMENTATION 1778#include "MipsGenAsmMatcher.inc" 1779