Skip to content
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] Implement base CallConvention. #83280

Merged
merged 6 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 130 additions & 1 deletion llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"

Expand All @@ -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);
}

ParseStatus parseDirective(AsmToken DirectiveID) override;
bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc, OperandVector &Operands) override;
Expand All @@ -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"
Expand All @@ -62,6 +74,7 @@ class XtensaAsmParser : public MCTargetAsmParser {
return ParseStatus::NoMatch;
}
ParseStatus parsePCRelTarget(OperandVector &Operands);
bool parseLiteralDirective(SMLoc L);

public:
enum XtensaMatchResultTy {
Expand Down Expand Up @@ -148,7 +161,8 @@ 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 { return Kind == Immediate; }

bool isOffset4m32() const {
return isImm(0, 60) &&
Expand Down Expand Up @@ -348,6 +362,69 @@ 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 =
static_cast<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 (!isInt<12>(Imm)) {
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, true, 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, true, IDLoc);
}
break;
}
default:
break;
}

return true;
}

bool XtensaAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
OperandVector &Operands,
MCStreamer &Out,
Expand All @@ -361,6 +438,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;
Expand Down Expand Up @@ -686,6 +764,57 @@ bool XtensaAsmParser::ParseInstruction(ParseInstructionInfo &Info,
return false;
}

bool XtensaAsmParser::parseLiteralDirective(SMLoc L) {
MCAsmParser &Parser = getParser();
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");

if (Parser.parseComma())
return true;

SMLoc OpcodeLoc = getLexer().getLoc();
if (parseOptionalToken(AsmToken::EndOfStatement))
return Error(OpcodeLoc, "expected value");

if (Parser.parseExpression(Value))
return true;

if (parseEOL())
return true;

MCSymbol *Sym = getContext().getOrCreateSymbol(SE->getSymbol().getName());

TS.emitLiteral(Sym, Value, true, LiteralLoc);

return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method should consume the terminating newline.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

}

ParseStatus XtensaAsmParser::parseDirective(AsmToken DirectiveID) {
StringRef IDVal = DirectiveID.getString();
SMLoc Loc = getLexer().getLoc();

if (IDVal == ".literal_position") {
XtensaTargetStreamer &TS = this->getTargetStreamer();
TS.emitLiteralPosition();
return parseEOL();
}

if (IDVal == ".literal") {
return parseLiteralDirective(Loc);
}

return ParseStatus::NoMatch;
}

// Force static initialization.
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmParser() {
RegisterMCAsmParser<XtensaAsmParser> X(getTheXtensaTarget());
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/Xtensa/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ 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)
Expand All @@ -15,13 +16,15 @@ add_public_tablegen_target(XtensaCommonTableGen)

add_llvm_target(XtensaCodeGen
XtensaAsmPrinter.cpp
XtensaConstantPoolValue.cpp
XtensaFrameLowering.cpp
XtensaInstrInfo.cpp
XtensaISelDAGToDAG.cpp
XtensaISelLowering.cpp
XtensaRegisterInfo.cpp
XtensaSubtarget.cpp
XtensaTargetMachine.cpp
XtensaUtils.cpp

LINK_COMPONENTS
AsmPrinter
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_llvm_component_library(LLVMXtensaDesc
XtensaMCCodeEmitter.cpp
XtensaMCExpr.cpp
XtensaMCTargetDesc.cpp
XtensaTargetStreamer.cpp

LINK_COMPONENTS
MC
Expand Down
28 changes: 25 additions & 3 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
//
//===----------------------------------------------------------------------===//
#include "XtensaMCTargetDesc.h"
#include "TargetInfo/XtensaTargetInfo.h"
#include "XtensaInstPrinter.h"
#include "XtensaMCAsmInfo.h"
#include "TargetInfo/XtensaTargetInfo.h"
#include "XtensaTargetStreamer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInstrInfo.h"
Expand Down Expand Up @@ -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(),
Expand All @@ -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);
}
Loading
Loading