-
Notifications
You must be signed in to change notification settings - Fork 15.7k
[Xtensa] Implement base CallConvention. #83280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
3a0dff0
4689ab3
393aa32
9d48072
c5f9a64
b2f202c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,9 @@ | |
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "MCTargetDesc/XtensaMCExpr.h" | ||
| #include "MCTargetDesc/XtensaMCTargetDesc.h" | ||
| #include "MCTargetDesc/XtensaTargetStreamer.h" | ||
| #include "TargetInfo/XtensaTargetInfo.h" | ||
| #include "llvm/ADT/STLExtras.h" | ||
| #include "llvm/ADT/StringSwitch.h" | ||
|
|
@@ -22,6 +24,7 @@ | |
| #include "llvm/MC/MCRegisterInfo.h" | ||
| #include "llvm/MC/MCStreamer.h" | ||
| #include "llvm/MC/MCSubtargetInfo.h" | ||
| #include "llvm/MC/MCSymbol.h" | ||
| #include "llvm/MC/TargetRegistry.h" | ||
| #include "llvm/Support/Casting.h" | ||
|
|
||
|
|
@@ -35,6 +38,12 @@ class XtensaAsmParser : public MCTargetAsmParser { | |
|
|
||
| SMLoc getLoc() const { return getParser().getTok().getLoc(); } | ||
|
|
||
| XtensaTargetStreamer &getTargetStreamer() { | ||
| MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); | ||
| return static_cast<XtensaTargetStreamer &>(TS); | ||
| } | ||
|
|
||
| bool ParseDirective(AsmToken DirectiveID) override; | ||
| bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override; | ||
| bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, | ||
| SMLoc NameLoc, OperandVector &Operands) override; | ||
|
|
@@ -45,6 +54,9 @@ class XtensaAsmParser : public MCTargetAsmParser { | |
| unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, | ||
| unsigned Kind) override; | ||
|
|
||
| bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, | ||
| const MCSubtargetInfo *STI); | ||
|
|
||
| // Auto-generated instruction matching functions | ||
| #define GET_ASSEMBLER_HEADER | ||
| #include "XtensaGenAsmMatcher.inc" | ||
|
|
@@ -62,6 +74,7 @@ class XtensaAsmParser : public MCTargetAsmParser { | |
| return ParseStatus::NoMatch; | ||
| } | ||
| ParseStatus parsePCRelTarget(OperandVector &Operands); | ||
| bool parseLiteralDirective(SMLoc L); | ||
|
|
||
| public: | ||
| enum XtensaMatchResultTy { | ||
|
|
@@ -148,7 +161,13 @@ struct XtensaOperand : public MCParsedAsmOperand { | |
|
|
||
| bool isImm12() const { return isImm(-2048, 2047); } | ||
|
|
||
| bool isImm12m() const { return isImm(-2048, 2047); } | ||
| // Convert MOVI to literal load, when immediate is not in range (-2048, 2047) | ||
| bool isImm12m() const { | ||
| if (Kind == Immediate) | ||
| return true; | ||
|
|
||
| return false; | ||
arsenm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| bool isOffset4m32() const { | ||
| return isImm(0, 60) && | ||
|
|
@@ -348,6 +367,67 @@ static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, | |
| return Loc; | ||
| } | ||
|
|
||
| bool XtensaAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, | ||
| MCStreamer &Out, | ||
| const MCSubtargetInfo *STI) { | ||
| Inst.setLoc(IDLoc); | ||
| const unsigned Opcode = Inst.getOpcode(); | ||
| switch (Opcode) { | ||
| case Xtensa::L32R: { | ||
| const MCSymbolRefExpr *OpExpr = | ||
| (const MCSymbolRefExpr *)Inst.getOperand(1).getExpr(); | ||
arsenm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| XtensaMCExpr::VariantKind Kind = XtensaMCExpr::VK_Xtensa_None; | ||
| const MCExpr *NewOpExpr = XtensaMCExpr::create(OpExpr, Kind, getContext()); | ||
| Inst.getOperand(1).setExpr(NewOpExpr); | ||
| } break; | ||
|
||
| case Xtensa::MOVI: { | ||
| XtensaTargetStreamer &TS = this->getTargetStreamer(); | ||
|
|
||
| // Expand MOVI operand | ||
| if (!Inst.getOperand(1).isExpr()) { | ||
| uint64_t ImmOp64 = Inst.getOperand(1).getImm(); | ||
| int32_t Imm = ImmOp64; | ||
| if ((Imm < -2048) || (Imm > 2047)) { | ||
arsenm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| XtensaTargetStreamer &TS = this->getTargetStreamer(); | ||
| MCInst TmpInst; | ||
| TmpInst.setLoc(IDLoc); | ||
| TmpInst.setOpcode(Xtensa::L32R); | ||
| const MCExpr *Value = MCConstantExpr::create(ImmOp64, getContext()); | ||
| MCSymbol *Sym = getContext().createTempSymbol(); | ||
| const MCExpr *Expr = MCSymbolRefExpr::create( | ||
| Sym, MCSymbolRefExpr::VK_None, getContext()); | ||
| const MCExpr *OpExpr = XtensaMCExpr::create( | ||
| Expr, XtensaMCExpr::VK_Xtensa_None, getContext()); | ||
| TmpInst.addOperand(Inst.getOperand(0)); | ||
| MCOperand Op1 = MCOperand::createExpr(OpExpr); | ||
| TmpInst.addOperand(Op1); | ||
| TS.emitLiteral(Sym, Value, IDLoc); | ||
| Inst = TmpInst; | ||
| } | ||
| } else { | ||
| MCInst TmpInst; | ||
| TmpInst.setLoc(IDLoc); | ||
| TmpInst.setOpcode(Xtensa::L32R); | ||
| const MCExpr *Value = Inst.getOperand(1).getExpr(); | ||
| MCSymbol *Sym = getContext().createTempSymbol(); | ||
| const MCExpr *Expr = | ||
| MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); | ||
| const MCExpr *OpExpr = XtensaMCExpr::create( | ||
| Expr, XtensaMCExpr::VK_Xtensa_None, getContext()); | ||
| TmpInst.addOperand(Inst.getOperand(0)); | ||
| MCOperand Op1 = MCOperand::createExpr(OpExpr); | ||
| TmpInst.addOperand(Op1); | ||
| Inst = TmpInst; | ||
| TS.emitLiteral(Sym, Value, IDLoc); | ||
| } | ||
| } break; | ||
arsenm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| default: | ||
| break; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| bool XtensaAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, | ||
| OperandVector &Operands, | ||
| MCStreamer &Out, | ||
|
|
@@ -361,6 +441,7 @@ bool XtensaAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, | |
| default: | ||
| break; | ||
| case Match_Success: | ||
| processInstruction(Inst, IDLoc, Out, STI); | ||
| Inst.setLoc(IDLoc); | ||
| Out.emitInstruction(Inst, getSTI()); | ||
| return false; | ||
|
|
@@ -686,6 +767,58 @@ bool XtensaAsmParser::ParseInstruction(ParseInstructionInfo &Info, | |
| return false; | ||
| } | ||
|
|
||
| bool XtensaAsmParser::parseLiteralDirective(SMLoc L) { | ||
| MCAsmParser &Parser = getParser(); | ||
| MCSymbol *Sym; | ||
arsenm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const MCExpr *Value; | ||
| SMLoc LiteralLoc = getLexer().getLoc(); | ||
| XtensaTargetStreamer &TS = this->getTargetStreamer(); | ||
|
|
||
| if (Parser.parseExpression(Value)) | ||
| return true; | ||
|
|
||
| const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Value); | ||
| if (!SE) | ||
| return Error(LiteralLoc, "literal label must be a symbol"); | ||
| else { | ||
arsenm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Sym = getContext().getOrCreateSymbol(SE->getSymbol().getName()); | ||
| } | ||
|
|
||
| if (Parser.parseToken(AsmToken::Comma, "expected comma")) | ||
| return true; | ||
|
|
||
| SMLoc OpcodeLoc = getLexer().getLoc(); | ||
| if (parseOptionalToken(AsmToken::EndOfStatement)) | ||
| return Error(OpcodeLoc, "expected value"); | ||
|
|
||
| if (Parser.parseExpression(Value)) | ||
| return true; | ||
|
|
||
| TS.emitLiteral(Sym, Value, LiteralLoc); | ||
|
|
||
| return false; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The method should consume the terminating newline.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
| } | ||
|
|
||
| bool XtensaAsmParser::ParseDirective(AsmToken DirectiveID) { | ||
| StringRef IDVal = DirectiveID.getString(); | ||
| SMLoc Loc = getLexer().getLoc(); | ||
|
|
||
| if (IDVal == ".literal_position") { | ||
| XtensaTargetStreamer &TS = this->getTargetStreamer(); | ||
| TS.emitLiteralPosition(); | ||
| Lex(); | ||
| return false; | ||
|
||
| } | ||
|
|
||
| if (IDVal == ".literal") { | ||
| parseLiteralDirective(Loc); | ||
| Lex(); | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| // Force static initialization. | ||
| extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmParser() { | ||
| RegisterMCAsmParser<XtensaAsmParser> X(getTheXtensaTarget()); | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,87 @@ | ||||||
| //===-- XtensaTargetStreamer.cpp - Xtensa Target Streamer Methods ---------===// | ||||||
| // | ||||||
| // The LLVM Compiler Infrastructure | ||||||
| // | ||||||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||||
| // See https://llvm.org/LICENSE.txt for license information. | ||||||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||
| // | ||||||
| //===----------------------------------------------------------------------===// | ||||||
| // | ||||||
| // This file provides Xtensa specific target streamer methods. | ||||||
| // | ||||||
| //===----------------------------------------------------------------------===// | ||||||
|
|
||||||
| #include "XtensaTargetStreamer.h" | ||||||
| #include "XtensaInstPrinter.h" | ||||||
| #include "llvm/BinaryFormat/ELF.h" | ||||||
| #include "llvm/MC/MCAssembler.h" | ||||||
| #include "llvm/MC/MCContext.h" | ||||||
| #include "llvm/MC/MCObjectFileInfo.h" | ||||||
| #include "llvm/MC/MCSectionELF.h" | ||||||
| #include "llvm/Support/FormattedStream.h" | ||||||
|
|
||||||
| using namespace llvm; | ||||||
|
|
||||||
| XtensaTargetStreamer::XtensaTargetStreamer(MCStreamer &S) | ||||||
| : MCTargetStreamer(S) {} | ||||||
|
|
||||||
| XtensaTargetAsmStreamer::XtensaTargetAsmStreamer(MCStreamer &S, | ||||||
| formatted_raw_ostream &OS) | ||||||
| : XtensaTargetStreamer(S), OS(OS) {} | ||||||
|
|
||||||
| void XtensaTargetAsmStreamer::emitLiteral(MCSymbol *LblSym, const MCExpr *Value, | ||||||
| SMLoc L) { | ||||||
| const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); | ||||||
|
|
||||||
| OS << "\t.literal\t"; | ||||||
| LblSym->print(OS, MAI); | ||||||
| OS << ", "; | ||||||
| Value->print(OS, MAI); | ||||||
| OS << '\n'; | ||||||
| } | ||||||
|
|
||||||
| void XtensaTargetAsmStreamer::emitLiteralPosition() { | ||||||
| OS << "\t.literal_position\n"; | ||||||
| } | ||||||
|
|
||||||
| XtensaTargetELFStreamer::XtensaTargetELFStreamer(MCStreamer &S) | ||||||
| : XtensaTargetStreamer(S) {} | ||||||
|
|
||||||
| static std::string getLiteralSectionName(std::string CSectionName) { | ||||||
| std::size_t Pos = CSectionName.find(".text"); | ||||||
| std::string SectionName; | ||||||
| if (Pos != std::string::npos) { | ||||||
| if (Pos > 0) | ||||||
| SectionName = CSectionName.substr(0, Pos + 5); | ||||||
arsenm marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| else | ||||||
| SectionName = ""; | ||||||
| SectionName += ".literal"; | ||||||
| SectionName += CSectionName.substr(Pos + 5); | ||||||
| } else { | ||||||
| SectionName = CSectionName; | ||||||
| SectionName += ".literal"; | ||||||
| } | ||||||
| return SectionName; | ||||||
| } | ||||||
|
|
||||||
| void XtensaTargetELFStreamer::emitLiteral(MCSymbol *LblSym, const MCExpr *Value, | ||||||
| SMLoc L) { | ||||||
| MCContext &Context = getStreamer().getContext(); | ||||||
| MCStreamer &OutStreamer = getStreamer(); | ||||||
| MCSectionELF *CS = (MCSectionELF *)OutStreamer.getCurrentSectionOnly(); | ||||||
|
||||||
| MCSectionELF *CS = (MCSectionELF *)OutStreamer.getCurrentSectionOnly(); | |
| auto *CS = static_cast<MCSectionELF *>OutStreamer.getCurrentSectionOnly(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is deprecated, use
parseDirective(starting with lowercase letter).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed