-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
[Xtensa] Initial codegen support from IR #78548
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write If you have received no comments on your PR for a week, you can request a review If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-mc Author: Andrei Safronov (andreisfr) ChangesThis PR provides implementation of the basic codegen infra such as TargetFrameLowering, CallingConv, TargetLowering, SelectionDAGISe. Initial ConstantPool support has also been implemented. The PR contains five commits that were originally published on Phabricator (third patch is approved), each commit depends on previous commits, and together these patches provide support for more complex IR tests. Patches have been updated based on reviewers comments from Phabricator and slightly refactored. Migrated from: Patch is 117.73 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/78548.diff 42 Files Affected:
diff --git a/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp b/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
index 3f808298527f8fc..9fd05ee96a9290d 100644
--- a/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
+++ b/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
@@ -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;
+ }
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();
+ 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)) {
+ 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;
+ 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;
+ 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 {
+ 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;
+}
+
+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());
diff --git a/llvm/lib/Target/Xtensa/CMakeLists.txt b/llvm/lib/Target/Xtensa/CMakeLists.txt
index 7192f7392072b31..f0abf3e550a124e 100644
--- a/llvm/lib/Target/Xtensa/CMakeLists.txt
+++ b/llvm/lib/Target/Xtensa/CMakeLists.txt
@@ -4,6 +4,8 @@ set(LLVM_TARGET_DEFINITIONS Xtensa.td)
tablegen(LLVM XtensaGenAsmMatcher.inc -gen-asm-matcher)
tablegen(LLVM XtensaGenAsmWriter.inc -gen-asm-writer)
+tablegen(LLVM XtensaGenCallingConv.inc -gen-callingconv)
+tablegen(LLVM XtensaGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM XtensaGenDisassemblerTables.inc -gen-disassembler)
tablegen(LLVM XtensaGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM XtensaGenMCCodeEmitter.inc -gen-emitter)
@@ -13,13 +15,24 @@ tablegen(LLVM XtensaGenSubtargetInfo.inc -gen-subtarget)
add_public_tablegen_target(XtensaCommonTableGen)
add_llvm_target(XtensaCodeGen
+ XtensaAsmPrinter.cpp
+ XtensaConstantPoolValue.cpp
+ XtensaFrameLowering.cpp
+ XtensaInstrInfo.cpp
+ XtensaISelDAGToDAG.cpp
+ XtensaISelLowering.cpp
+ XtensaMCInstLower.cpp
+ XtensaRegisterInfo.cpp
+ XtensaSubtarget.cpp
XtensaTargetMachine.cpp
+ XtensaUtils.cpp
LINK_COMPONENTS
AsmPrinter
CodeGen
Core
MC
+ SelectionDAG
Support
Target
XtensaDesc
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
index 6841b44f9d569cd..dc12863394c7ad0 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
@@ -6,6 +6,7 @@ add_llvm_component_library(LLVMXtensaDesc
XtensaMCCodeEmitter.cpp
XtensaMCExpr.cpp
XtensaMCTargetDesc.cpp
+ XtensaTargetStreamer.cpp
LINK_COMPONENTS
MC
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
index db4484bb57c1ad7..c87e2187b73d4e6 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
@@ -84,7 +84,7 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
unsigned Kind = Fixup.getKind();
switch (Kind) {
default:
- llvm_unreachable("Unknown fixup kind!");
+ report_fatal_error("Unknown fixup kind!");
case FK_Data_1:
case FK_Data_2:
case FK_Data_4:
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
index fe1dc0e2e483e72..f234d5e900a472a 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
@@ -102,7 +102,7 @@ void XtensaInstPrinter::printBranchTarget(const MCInst *MI, int OpNum,
} else if (MC.isExpr())
MC.getExpr()->print(OS, &MAI, true);
else
- llvm_unreachable("Invalid operand");
+ report_fatal_error("Invalid operand");
}
void XtensaInstPrinter::printJumpTarget(const MCInst *MI, int OpNum,
@@ -117,7 +117,7 @@ void XtensaInstPrinter::printJumpTarget(const MCInst *MI, int OpNum,
} else if (MC.isExpr())
MC.getExpr()->print(OS, &MAI, true);
else
- llvm_unreachable("Invalid operand");
+ report_fatal_error("Invalid operand");
;
}
@@ -133,7 +133,7 @@ void XtensaInstPrinter::printCallOperand(const MCInst *MI, int OpNum,
} else if (MC.isExpr())
MC.getExpr()->print(OS, &MAI, true);
else
- llvm_unreachable("Invalid operand");
+ report_fatal_error("Invalid operand");
}
void XtensaInstPrinter::printL32RTarget(const MCInst *MI, int OpNum,
@@ -151,7 +151,7 @@ void XtensaInstPrinter::printL32RTarget(const MCInst *MI, int OpNum,
} else if (MC.isExpr())
MC.getExpr()->print(O, &MAI, true);
else
- llvm_unreachable("Invalid operand");
+ report_fatal_error("Invalid operand");
}
void XtensaInstPrinter::printImm8_AsmOperand(const MCInst *MI, int OpNum,
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
index 1afdbb38f9571a2..c6941499cba192d 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
@@ -203,7 +203,7 @@ XtensaMCCodeEmitter::getCallEncoding(const MCInst &MI, unsigned int OpNum,
if (MO.isImm()) {
int32_t Res = MO.getImm();
if (Res & 0x3) {
- llvm_unreachable("Unexpected operand value!");
+ report_fatal_error("Unexpected operand value!");
}
Res >>= 2;
return Res;
@@ -396,7 +396,7 @@ XtensaMCCodeEmitter::getB4constOpValue(const MCInst &MI, unsigned OpNo,
Res = 15;
break;
default:
- llvm_unreachable("Unexpected operand value!");
+ report_fatal_error("Unexpected operand value!");
}
return Res;
@@ -446,7 +446,7 @@ XtensaMCCodeEmitter::getB4constuOpValue(const MCInst &MI, unsigned OpNo,
Res = 15;
break;
default:
- llvm_unreachable("Unexpected operand value!");
+ report_fatal_error("Unexpected operand value!");
}
return Res;
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.cpp
index cafd8b7e2978202..2d0db1aae0645b3 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.cpp
@@ -58,6 +58,6 @@ XtensaMCExpr::VariantKind XtensaMCExpr::getVariantKindForName(StringRef name) {
StringRef XtensaMCExpr::getVariantKindName(VariantKind Kind) {
switch (Kind) {
default:
- llvm_unreachable("Invalid ELF symbol kind");
+ report_fatal_error("Invalid ELF symbol kind");
}
}
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
index 48674d15bdfbe27..8914ebf658cc434 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
@@ -10,6 +10,7 @@
#include "XtensaMCTargetDesc.h"
#include "XtensaInstPrinter.h"
#include "XtensaMCAsmInfo.h"
+#include "XtensaTargetStreamer.h"
#include "TargetInfo/XtensaTargetInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -63,16 +64,29 @@ createXtensaMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
return createXtensaMCSubtargetInfoImpl(TT, CPU, CPU, FS);
}
+static MCTargetStreamer *
+createXtensaAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS,
+ MCInstPrinter *InstPrint, bool isVerboseAsm) {
+ return new XtensaTargetAsmStreamer(S, OS);
+}
+
+static MCTargetStreamer *
+createXtensaObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
+ return new XtensaTargetELFStreamer(S);
+}
+
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaTargetMC() {
// Register the MCAsmInfo.
- TargetRegistry::RegisterMCAsmInfo(getTheXtensaTarget(), createXtensaMCAsmInfo);
+ TargetRegistry::RegisterMCAsmInfo(getTheXtensaTarget(),
+ createXtensaMCAsmInfo);
// Register the MCCodeEmitter.
TargetRegistry::RegisterMCCodeEmitter(getTheXtensaTarget(),
createXtensaMCCodeEmitter);
// Register the MCInstrInfo.
- TargetRegistry::RegisterMCInstrInfo(getTheXtensaTarget(), createXtensaMCInstrInfo);
+ TargetRegistry::RegisterMCInstrInfo(getTheXtensaTarget(),
+ createXtensaMCInstrInfo);
// Register the MCInstPrinter.
TargetRegistry::RegisterMCInstPrinter(getTheXtensaTarget(),
@@ -89,4 +103,12 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaTargetMC() {
// Register the MCAsmBackend.
TargetRegistry::RegisterMCAsmBackend(getTheXtensaTarget(),
createXtensaMCAsmBackend);
+
+ // Register the asm target streamer.
+ TargetRegistry::RegisterAsmTargetStreamer(getTheXtensaTarget(),
+ createXtensaAsmTargetStreamer);
+
+ // Register the ELF target streamer.
+ TargetRegistry::RegisterObjectTargetStreamer(
+ getTheXtensaTarget(), createXtensaObjectTargetStreamer);
}
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.cpp
new file mode 100644
index 000000000000000..4163e64de48f091
--- /dev/null
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.cpp
@@ -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);
+ 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();
+ std::string SectionName = getLiteralSectionName(CS->getName().str());
+
+ MCSection *ConstSection = Context.getELFSection(
+ SectionName, ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC);
+
+ OutStreamer.pushSection();
+ OutStreamer.switchSection(ConstSection);
+ OutStreamer.emitLabel(LblSym, L);
+ OutStreamer.emitValue(Value, 4, L);
+ OutStreamer.popSection();
+}
+
+MCELFStreamer &XtensaTargetELFStreamer::getStreamer() {
+ return static_cast<MCELFStreamer &>(Streamer);
+}
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.h b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.h
new file mode 100644
index 000000000000000..a7d8b6dd9c792b5
--- /dev/null
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.h
@@ -0,0 +1,46 @@
+//===-- XtensaTargetStreamer.h - Xtensa Target Streamer --------*- C++ -*--===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_XTENSA_XTENSATARGETSTREAMER_H
+#define LLVM_LIB_TARGET_XTENSA_XTENSATARGETSTREAMER_H
+
+#include "llvm/MC/MCELFStreamer.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/Support/SMLoc.h"
+
+namespace llvm {
+class formatted_raw_ostream;
+
+class XtensaTargetStreamer : public MCTargetStreamer {
+public:
+ XtensaTargetStreamer(MCStreamer &S);
+ virtual void emitLiteral(MCSymbol *LblSym, const MCExpr *Value, SMLoc L) = 0;
+ virtual void emitLiteralPosition() = 0;
+};
+
+class XtensaTargetAsmStreamer : public XtensaTargetStreamer {
+ formatted_raw_ostream &OS;
+
+public:
+ XtensaTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
+ void emitLiteral(MCSymbol *LblSym, const MCExpr *Value, SMLoc L) override;
+ void emitLiteralPosition() override;
+};
+
+class XtensaTargetELFStreamer : public XtensaTargetStreamer {
+public:
+ XtensaTargetELFStreamer(MCStreamer &S);
+ MCELFStreamer &getStreamer();
+ void emitLiteral(MCSymbol *LblSym, const MCExpr *Value, SMLoc L) override;
+ void emitLiteralPosition() override {}
+};
+} // end namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/Xtensa/Xtensa.h b/llvm/lib/Target/Xtensa/Xtensa.h
new file mode...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Unfortunately you should open a separate PR for each of these changes |
6f375b3
to
fdb8e58
Compare
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.
Calling convention implementation needs to be in separate PR. It should support passing arguments on the stack, which requires implementing some methods in *FrameLowering, *InstrInfo and *RegisterInfo, as well as supporting load/store/call/return in ISel.
I would also suggest a separate PR for boilerplate classes, i.e. *RegisterInfo, *InstrInfo, *Subtarget, *FrameLowering, *TargetMachine, *AsmPrinter and *DAGToDAGISel. You can check that everything works by launching llc on an empty *.ll file (it should produce a template assembly (-filetype=asm) and object (-filetype=obj) files without crashing).
Supporting ALU operations should then touch only files related to instruction selection. (There may be other minor changes in other files.)
Changes in MCTargetDesc/ look completely unrelated.
Thanks for the comment. Do I understand correctly that you are proposing to split this patch into three patches (the last one will be with ALU operations)? |
Yes, that's what I'm proposing. |
074c148
to
45525f6
Compare
Thank you. I removed the Calling Convention functionality from this commit and will prepare a separate patch with it. |
Thanks, I removed redundant commits. |
45525f6
to
22a85f7
Compare
I think the patch series https://reviews.llvm.org/D145658 may be too fine-grained. It might be better to pack more changes in one PR, otherwise there could be a lot of For CMake changes, I always check the first two of the following configurations. A
|
|
||
XtensaSubtarget::XtensaSubtarget(const Triple &TT, const std::string &CPU, | ||
const std::string &FS, const TargetMachine &TM) | ||
: XtensaGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), TargetTriple(TT), |
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.
Canonical style is /*TuneCPU=*/CPU
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.
Thank you very much for comments. Fixed
class XtensaSubtarget; | ||
class XtensaInstrInfo : public XtensaGenInstrInfo { | ||
const XtensaRegisterInfo RI; | ||
XtensaSubtarget &STI; |
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.
Please ensure that each incremental change does not cause new warnings when compiled with a recent Clang.
You may use https://raw.githubusercontent.com/chromium/chromium/main/tools/clang/scripts/update.py
warning: private field 'STI' is not used [-Wunused-private-field]
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, I implemented "getSubtarget()" function.
class XtensaAsmPrinter; | ||
|
||
class LLVM_LIBRARY_VISIBILITY XtensaMCInstLower { | ||
MCContext &Ctx; |
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.
warning: private field 'Ctx' is not used [-Wunused-private-field]
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.
Fxied.
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.
lgtm with some nits
// hasFP - Return true if the specified function should have a dedicated frame | ||
// pointer register. This is true if the function has variable sized allocas or | ||
// if frame pointer elimination is disabled. |
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.
I wouldn't bother duplicating the base implementation comment here
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.
Thank you very much for comments. Fixed
} | ||
|
||
const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const { | ||
return NULL; |
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.
nullptr
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
int SPAdj, unsigned FIOperandNum, | ||
RegScavenger *RS) const { | ||
report_fatal_error("Eliminate frame index not supported yet"); | ||
return false; |
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.
dead return
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
|
||
Register XtensaRegisterInfo::getFrameRegister(const MachineFunction &MF) const { | ||
const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); | ||
return TFI->hasFP(MF) ? (Xtensa::A15) : Xtensa::SP; |
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.
No () around register name.
Also should do getSubtarget()
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
@MaskRay sorry for bothering you. I am from Espressif LLVM team.
Looks like this conflicts with suggestions from @s-barannikov #78548 (review). As far as I understood he proposed to split it into more fine-grained commits. |
The split is better to review, but the pieces should build warning free and come with the relevant tests. I think this patch is fine with the warnings 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.
LGTM with comments in XtensaTargetMachine.h addressed.
XtensaSubtarget(const Triple &TT, const std::string &CPU, | ||
const std::string &FS, const TargetMachine &TM); | ||
|
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.
const std::string & -> StringRef
TT parameter is redundant as it can be obtained from TM.
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 "const std::string" problem. Do you mean we should use XtensaSubtarget constructor prototype without TT argument?
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.
Yes, but this is a very minor issue. Most backends do pass it.
34e6e4e
to
c19abd4
Compare
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.
LGTM, final style nits
Initial codegen support for IR tests. Added basic implementation of the TargetFrameLowering, MCInstLower, AsmPrinter, RegisterInfo, InstructionInfo, TargetLowering, SelectionDAGISel.
c19abd4
to
00b6664
Compare
I'll land this patch on your behalf tomorrow, unless someone objects it, assuming that you do not have write access yet! |
Thank you! |
This PR provides implementation of the basic codegen infra such as TargetFrameLowering, MCInstLower,
AsmPrinter, RegisterInfo, InstructionInfo, TargetLowering, SelectionDAGISel.
Migrated from https://reviews.llvm.org/D145658