LLVM API Documentation
00001 //===-- SparcAsmParser.cpp - Parse Sparc assembly to MCInst instructions --===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "MCTargetDesc/SparcMCTargetDesc.h" 00011 #include "MCTargetDesc/SparcMCExpr.h" 00012 #include "llvm/ADT/STLExtras.h" 00013 #include "llvm/MC/MCContext.h" 00014 #include "llvm/MC/MCInst.h" 00015 #include "llvm/MC/MCObjectFileInfo.h" 00016 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 00017 #include "llvm/MC/MCStreamer.h" 00018 #include "llvm/MC/MCSubtargetInfo.h" 00019 #include "llvm/MC/MCSymbol.h" 00020 #include "llvm/MC/MCTargetAsmParser.h" 00021 #include "llvm/Support/TargetRegistry.h" 00022 00023 using namespace llvm; 00024 00025 // The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target 00026 // namespace. But SPARC backend uses "SP" as its namespace. 00027 namespace llvm { 00028 namespace Sparc { 00029 using namespace SP; 00030 } 00031 } 00032 00033 namespace { 00034 class SparcOperand; 00035 class SparcAsmParser : public MCTargetAsmParser { 00036 00037 MCSubtargetInfo &STI; 00038 MCAsmParser &Parser; 00039 00040 /// @name Auto-generated Match Functions 00041 /// { 00042 00043 #define GET_ASSEMBLER_HEADER 00044 #include "SparcGenAsmMatcher.inc" 00045 00046 /// } 00047 00048 // public interface of the MCTargetAsmParser. 00049 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 00050 OperandVector &Operands, MCStreamer &Out, 00051 uint64_t &ErrorInfo, 00052 bool MatchingInlineAsm) override; 00053 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 00054 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 00055 SMLoc NameLoc, OperandVector &Operands) override; 00056 bool ParseDirective(AsmToken DirectiveID) override; 00057 00058 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 00059 unsigned Kind) override; 00060 00061 // Custom parse functions for Sparc specific operands. 00062 OperandMatchResultTy parseMEMOperand(OperandVector &Operands); 00063 00064 OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name); 00065 00066 OperandMatchResultTy 00067 parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand, 00068 bool isCall = false); 00069 00070 OperandMatchResultTy parseBranchModifiers(OperandVector &Operands); 00071 00072 // returns true if Tok is matched to a register and returns register in RegNo. 00073 bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, 00074 unsigned &RegKind); 00075 00076 bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc); 00077 bool parseDirectiveWord(unsigned Size, SMLoc L); 00078 00079 bool is64Bit() const { return STI.getTargetTriple().startswith("sparcv9"); } 00080 public: 00081 SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, 00082 const MCInstrInfo &MII, 00083 const MCTargetOptions &Options) 00084 : MCTargetAsmParser(), STI(sti), Parser(parser) { 00085 // Initialize the set of available features. 00086 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 00087 } 00088 00089 }; 00090 00091 static unsigned IntRegs[32] = { 00092 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3, 00093 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7, 00094 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3, 00095 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7, 00096 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3, 00097 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7, 00098 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3, 00099 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 }; 00100 00101 static unsigned FloatRegs[32] = { 00102 Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3, 00103 Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7, 00104 Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11, 00105 Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15, 00106 Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19, 00107 Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23, 00108 Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27, 00109 Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 }; 00110 00111 static unsigned DoubleRegs[32] = { 00112 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3, 00113 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7, 00114 Sparc::D8, Sparc::D7, Sparc::D8, Sparc::D9, 00115 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15, 00116 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19, 00117 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23, 00118 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27, 00119 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 }; 00120 00121 static unsigned QuadFPRegs[32] = { 00122 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3, 00123 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7, 00124 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11, 00125 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 }; 00126 00127 00128 /// SparcOperand - Instances of this class represent a parsed Sparc machine 00129 /// instruction. 00130 class SparcOperand : public MCParsedAsmOperand { 00131 public: 00132 enum RegisterKind { 00133 rk_None, 00134 rk_IntReg, 00135 rk_FloatReg, 00136 rk_DoubleReg, 00137 rk_QuadReg, 00138 rk_CCReg, 00139 rk_Y 00140 }; 00141 private: 00142 enum KindTy { 00143 k_Token, 00144 k_Register, 00145 k_Immediate, 00146 k_MemoryReg, 00147 k_MemoryImm 00148 } Kind; 00149 00150 SMLoc StartLoc, EndLoc; 00151 00152 struct Token { 00153 const char *Data; 00154 unsigned Length; 00155 }; 00156 00157 struct RegOp { 00158 unsigned RegNum; 00159 RegisterKind Kind; 00160 }; 00161 00162 struct ImmOp { 00163 const MCExpr *Val; 00164 }; 00165 00166 struct MemOp { 00167 unsigned Base; 00168 unsigned OffsetReg; 00169 const MCExpr *Off; 00170 }; 00171 00172 union { 00173 struct Token Tok; 00174 struct RegOp Reg; 00175 struct ImmOp Imm; 00176 struct MemOp Mem; 00177 }; 00178 public: 00179 SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 00180 00181 bool isToken() const override { return Kind == k_Token; } 00182 bool isReg() const override { return Kind == k_Register; } 00183 bool isImm() const override { return Kind == k_Immediate; } 00184 bool isMem() const override { return isMEMrr() || isMEMri(); } 00185 bool isMEMrr() const { return Kind == k_MemoryReg; } 00186 bool isMEMri() const { return Kind == k_MemoryImm; } 00187 00188 bool isFloatReg() const { 00189 return (Kind == k_Register && Reg.Kind == rk_FloatReg); 00190 } 00191 00192 bool isFloatOrDoubleReg() const { 00193 return (Kind == k_Register && (Reg.Kind == rk_FloatReg 00194 || Reg.Kind == rk_DoubleReg)); 00195 } 00196 00197 00198 StringRef getToken() const { 00199 assert(Kind == k_Token && "Invalid access!"); 00200 return StringRef(Tok.Data, Tok.Length); 00201 } 00202 00203 unsigned getReg() const override { 00204 assert((Kind == k_Register) && "Invalid access!"); 00205 return Reg.RegNum; 00206 } 00207 00208 const MCExpr *getImm() const { 00209 assert((Kind == k_Immediate) && "Invalid access!"); 00210 return Imm.Val; 00211 } 00212 00213 unsigned getMemBase() const { 00214 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!"); 00215 return Mem.Base; 00216 } 00217 00218 unsigned getMemOffsetReg() const { 00219 assert((Kind == k_MemoryReg) && "Invalid access!"); 00220 return Mem.OffsetReg; 00221 } 00222 00223 const MCExpr *getMemOff() const { 00224 assert((Kind == k_MemoryImm) && "Invalid access!"); 00225 return Mem.Off; 00226 } 00227 00228 /// getStartLoc - Get the location of the first token of this operand. 00229 SMLoc getStartLoc() const override { 00230 return StartLoc; 00231 } 00232 /// getEndLoc - Get the location of the last token of this operand. 00233 SMLoc getEndLoc() const override { 00234 return EndLoc; 00235 } 00236 00237 void print(raw_ostream &OS) const override { 00238 switch (Kind) { 00239 case k_Token: OS << "Token: " << getToken() << "\n"; break; 00240 case k_Register: OS << "Reg: #" << getReg() << "\n"; break; 00241 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break; 00242 case k_MemoryReg: OS << "Mem: " << getMemBase() << "+" 00243 << getMemOffsetReg() << "\n"; break; 00244 case k_MemoryImm: assert(getMemOff() != nullptr); 00245 OS << "Mem: " << getMemBase() 00246 << "+" << *getMemOff() 00247 << "\n"; break; 00248 } 00249 } 00250 00251 void addRegOperands(MCInst &Inst, unsigned N) const { 00252 assert(N == 1 && "Invalid number of operands!"); 00253 Inst.addOperand(MCOperand::CreateReg(getReg())); 00254 } 00255 00256 void addImmOperands(MCInst &Inst, unsigned N) const { 00257 assert(N == 1 && "Invalid number of operands!"); 00258 const MCExpr *Expr = getImm(); 00259 addExpr(Inst, Expr); 00260 } 00261 00262 void addExpr(MCInst &Inst, const MCExpr *Expr) const{ 00263 // Add as immediate when possible. Null MCExpr = 0. 00264 if (!Expr) 00265 Inst.addOperand(MCOperand::CreateImm(0)); 00266 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 00267 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 00268 else 00269 Inst.addOperand(MCOperand::CreateExpr(Expr)); 00270 } 00271 00272 void addMEMrrOperands(MCInst &Inst, unsigned N) const { 00273 assert(N == 2 && "Invalid number of operands!"); 00274 00275 Inst.addOperand(MCOperand::CreateReg(getMemBase())); 00276 00277 assert(getMemOffsetReg() != 0 && "Invalid offset"); 00278 Inst.addOperand(MCOperand::CreateReg(getMemOffsetReg())); 00279 } 00280 00281 void addMEMriOperands(MCInst &Inst, unsigned N) const { 00282 assert(N == 2 && "Invalid number of operands!"); 00283 00284 Inst.addOperand(MCOperand::CreateReg(getMemBase())); 00285 00286 const MCExpr *Expr = getMemOff(); 00287 addExpr(Inst, Expr); 00288 } 00289 00290 static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) { 00291 auto Op = make_unique<SparcOperand>(k_Token); 00292 Op->Tok.Data = Str.data(); 00293 Op->Tok.Length = Str.size(); 00294 Op->StartLoc = S; 00295 Op->EndLoc = S; 00296 return Op; 00297 } 00298 00299 static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind, 00300 SMLoc S, SMLoc E) { 00301 auto Op = make_unique<SparcOperand>(k_Register); 00302 Op->Reg.RegNum = RegNum; 00303 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind; 00304 Op->StartLoc = S; 00305 Op->EndLoc = E; 00306 return Op; 00307 } 00308 00309 static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S, 00310 SMLoc E) { 00311 auto Op = make_unique<SparcOperand>(k_Immediate); 00312 Op->Imm.Val = Val; 00313 Op->StartLoc = S; 00314 Op->EndLoc = E; 00315 return Op; 00316 } 00317 00318 static bool MorphToDoubleReg(SparcOperand &Op) { 00319 unsigned Reg = Op.getReg(); 00320 assert(Op.Reg.Kind == rk_FloatReg); 00321 unsigned regIdx = Reg - Sparc::F0; 00322 if (regIdx % 2 || regIdx > 31) 00323 return false; 00324 Op.Reg.RegNum = DoubleRegs[regIdx / 2]; 00325 Op.Reg.Kind = rk_DoubleReg; 00326 return true; 00327 } 00328 00329 static bool MorphToQuadReg(SparcOperand &Op) { 00330 unsigned Reg = Op.getReg(); 00331 unsigned regIdx = 0; 00332 switch (Op.Reg.Kind) { 00333 default: llvm_unreachable("Unexpected register kind!"); 00334 case rk_FloatReg: 00335 regIdx = Reg - Sparc::F0; 00336 if (regIdx % 4 || regIdx > 31) 00337 return false; 00338 Reg = QuadFPRegs[regIdx / 4]; 00339 break; 00340 case rk_DoubleReg: 00341 regIdx = Reg - Sparc::D0; 00342 if (regIdx % 2 || regIdx > 31) 00343 return false; 00344 Reg = QuadFPRegs[regIdx / 2]; 00345 break; 00346 } 00347 Op.Reg.RegNum = Reg; 00348 Op.Reg.Kind = rk_QuadReg; 00349 return true; 00350 } 00351 00352 static std::unique_ptr<SparcOperand> 00353 MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) { 00354 unsigned offsetReg = Op->getReg(); 00355 Op->Kind = k_MemoryReg; 00356 Op->Mem.Base = Base; 00357 Op->Mem.OffsetReg = offsetReg; 00358 Op->Mem.Off = nullptr; 00359 return Op; 00360 } 00361 00362 static std::unique_ptr<SparcOperand> 00363 CreateMEMri(unsigned Base, const MCExpr *Off, SMLoc S, SMLoc E) { 00364 auto Op = make_unique<SparcOperand>(k_MemoryImm); 00365 Op->Mem.Base = Base; 00366 Op->Mem.OffsetReg = 0; 00367 Op->Mem.Off = Off; 00368 Op->StartLoc = S; 00369 Op->EndLoc = E; 00370 return Op; 00371 } 00372 00373 static std::unique_ptr<SparcOperand> 00374 MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) { 00375 const MCExpr *Imm = Op->getImm(); 00376 Op->Kind = k_MemoryImm; 00377 Op->Mem.Base = Base; 00378 Op->Mem.OffsetReg = 0; 00379 Op->Mem.Off = Imm; 00380 return Op; 00381 } 00382 }; 00383 00384 } // end namespace 00385 00386 bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 00387 OperandVector &Operands, 00388 MCStreamer &Out, 00389 uint64_t &ErrorInfo, 00390 bool MatchingInlineAsm) { 00391 MCInst Inst; 00392 SmallVector<MCInst, 8> Instructions; 00393 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, 00394 MatchingInlineAsm); 00395 switch (MatchResult) { 00396 default: 00397 break; 00398 00399 case Match_Success: { 00400 Inst.setLoc(IDLoc); 00401 Out.EmitInstruction(Inst, STI); 00402 return false; 00403 } 00404 00405 case Match_MissingFeature: 00406 return Error(IDLoc, 00407 "instruction requires a CPU feature not currently enabled"); 00408 00409 case Match_InvalidOperand: { 00410 SMLoc ErrorLoc = IDLoc; 00411 if (ErrorInfo != ~0ULL) { 00412 if (ErrorInfo >= Operands.size()) 00413 return Error(IDLoc, "too few operands for instruction"); 00414 00415 ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc(); 00416 if (ErrorLoc == SMLoc()) 00417 ErrorLoc = IDLoc; 00418 } 00419 00420 return Error(ErrorLoc, "invalid operand for instruction"); 00421 } 00422 case Match_MnemonicFail: 00423 return Error(IDLoc, "invalid instruction mnemonic"); 00424 } 00425 return true; 00426 } 00427 00428 bool SparcAsmParser:: 00429 ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) 00430 { 00431 const AsmToken &Tok = Parser.getTok(); 00432 StartLoc = Tok.getLoc(); 00433 EndLoc = Tok.getEndLoc(); 00434 RegNo = 0; 00435 if (getLexer().getKind() != AsmToken::Percent) 00436 return false; 00437 Parser.Lex(); 00438 unsigned regKind = SparcOperand::rk_None; 00439 if (matchRegisterName(Tok, RegNo, regKind)) { 00440 Parser.Lex(); 00441 return false; 00442 } 00443 00444 return Error(StartLoc, "invalid register name"); 00445 } 00446 00447 static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features, 00448 unsigned VariantID); 00449 00450 bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info, 00451 StringRef Name, SMLoc NameLoc, 00452 OperandVector &Operands) { 00453 00454 // First operand in MCInst is instruction mnemonic. 00455 Operands.push_back(SparcOperand::CreateToken(Name, NameLoc)); 00456 00457 // apply mnemonic aliases, if any, so that we can parse operands correctly. 00458 applyMnemonicAliases(Name, getAvailableFeatures(), 0); 00459 00460 if (getLexer().isNot(AsmToken::EndOfStatement)) { 00461 // Read the first operand. 00462 if (getLexer().is(AsmToken::Comma)) { 00463 if (parseBranchModifiers(Operands) != MatchOperand_Success) { 00464 SMLoc Loc = getLexer().getLoc(); 00465 Parser.eatToEndOfStatement(); 00466 return Error(Loc, "unexpected token"); 00467 } 00468 } 00469 if (parseOperand(Operands, Name) != MatchOperand_Success) { 00470 SMLoc Loc = getLexer().getLoc(); 00471 Parser.eatToEndOfStatement(); 00472 return Error(Loc, "unexpected token"); 00473 } 00474 00475 while (getLexer().is(AsmToken::Comma)) { 00476 Parser.Lex(); // Eat the comma. 00477 // Parse and remember the operand. 00478 if (parseOperand(Operands, Name) != MatchOperand_Success) { 00479 SMLoc Loc = getLexer().getLoc(); 00480 Parser.eatToEndOfStatement(); 00481 return Error(Loc, "unexpected token"); 00482 } 00483 } 00484 } 00485 if (getLexer().isNot(AsmToken::EndOfStatement)) { 00486 SMLoc Loc = getLexer().getLoc(); 00487 Parser.eatToEndOfStatement(); 00488 return Error(Loc, "unexpected token"); 00489 } 00490 Parser.Lex(); // Consume the EndOfStatement. 00491 return false; 00492 } 00493 00494 bool SparcAsmParser:: 00495 ParseDirective(AsmToken DirectiveID) 00496 { 00497 StringRef IDVal = DirectiveID.getString(); 00498 00499 if (IDVal == ".byte") 00500 return parseDirectiveWord(1, DirectiveID.getLoc()); 00501 00502 if (IDVal == ".half") 00503 return parseDirectiveWord(2, DirectiveID.getLoc()); 00504 00505 if (IDVal == ".word") 00506 return parseDirectiveWord(4, DirectiveID.getLoc()); 00507 00508 if (IDVal == ".nword") 00509 return parseDirectiveWord(is64Bit() ? 8 : 4, DirectiveID.getLoc()); 00510 00511 if (is64Bit() && IDVal == ".xword") 00512 return parseDirectiveWord(8, DirectiveID.getLoc()); 00513 00514 if (IDVal == ".register") { 00515 // For now, ignore .register directive. 00516 Parser.eatToEndOfStatement(); 00517 return false; 00518 } 00519 00520 // Let the MC layer to handle other directives. 00521 return true; 00522 } 00523 00524 bool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) { 00525 if (getLexer().isNot(AsmToken::EndOfStatement)) { 00526 for (;;) { 00527 const MCExpr *Value; 00528 if (getParser().parseExpression(Value)) 00529 return true; 00530 00531 getParser().getStreamer().EmitValue(Value, Size); 00532 00533 if (getLexer().is(AsmToken::EndOfStatement)) 00534 break; 00535 00536 // FIXME: Improve diagnostic. 00537 if (getLexer().isNot(AsmToken::Comma)) 00538 return Error(L, "unexpected token in directive"); 00539 Parser.Lex(); 00540 } 00541 } 00542 Parser.Lex(); 00543 return false; 00544 } 00545 00546 SparcAsmParser::OperandMatchResultTy 00547 SparcAsmParser::parseMEMOperand(OperandVector &Operands) { 00548 00549 SMLoc S, E; 00550 unsigned BaseReg = 0; 00551 00552 if (ParseRegister(BaseReg, S, E)) { 00553 return MatchOperand_NoMatch; 00554 } 00555 00556 switch (getLexer().getKind()) { 00557 default: return MatchOperand_NoMatch; 00558 00559 case AsmToken::Comma: 00560 case AsmToken::RBrac: 00561 case AsmToken::EndOfStatement: 00562 Operands.push_back(SparcOperand::CreateMEMri(BaseReg, nullptr, S, E)); 00563 return MatchOperand_Success; 00564 00565 case AsmToken:: Plus: 00566 Parser.Lex(); // Eat the '+' 00567 break; 00568 case AsmToken::Minus: 00569 break; 00570 } 00571 00572 std::unique_ptr<SparcOperand> Offset; 00573 OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset); 00574 if (ResTy != MatchOperand_Success || !Offset) 00575 return MatchOperand_NoMatch; 00576 00577 Operands.push_back( 00578 Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset)) 00579 : SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset))); 00580 00581 return MatchOperand_Success; 00582 } 00583 00584 SparcAsmParser::OperandMatchResultTy 00585 SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 00586 00587 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 00588 00589 // If there wasn't a custom match, try the generic matcher below. Otherwise, 00590 // there was a match, but an error occurred, in which case, just return that 00591 // the operand parsing failed. 00592 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail) 00593 return ResTy; 00594 00595 if (getLexer().is(AsmToken::LBrac)) { 00596 // Memory operand 00597 Operands.push_back(SparcOperand::CreateToken("[", 00598 Parser.getTok().getLoc())); 00599 Parser.Lex(); // Eat the [ 00600 00601 if (Mnemonic == "cas" || Mnemonic == "casx") { 00602 SMLoc S = Parser.getTok().getLoc(); 00603 if (getLexer().getKind() != AsmToken::Percent) 00604 return MatchOperand_NoMatch; 00605 Parser.Lex(); // eat % 00606 00607 unsigned RegNo, RegKind; 00608 if (!matchRegisterName(Parser.getTok(), RegNo, RegKind)) 00609 return MatchOperand_NoMatch; 00610 00611 Parser.Lex(); // Eat the identifier token. 00612 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1); 00613 Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E)); 00614 ResTy = MatchOperand_Success; 00615 } else { 00616 ResTy = parseMEMOperand(Operands); 00617 } 00618 00619 if (ResTy != MatchOperand_Success) 00620 return ResTy; 00621 00622 if (!getLexer().is(AsmToken::RBrac)) 00623 return MatchOperand_ParseFail; 00624 00625 Operands.push_back(SparcOperand::CreateToken("]", 00626 Parser.getTok().getLoc())); 00627 Parser.Lex(); // Eat the ] 00628 return MatchOperand_Success; 00629 } 00630 00631 std::unique_ptr<SparcOperand> Op; 00632 00633 ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call")); 00634 if (ResTy != MatchOperand_Success || !Op) 00635 return MatchOperand_ParseFail; 00636 00637 // Push the parsed operand into the list of operands 00638 Operands.push_back(std::move(Op)); 00639 00640 return MatchOperand_Success; 00641 } 00642 00643 SparcAsmParser::OperandMatchResultTy 00644 SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op, 00645 bool isCall) { 00646 00647 SMLoc S = Parser.getTok().getLoc(); 00648 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 00649 const MCExpr *EVal; 00650 00651 Op = nullptr; 00652 switch (getLexer().getKind()) { 00653 default: break; 00654 00655 case AsmToken::Percent: 00656 Parser.Lex(); // Eat the '%'. 00657 unsigned RegNo; 00658 unsigned RegKind; 00659 if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) { 00660 StringRef name = Parser.getTok().getString(); 00661 Parser.Lex(); // Eat the identifier token. 00662 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 00663 switch (RegNo) { 00664 default: 00665 Op = SparcOperand::CreateReg(RegNo, RegKind, S, E); 00666 break; 00667 case Sparc::Y: 00668 Op = SparcOperand::CreateToken("%y", S); 00669 break; 00670 00671 case Sparc::ICC: 00672 if (name == "xcc") 00673 Op = SparcOperand::CreateToken("%xcc", S); 00674 else 00675 Op = SparcOperand::CreateToken("%icc", S); 00676 break; 00677 } 00678 break; 00679 } 00680 if (matchSparcAsmModifiers(EVal, E)) { 00681 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 00682 Op = SparcOperand::CreateImm(EVal, S, E); 00683 } 00684 break; 00685 00686 case AsmToken::Minus: 00687 case AsmToken::Integer: 00688 if (!getParser().parseExpression(EVal, E)) 00689 Op = SparcOperand::CreateImm(EVal, S, E); 00690 break; 00691 00692 case AsmToken::Identifier: { 00693 StringRef Identifier; 00694 if (!getParser().parseIdentifier(Identifier)) { 00695 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 00696 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier); 00697 00698 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 00699 getContext()); 00700 if (isCall && 00701 getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_) 00702 Res = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_WPLT30, Res, 00703 getContext()); 00704 Op = SparcOperand::CreateImm(Res, S, E); 00705 } 00706 break; 00707 } 00708 } 00709 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail; 00710 } 00711 00712 SparcAsmParser::OperandMatchResultTy 00713 SparcAsmParser::parseBranchModifiers(OperandVector &Operands) { 00714 00715 // parse (,a|,pn|,pt)+ 00716 00717 while (getLexer().is(AsmToken::Comma)) { 00718 00719 Parser.Lex(); // Eat the comma 00720 00721 if (!getLexer().is(AsmToken::Identifier)) 00722 return MatchOperand_ParseFail; 00723 StringRef modName = Parser.getTok().getString(); 00724 if (modName == "a" || modName == "pn" || modName == "pt") { 00725 Operands.push_back(SparcOperand::CreateToken(modName, 00726 Parser.getTok().getLoc())); 00727 Parser.Lex(); // eat the identifier. 00728 } 00729 } 00730 return MatchOperand_Success; 00731 } 00732 00733 bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, 00734 unsigned &RegNo, 00735 unsigned &RegKind) 00736 { 00737 int64_t intVal = 0; 00738 RegNo = 0; 00739 RegKind = SparcOperand::rk_None; 00740 if (Tok.is(AsmToken::Identifier)) { 00741 StringRef name = Tok.getString(); 00742 00743 // %fp 00744 if (name.equals("fp")) { 00745 RegNo = Sparc::I6; 00746 RegKind = SparcOperand::rk_IntReg; 00747 return true; 00748 } 00749 // %sp 00750 if (name.equals("sp")) { 00751 RegNo = Sparc::O6; 00752 RegKind = SparcOperand::rk_IntReg; 00753 return true; 00754 } 00755 00756 if (name.equals("y")) { 00757 RegNo = Sparc::Y; 00758 RegKind = SparcOperand::rk_Y; 00759 return true; 00760 } 00761 00762 if (name.equals("icc")) { 00763 RegNo = Sparc::ICC; 00764 RegKind = SparcOperand::rk_CCReg; 00765 return true; 00766 } 00767 00768 if (name.equals("xcc")) { 00769 // FIXME:: check 64bit. 00770 RegNo = Sparc::ICC; 00771 RegKind = SparcOperand::rk_CCReg; 00772 return true; 00773 } 00774 00775 // %fcc0 - %fcc3 00776 if (name.substr(0, 3).equals_lower("fcc") 00777 && !name.substr(3).getAsInteger(10, intVal) 00778 && intVal < 4) { 00779 // FIXME: check 64bit and handle %fcc1 - %fcc3 00780 RegNo = Sparc::FCC0 + intVal; 00781 RegKind = SparcOperand::rk_CCReg; 00782 return true; 00783 } 00784 00785 // %g0 - %g7 00786 if (name.substr(0, 1).equals_lower("g") 00787 && !name.substr(1).getAsInteger(10, intVal) 00788 && intVal < 8) { 00789 RegNo = IntRegs[intVal]; 00790 RegKind = SparcOperand::rk_IntReg; 00791 return true; 00792 } 00793 // %o0 - %o7 00794 if (name.substr(0, 1).equals_lower("o") 00795 && !name.substr(1).getAsInteger(10, intVal) 00796 && intVal < 8) { 00797 RegNo = IntRegs[8 + intVal]; 00798 RegKind = SparcOperand::rk_IntReg; 00799 return true; 00800 } 00801 if (name.substr(0, 1).equals_lower("l") 00802 && !name.substr(1).getAsInteger(10, intVal) 00803 && intVal < 8) { 00804 RegNo = IntRegs[16 + intVal]; 00805 RegKind = SparcOperand::rk_IntReg; 00806 return true; 00807 } 00808 if (name.substr(0, 1).equals_lower("i") 00809 && !name.substr(1).getAsInteger(10, intVal) 00810 && intVal < 8) { 00811 RegNo = IntRegs[24 + intVal]; 00812 RegKind = SparcOperand::rk_IntReg; 00813 return true; 00814 } 00815 // %f0 - %f31 00816 if (name.substr(0, 1).equals_lower("f") 00817 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) { 00818 RegNo = FloatRegs[intVal]; 00819 RegKind = SparcOperand::rk_FloatReg; 00820 return true; 00821 } 00822 // %f32 - %f62 00823 if (name.substr(0, 1).equals_lower("f") 00824 && !name.substr(1, 2).getAsInteger(10, intVal) 00825 && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) { 00826 // FIXME: Check V9 00827 RegNo = DoubleRegs[intVal/2]; 00828 RegKind = SparcOperand::rk_DoubleReg; 00829 return true; 00830 } 00831 00832 // %r0 - %r31 00833 if (name.substr(0, 1).equals_lower("r") 00834 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) { 00835 RegNo = IntRegs[intVal]; 00836 RegKind = SparcOperand::rk_IntReg; 00837 return true; 00838 } 00839 } 00840 return false; 00841 } 00842 00843 static bool hasGOTReference(const MCExpr *Expr) { 00844 switch (Expr->getKind()) { 00845 case MCExpr::Target: 00846 if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr)) 00847 return hasGOTReference(SE->getSubExpr()); 00848 break; 00849 00850 case MCExpr::Constant: 00851 break; 00852 00853 case MCExpr::Binary: { 00854 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); 00855 return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS()); 00856 } 00857 00858 case MCExpr::SymbolRef: { 00859 const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr); 00860 return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_"); 00861 } 00862 00863 case MCExpr::Unary: 00864 return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr()); 00865 } 00866 return false; 00867 } 00868 00869 bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal, 00870 SMLoc &EndLoc) 00871 { 00872 AsmToken Tok = Parser.getTok(); 00873 if (!Tok.is(AsmToken::Identifier)) 00874 return false; 00875 00876 StringRef name = Tok.getString(); 00877 00878 SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name); 00879 00880 if (VK == SparcMCExpr::VK_Sparc_None) 00881 return false; 00882 00883 Parser.Lex(); // Eat the identifier. 00884 if (Parser.getTok().getKind() != AsmToken::LParen) 00885 return false; 00886 00887 Parser.Lex(); // Eat the LParen token. 00888 const MCExpr *subExpr; 00889 if (Parser.parseParenExpression(subExpr, EndLoc)) 00890 return false; 00891 00892 bool isPIC = getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_; 00893 00894 switch(VK) { 00895 default: break; 00896 case SparcMCExpr::VK_Sparc_LO: 00897 VK = (hasGOTReference(subExpr) 00898 ? SparcMCExpr::VK_Sparc_PC10 00899 : (isPIC ? SparcMCExpr::VK_Sparc_GOT10 : VK)); 00900 break; 00901 case SparcMCExpr::VK_Sparc_HI: 00902 VK = (hasGOTReference(subExpr) 00903 ? SparcMCExpr::VK_Sparc_PC22 00904 : (isPIC ? SparcMCExpr::VK_Sparc_GOT22 : VK)); 00905 break; 00906 } 00907 00908 EVal = SparcMCExpr::Create(VK, subExpr, getContext()); 00909 return true; 00910 } 00911 00912 00913 extern "C" void LLVMInitializeSparcAsmParser() { 00914 RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget); 00915 RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target); 00916 } 00917 00918 #define GET_REGISTER_MATCHER 00919 #define GET_MATCHER_IMPLEMENTATION 00920 #include "SparcGenAsmMatcher.inc" 00921 00922 unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp, 00923 unsigned Kind) { 00924 SparcOperand &Op = (SparcOperand &)GOp; 00925 if (Op.isFloatOrDoubleReg()) { 00926 switch (Kind) { 00927 default: break; 00928 case MCK_DFPRegs: 00929 if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op)) 00930 return MCTargetAsmParser::Match_Success; 00931 break; 00932 case MCK_QFPRegs: 00933 if (SparcOperand::MorphToQuadReg(Op)) 00934 return MCTargetAsmParser::Match_Success; 00935 break; 00936 } 00937 } 00938 return Match_InvalidOperand; 00939 }