Skip to content

Commit 36209d3

Browse files
authored
[Xtensa] Implement base CallConvention. (#83280)
Implement base Calling Convention functionality. Implement stack load/store register operations. Implement call lowering.
1 parent 4182120 commit 36209d3

32 files changed

+2270
-17
lines changed

llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
//
99
//===----------------------------------------------------------------------===//
1010

11+
#include "MCTargetDesc/XtensaMCExpr.h"
1112
#include "MCTargetDesc/XtensaMCTargetDesc.h"
13+
#include "MCTargetDesc/XtensaTargetStreamer.h"
1214
#include "TargetInfo/XtensaTargetInfo.h"
1315
#include "llvm/ADT/STLExtras.h"
1416
#include "llvm/ADT/StringSwitch.h"
@@ -22,6 +24,7 @@
2224
#include "llvm/MC/MCRegisterInfo.h"
2325
#include "llvm/MC/MCStreamer.h"
2426
#include "llvm/MC/MCSubtargetInfo.h"
27+
#include "llvm/MC/MCSymbol.h"
2528
#include "llvm/MC/TargetRegistry.h"
2629
#include "llvm/Support/Casting.h"
2730

@@ -35,6 +38,12 @@ class XtensaAsmParser : public MCTargetAsmParser {
3538

3639
SMLoc getLoc() const { return getParser().getTok().getLoc(); }
3740

41+
XtensaTargetStreamer &getTargetStreamer() {
42+
MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
43+
return static_cast<XtensaTargetStreamer &>(TS);
44+
}
45+
46+
ParseStatus parseDirective(AsmToken DirectiveID) override;
3847
bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
3948
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4049
SMLoc NameLoc, OperandVector &Operands) override;
@@ -45,6 +54,9 @@ class XtensaAsmParser : public MCTargetAsmParser {
4554
unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
4655
unsigned Kind) override;
4756

57+
bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
58+
const MCSubtargetInfo *STI);
59+
4860
// Auto-generated instruction matching functions
4961
#define GET_ASSEMBLER_HEADER
5062
#include "XtensaGenAsmMatcher.inc"
@@ -62,6 +74,7 @@ class XtensaAsmParser : public MCTargetAsmParser {
6274
return ParseStatus::NoMatch;
6375
}
6476
ParseStatus parsePCRelTarget(OperandVector &Operands);
77+
bool parseLiteralDirective(SMLoc L);
6578

6679
public:
6780
enum XtensaMatchResultTy {
@@ -148,7 +161,8 @@ struct XtensaOperand : public MCParsedAsmOperand {
148161

149162
bool isImm12() const { return isImm(-2048, 2047); }
150163

151-
bool isImm12m() const { return isImm(-2048, 2047); }
164+
// Convert MOVI to literal load, when immediate is not in range (-2048, 2047)
165+
bool isImm12m() const { return Kind == Immediate; }
152166

153167
bool isOffset4m32() const {
154168
return isImm(0, 60) &&
@@ -348,6 +362,69 @@ static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
348362
return Loc;
349363
}
350364

365+
bool XtensaAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
366+
MCStreamer &Out,
367+
const MCSubtargetInfo *STI) {
368+
Inst.setLoc(IDLoc);
369+
const unsigned Opcode = Inst.getOpcode();
370+
switch (Opcode) {
371+
case Xtensa::L32R: {
372+
const MCSymbolRefExpr *OpExpr =
373+
static_cast<const MCSymbolRefExpr *>(Inst.getOperand(1).getExpr());
374+
XtensaMCExpr::VariantKind Kind = XtensaMCExpr::VK_Xtensa_None;
375+
const MCExpr *NewOpExpr = XtensaMCExpr::create(OpExpr, Kind, getContext());
376+
Inst.getOperand(1).setExpr(NewOpExpr);
377+
break;
378+
}
379+
case Xtensa::MOVI: {
380+
XtensaTargetStreamer &TS = this->getTargetStreamer();
381+
382+
// Expand MOVI operand
383+
if (!Inst.getOperand(1).isExpr()) {
384+
uint64_t ImmOp64 = Inst.getOperand(1).getImm();
385+
int32_t Imm = ImmOp64;
386+
if (!isInt<12>(Imm)) {
387+
XtensaTargetStreamer &TS = this->getTargetStreamer();
388+
MCInst TmpInst;
389+
TmpInst.setLoc(IDLoc);
390+
TmpInst.setOpcode(Xtensa::L32R);
391+
const MCExpr *Value = MCConstantExpr::create(ImmOp64, getContext());
392+
MCSymbol *Sym = getContext().createTempSymbol();
393+
const MCExpr *Expr = MCSymbolRefExpr::create(
394+
Sym, MCSymbolRefExpr::VK_None, getContext());
395+
const MCExpr *OpExpr = XtensaMCExpr::create(
396+
Expr, XtensaMCExpr::VK_Xtensa_None, getContext());
397+
TmpInst.addOperand(Inst.getOperand(0));
398+
MCOperand Op1 = MCOperand::createExpr(OpExpr);
399+
TmpInst.addOperand(Op1);
400+
TS.emitLiteral(Sym, Value, true, IDLoc);
401+
Inst = TmpInst;
402+
}
403+
} else {
404+
MCInst TmpInst;
405+
TmpInst.setLoc(IDLoc);
406+
TmpInst.setOpcode(Xtensa::L32R);
407+
const MCExpr *Value = Inst.getOperand(1).getExpr();
408+
MCSymbol *Sym = getContext().createTempSymbol();
409+
const MCExpr *Expr =
410+
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
411+
const MCExpr *OpExpr = XtensaMCExpr::create(
412+
Expr, XtensaMCExpr::VK_Xtensa_None, getContext());
413+
TmpInst.addOperand(Inst.getOperand(0));
414+
MCOperand Op1 = MCOperand::createExpr(OpExpr);
415+
TmpInst.addOperand(Op1);
416+
Inst = TmpInst;
417+
TS.emitLiteral(Sym, Value, true, IDLoc);
418+
}
419+
break;
420+
}
421+
default:
422+
break;
423+
}
424+
425+
return true;
426+
}
427+
351428
bool XtensaAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
352429
OperandVector &Operands,
353430
MCStreamer &Out,
@@ -361,6 +438,7 @@ bool XtensaAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
361438
default:
362439
break;
363440
case Match_Success:
441+
processInstruction(Inst, IDLoc, Out, STI);
364442
Inst.setLoc(IDLoc);
365443
Out.emitInstruction(Inst, getSTI());
366444
return false;
@@ -686,6 +764,57 @@ bool XtensaAsmParser::ParseInstruction(ParseInstructionInfo &Info,
686764
return false;
687765
}
688766

767+
bool XtensaAsmParser::parseLiteralDirective(SMLoc L) {
768+
MCAsmParser &Parser = getParser();
769+
const MCExpr *Value;
770+
SMLoc LiteralLoc = getLexer().getLoc();
771+
XtensaTargetStreamer &TS = this->getTargetStreamer();
772+
773+
if (Parser.parseExpression(Value))
774+
return true;
775+
776+
const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Value);
777+
778+
if (!SE)
779+
return Error(LiteralLoc, "literal label must be a symbol");
780+
781+
if (Parser.parseComma())
782+
return true;
783+
784+
SMLoc OpcodeLoc = getLexer().getLoc();
785+
if (parseOptionalToken(AsmToken::EndOfStatement))
786+
return Error(OpcodeLoc, "expected value");
787+
788+
if (Parser.parseExpression(Value))
789+
return true;
790+
791+
if (parseEOL())
792+
return true;
793+
794+
MCSymbol *Sym = getContext().getOrCreateSymbol(SE->getSymbol().getName());
795+
796+
TS.emitLiteral(Sym, Value, true, LiteralLoc);
797+
798+
return false;
799+
}
800+
801+
ParseStatus XtensaAsmParser::parseDirective(AsmToken DirectiveID) {
802+
StringRef IDVal = DirectiveID.getString();
803+
SMLoc Loc = getLexer().getLoc();
804+
805+
if (IDVal == ".literal_position") {
806+
XtensaTargetStreamer &TS = this->getTargetStreamer();
807+
TS.emitLiteralPosition();
808+
return parseEOL();
809+
}
810+
811+
if (IDVal == ".literal") {
812+
return parseLiteralDirective(Loc);
813+
}
814+
815+
return ParseStatus::NoMatch;
816+
}
817+
689818
// Force static initialization.
690819
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmParser() {
691820
RegisterMCAsmParser<XtensaAsmParser> X(getTheXtensaTarget());

llvm/lib/Target/Xtensa/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ set(LLVM_TARGET_DEFINITIONS Xtensa.td)
44

55
tablegen(LLVM XtensaGenAsmMatcher.inc -gen-asm-matcher)
66
tablegen(LLVM XtensaGenAsmWriter.inc -gen-asm-writer)
7+
tablegen(LLVM XtensaGenCallingConv.inc -gen-callingconv)
78
tablegen(LLVM XtensaGenDAGISel.inc -gen-dag-isel)
89
tablegen(LLVM XtensaGenDisassemblerTables.inc -gen-disassembler)
910
tablegen(LLVM XtensaGenInstrInfo.inc -gen-instr-info)
@@ -15,13 +16,15 @@ add_public_tablegen_target(XtensaCommonTableGen)
1516

1617
add_llvm_target(XtensaCodeGen
1718
XtensaAsmPrinter.cpp
19+
XtensaConstantPoolValue.cpp
1820
XtensaFrameLowering.cpp
1921
XtensaInstrInfo.cpp
2022
XtensaISelDAGToDAG.cpp
2123
XtensaISelLowering.cpp
2224
XtensaRegisterInfo.cpp
2325
XtensaSubtarget.cpp
2426
XtensaTargetMachine.cpp
27+
XtensaUtils.cpp
2528

2629
LINK_COMPONENTS
2730
AsmPrinter

llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ add_llvm_component_library(LLVMXtensaDesc
66
XtensaMCCodeEmitter.cpp
77
XtensaMCExpr.cpp
88
XtensaMCTargetDesc.cpp
9+
XtensaTargetStreamer.cpp
910

1011
LINK_COMPONENTS
1112
MC

llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
//
99
//===----------------------------------------------------------------------===//
1010
#include "XtensaMCTargetDesc.h"
11+
#include "TargetInfo/XtensaTargetInfo.h"
1112
#include "XtensaInstPrinter.h"
1213
#include "XtensaMCAsmInfo.h"
13-
#include "TargetInfo/XtensaTargetInfo.h"
14+
#include "XtensaTargetStreamer.h"
1415
#include "llvm/ADT/STLExtras.h"
1516
#include "llvm/MC/MCAsmInfo.h"
1617
#include "llvm/MC/MCInstrInfo.h"
@@ -63,16 +64,29 @@ createXtensaMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
6364
return createXtensaMCSubtargetInfoImpl(TT, CPU, CPU, FS);
6465
}
6566

67+
static MCTargetStreamer *
68+
createXtensaAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS,
69+
MCInstPrinter *InstPrint, bool isVerboseAsm) {
70+
return new XtensaTargetAsmStreamer(S, OS);
71+
}
72+
73+
static MCTargetStreamer *
74+
createXtensaObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
75+
return new XtensaTargetELFStreamer(S);
76+
}
77+
6678
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaTargetMC() {
6779
// Register the MCAsmInfo.
68-
TargetRegistry::RegisterMCAsmInfo(getTheXtensaTarget(), createXtensaMCAsmInfo);
80+
TargetRegistry::RegisterMCAsmInfo(getTheXtensaTarget(),
81+
createXtensaMCAsmInfo);
6982

7083
// Register the MCCodeEmitter.
7184
TargetRegistry::RegisterMCCodeEmitter(getTheXtensaTarget(),
7285
createXtensaMCCodeEmitter);
7386

7487
// Register the MCInstrInfo.
75-
TargetRegistry::RegisterMCInstrInfo(getTheXtensaTarget(), createXtensaMCInstrInfo);
88+
TargetRegistry::RegisterMCInstrInfo(getTheXtensaTarget(),
89+
createXtensaMCInstrInfo);
7690

7791
// Register the MCInstPrinter.
7892
TargetRegistry::RegisterMCInstPrinter(getTheXtensaTarget(),
@@ -89,4 +103,12 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaTargetMC() {
89103
// Register the MCAsmBackend.
90104
TargetRegistry::RegisterMCAsmBackend(getTheXtensaTarget(),
91105
createXtensaMCAsmBackend);
106+
107+
// Register the asm target streamer.
108+
TargetRegistry::RegisterAsmTargetStreamer(getTheXtensaTarget(),
109+
createXtensaAsmTargetStreamer);
110+
111+
// Register the ELF target streamer.
112+
TargetRegistry::RegisterObjectTargetStreamer(
113+
getTheXtensaTarget(), createXtensaObjectTargetStreamer);
92114
}

0 commit comments

Comments
 (0)