Skip to content

Commit 4689ab3

Browse files
committed
[Xtensa] Implement call lowering.
Implement lowering call operations. Implement stack pseudo instructions ADJCALLSTACKDOWN, ADJCALLSTACKUP. Implement basic support of the ConstantPool, integer and symbols constants placement in literal section.
1 parent 3a0dff0 commit 4689ab3

25 files changed

+1594
-15
lines changed

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

Lines changed: 134 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+
bool 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,13 @@ 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 {
166+
if (Kind == Immediate)
167+
return true;
168+
169+
return false;
170+
}
152171

153172
bool isOffset4m32() const {
154173
return isImm(0, 60) &&
@@ -348,6 +367,67 @@ static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
348367
return Loc;
349368
}
350369

370+
bool XtensaAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
371+
MCStreamer &Out,
372+
const MCSubtargetInfo *STI) {
373+
Inst.setLoc(IDLoc);
374+
const unsigned Opcode = Inst.getOpcode();
375+
switch (Opcode) {
376+
case Xtensa::L32R: {
377+
const MCSymbolRefExpr *OpExpr =
378+
(const MCSymbolRefExpr *)Inst.getOperand(1).getExpr();
379+
XtensaMCExpr::VariantKind Kind = XtensaMCExpr::VK_Xtensa_None;
380+
const MCExpr *NewOpExpr = XtensaMCExpr::create(OpExpr, Kind, getContext());
381+
Inst.getOperand(1).setExpr(NewOpExpr);
382+
} break;
383+
case Xtensa::MOVI: {
384+
XtensaTargetStreamer &TS = this->getTargetStreamer();
385+
386+
// Expand MOVI operand
387+
if (!Inst.getOperand(1).isExpr()) {
388+
uint64_t ImmOp64 = Inst.getOperand(1).getImm();
389+
int32_t Imm = ImmOp64;
390+
if ((Imm < -2048) || (Imm > 2047)) {
391+
XtensaTargetStreamer &TS = this->getTargetStreamer();
392+
MCInst TmpInst;
393+
TmpInst.setLoc(IDLoc);
394+
TmpInst.setOpcode(Xtensa::L32R);
395+
const MCExpr *Value = MCConstantExpr::create(ImmOp64, getContext());
396+
MCSymbol *Sym = getContext().createTempSymbol();
397+
const MCExpr *Expr = MCSymbolRefExpr::create(
398+
Sym, MCSymbolRefExpr::VK_None, getContext());
399+
const MCExpr *OpExpr = XtensaMCExpr::create(
400+
Expr, XtensaMCExpr::VK_Xtensa_None, getContext());
401+
TmpInst.addOperand(Inst.getOperand(0));
402+
MCOperand Op1 = MCOperand::createExpr(OpExpr);
403+
TmpInst.addOperand(Op1);
404+
TS.emitLiteral(Sym, Value, IDLoc);
405+
Inst = TmpInst;
406+
}
407+
} else {
408+
MCInst TmpInst;
409+
TmpInst.setLoc(IDLoc);
410+
TmpInst.setOpcode(Xtensa::L32R);
411+
const MCExpr *Value = Inst.getOperand(1).getExpr();
412+
MCSymbol *Sym = getContext().createTempSymbol();
413+
const MCExpr *Expr =
414+
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
415+
const MCExpr *OpExpr = XtensaMCExpr::create(
416+
Expr, XtensaMCExpr::VK_Xtensa_None, getContext());
417+
TmpInst.addOperand(Inst.getOperand(0));
418+
MCOperand Op1 = MCOperand::createExpr(OpExpr);
419+
TmpInst.addOperand(Op1);
420+
Inst = TmpInst;
421+
TS.emitLiteral(Sym, Value, IDLoc);
422+
}
423+
} break;
424+
default:
425+
break;
426+
}
427+
428+
return true;
429+
}
430+
351431
bool XtensaAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
352432
OperandVector &Operands,
353433
MCStreamer &Out,
@@ -361,6 +441,7 @@ bool XtensaAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
361441
default:
362442
break;
363443
case Match_Success:
444+
processInstruction(Inst, IDLoc, Out, STI);
364445
Inst.setLoc(IDLoc);
365446
Out.emitInstruction(Inst, getSTI());
366447
return false;
@@ -686,6 +767,58 @@ bool XtensaAsmParser::ParseInstruction(ParseInstructionInfo &Info,
686767
return false;
687768
}
688769

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

llvm/lib/Target/Xtensa/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ add_public_tablegen_target(XtensaCommonTableGen)
1616

1717
add_llvm_target(XtensaCodeGen
1818
XtensaAsmPrinter.cpp
19+
XtensaConstantPoolValue.cpp
1920
XtensaFrameLowering.cpp
2021
XtensaInstrInfo.cpp
2122
XtensaISelDAGToDAG.cpp

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: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "XtensaMCTargetDesc.h"
1111
#include "XtensaInstPrinter.h"
1212
#include "XtensaMCAsmInfo.h"
13+
#include "XtensaTargetStreamer.h"
1314
#include "TargetInfo/XtensaTargetInfo.h"
1415
#include "llvm/ADT/STLExtras.h"
1516
#include "llvm/MC/MCAsmInfo.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
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
//===-- XtensaTargetStreamer.cpp - Xtensa Target Streamer Methods ---------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6+
// See https://llvm.org/LICENSE.txt for license information.
7+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
//
9+
//===----------------------------------------------------------------------===//
10+
//
11+
// This file provides Xtensa specific target streamer methods.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#include "XtensaTargetStreamer.h"
16+
#include "XtensaInstPrinter.h"
17+
#include "llvm/BinaryFormat/ELF.h"
18+
#include "llvm/MC/MCAssembler.h"
19+
#include "llvm/MC/MCContext.h"
20+
#include "llvm/MC/MCObjectFileInfo.h"
21+
#include "llvm/MC/MCSectionELF.h"
22+
#include "llvm/Support/FormattedStream.h"
23+
24+
using namespace llvm;
25+
26+
XtensaTargetStreamer::XtensaTargetStreamer(MCStreamer &S)
27+
: MCTargetStreamer(S) {}
28+
29+
XtensaTargetAsmStreamer::XtensaTargetAsmStreamer(MCStreamer &S,
30+
formatted_raw_ostream &OS)
31+
: XtensaTargetStreamer(S), OS(OS) {}
32+
33+
void XtensaTargetAsmStreamer::emitLiteral(MCSymbol *LblSym, const MCExpr *Value,
34+
SMLoc L) {
35+
const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
36+
37+
OS << "\t.literal\t";
38+
LblSym->print(OS, MAI);
39+
OS << ", ";
40+
Value->print(OS, MAI);
41+
OS << '\n';
42+
}
43+
44+
void XtensaTargetAsmStreamer::emitLiteralPosition() {
45+
OS << "\t.literal_position\n";
46+
}
47+
48+
XtensaTargetELFStreamer::XtensaTargetELFStreamer(MCStreamer &S)
49+
: XtensaTargetStreamer(S) {}
50+
51+
static std::string getLiteralSectionName(std::string CSectionName) {
52+
std::size_t Pos = CSectionName.find(".text");
53+
std::string SectionName;
54+
if (Pos != std::string::npos) {
55+
if (Pos > 0)
56+
SectionName = CSectionName.substr(0, Pos + 5);
57+
else
58+
SectionName = "";
59+
SectionName += ".literal";
60+
SectionName += CSectionName.substr(Pos + 5);
61+
} else {
62+
SectionName = CSectionName;
63+
SectionName += ".literal";
64+
}
65+
return SectionName;
66+
}
67+
68+
void XtensaTargetELFStreamer::emitLiteral(MCSymbol *LblSym, const MCExpr *Value,
69+
SMLoc L) {
70+
MCContext &Context = getStreamer().getContext();
71+
MCStreamer &OutStreamer = getStreamer();
72+
MCSectionELF *CS = (MCSectionELF *)OutStreamer.getCurrentSectionOnly();
73+
std::string SectionName = getLiteralSectionName(CS->getName().str());
74+
75+
MCSection *ConstSection = Context.getELFSection(
76+
SectionName, ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC);
77+
78+
OutStreamer.pushSection();
79+
OutStreamer.switchSection(ConstSection);
80+
OutStreamer.emitLabel(LblSym, L);
81+
OutStreamer.emitValue(Value, 4, L);
82+
OutStreamer.popSection();
83+
}
84+
85+
MCELFStreamer &XtensaTargetELFStreamer::getStreamer() {
86+
return static_cast<MCELFStreamer &>(Streamer);
87+
}

0 commit comments

Comments
 (0)