Skip to content

Commit b5046a7

Browse files
authored
[Xtensa] Initial codegen support from IR (#78548)
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
1 parent 3033822 commit b5046a7

19 files changed

+769
-1
lines changed

llvm/lib/Target/Xtensa/CMakeLists.txt

Lines changed: 9 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 XtensaGenDAGISel.inc -gen-dag-isel)
78
tablegen(LLVM XtensaGenDisassemblerTables.inc -gen-disassembler)
89
tablegen(LLVM XtensaGenInstrInfo.inc -gen-instr-info)
910
tablegen(LLVM XtensaGenMCCodeEmitter.inc -gen-emitter)
@@ -13,13 +14,21 @@ tablegen(LLVM XtensaGenSubtargetInfo.inc -gen-subtarget)
1314
add_public_tablegen_target(XtensaCommonTableGen)
1415

1516
add_llvm_target(XtensaCodeGen
17+
XtensaAsmPrinter.cpp
18+
XtensaFrameLowering.cpp
19+
XtensaInstrInfo.cpp
20+
XtensaISelDAGToDAG.cpp
21+
XtensaISelLowering.cpp
22+
XtensaRegisterInfo.cpp
23+
XtensaSubtarget.cpp
1624
XtensaTargetMachine.cpp
1725

1826
LINK_COMPONENTS
1927
AsmPrinter
2028
CodeGen
2129
Core
2230
MC
31+
SelectionDAG
2332
Support
2433
Target
2534
XtensaDesc

llvm/lib/Target/Xtensa/Xtensa.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===- Xtensa.h - Top-level interface for Xtensa representation -*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file contains the entry points for global functions defined in
10+
// the LLVM Xtensa back-end.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_LIB_TARGET_XTENSA_XTENSA_H
15+
#define LLVM_LIB_TARGET_XTENSA_XTENSA_H
16+
17+
#include "MCTargetDesc/XtensaMCTargetDesc.h"
18+
#include "llvm/PassRegistry.h"
19+
#include "llvm/Support/CodeGen.h"
20+
21+
namespace llvm {
22+
class XtensaTargetMachine;
23+
class FunctionPass;
24+
25+
FunctionPass *createXtensaISelDag(XtensaTargetMachine &TM,
26+
CodeGenOptLevel OptLevel);
27+
} // namespace llvm
28+
#endif // LLVM_LIB_TARGET_XTENSA_XTENSA_H
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===- XtensaAsmPrinter.cpp Xtensa LLVM Assembly Printer ------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file contains a printer that converts from our internal representation
10+
// of machine-dependent LLVM code to GAS-format Xtensa assembly language.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "XtensaAsmPrinter.h"
15+
#include "TargetInfo/XtensaTargetInfo.h"
16+
#include "llvm/BinaryFormat/ELF.h"
17+
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
18+
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
19+
#include "llvm/MC/MCExpr.h"
20+
#include "llvm/MC/MCSectionELF.h"
21+
#include "llvm/MC/MCStreamer.h"
22+
#include "llvm/MC/MCSymbol.h"
23+
#include "llvm/MC/MCSymbolELF.h"
24+
#include "llvm/MC/TargetRegistry.h"
25+
26+
using namespace llvm;
27+
28+
void XtensaAsmPrinter::emitInstruction(const MachineInstr *MI) {
29+
MCInst LoweredMI;
30+
lowerToMCInst(MI, LoweredMI);
31+
EmitToStreamer(*OutStreamer, LoweredMI);
32+
}
33+
34+
MCOperand XtensaAsmPrinter::lowerOperand(const MachineOperand &MO,
35+
unsigned Offset) const {
36+
MachineOperand::MachineOperandType MOTy = MO.getType();
37+
38+
switch (MOTy) {
39+
case MachineOperand::MO_Register:
40+
// Ignore all implicit register operands.
41+
if (MO.isImplicit())
42+
break;
43+
return MCOperand::createReg(MO.getReg());
44+
case MachineOperand::MO_Immediate:
45+
return MCOperand::createImm(MO.getImm() + Offset);
46+
case MachineOperand::MO_RegisterMask:
47+
break;
48+
default:
49+
report_fatal_error("unknown operand type");
50+
}
51+
52+
return MCOperand();
53+
}
54+
55+
void XtensaAsmPrinter::lowerToMCInst(const MachineInstr *MI,
56+
MCInst &OutMI) const {
57+
OutMI.setOpcode(MI->getOpcode());
58+
59+
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
60+
const MachineOperand &MO = MI->getOperand(i);
61+
MCOperand MCOp = lowerOperand(MO);
62+
63+
if (MCOp.isValid())
64+
OutMI.addOperand(MCOp);
65+
}
66+
}
67+
68+
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmPrinter() {
69+
RegisterAsmPrinter<XtensaAsmPrinter> A(getTheXtensaTarget());
70+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===- XtensaAsmPrinter.h - Xtensa LLVM Assembly Printer --------*- C++-*--===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Xtensa Assembly printer class.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_LIB_TARGET_XTENSA_XTENSAASMPRINTER_H
14+
#define LLVM_LIB_TARGET_XTENSA_XTENSAASMPRINTER_H
15+
16+
#include "XtensaTargetMachine.h"
17+
#include "llvm/CodeGen/AsmPrinter.h"
18+
#include "llvm/Support/Compiler.h"
19+
20+
namespace llvm {
21+
class MCStreamer;
22+
class MachineBasicBlock;
23+
class MachineInstr;
24+
class Module;
25+
class raw_ostream;
26+
27+
class LLVM_LIBRARY_VISIBILITY XtensaAsmPrinter : public AsmPrinter {
28+
const MCSubtargetInfo *STI;
29+
30+
public:
31+
explicit XtensaAsmPrinter(TargetMachine &TM,
32+
std::unique_ptr<MCStreamer> Streamer)
33+
: AsmPrinter(TM, std::move(Streamer)), STI(TM.getMCSubtargetInfo()) {}
34+
35+
StringRef getPassName() const override { return "Xtensa Assembly Printer"; }
36+
void emitInstruction(const MachineInstr *MI) override;
37+
38+
// Lower MachineInstr MI to MCInst OutMI.
39+
void lowerToMCInst(const MachineInstr *MI, MCInst &OutMI) const;
40+
41+
// Return an MCOperand for MO. Return an empty operand if MO is implicit.
42+
MCOperand lowerOperand(const MachineOperand &MO, unsigned Offset = 0) const;
43+
};
44+
} // end namespace llvm
45+
46+
#endif /* LLVM_LIB_TARGET_XTENSA_XTENSAASMPRINTER_H */
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===- XtensaFrameLowering.cpp - Xtensa Frame Information -----------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file contains the Xtensa implementation of TargetFrameLowering class.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "XtensaFrameLowering.h"
14+
#include "XtensaInstrInfo.h"
15+
#include "XtensaSubtarget.h"
16+
#include "llvm/CodeGen/MachineFrameInfo.h"
17+
#include "llvm/CodeGen/MachineInstrBuilder.h"
18+
#include "llvm/CodeGen/MachineModuleInfo.h"
19+
#include "llvm/CodeGen/MachineRegisterInfo.h"
20+
#include "llvm/CodeGen/RegisterScavenging.h"
21+
#include "llvm/IR/Function.h"
22+
23+
using namespace llvm;
24+
25+
XtensaFrameLowering::XtensaFrameLowering()
26+
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(4), 0,
27+
Align(4)) {}
28+
29+
bool XtensaFrameLowering::hasFP(const MachineFunction &MF) const {
30+
const MachineFrameInfo &MFI = MF.getFrameInfo();
31+
return MF.getTarget().Options.DisableFramePointerElim(MF) ||
32+
MFI.hasVarSizedObjects();
33+
}
34+
35+
void XtensaFrameLowering::emitPrologue(MachineFunction &MF,
36+
MachineBasicBlock &MBB) const {}
37+
38+
void XtensaFrameLowering::emitEpilogue(MachineFunction &MF,
39+
MachineBasicBlock &MBB) const {}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===- XtensaFrameLowering.h - Define frame lowering for Xtensa --*- C++ -*-==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===-----------------------------------------------------------------------==//
8+
9+
#ifndef LLVM_LIB_TARGET_XTENSA_XTENSAFRAMELOWERING_H
10+
#define LLVM_LIB_TARGET_XTENSA_XTENSAFRAMELOWERING_H
11+
12+
#include "llvm/CodeGen/TargetFrameLowering.h"
13+
14+
namespace llvm {
15+
class XtensaTargetMachine;
16+
class XtensaSubtarget;
17+
18+
class XtensaFrameLowering : public TargetFrameLowering {
19+
public:
20+
XtensaFrameLowering();
21+
22+
bool hasFP(const MachineFunction &MF) const override;
23+
24+
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
25+
/// the function.
26+
void emitPrologue(MachineFunction &, MachineBasicBlock &) const override;
27+
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
28+
};
29+
30+
} // namespace llvm
31+
32+
#endif /* LLVM_LIB_TARGET_XTENSA_XTENSAFRAMELOWERING_H */
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//===- XtensaISelDAGToDAG.cpp - A dag to dag inst selector for Xtensa -----===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines an instruction selector for the Xtensa target.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "Xtensa.h"
14+
#include "XtensaTargetMachine.h"
15+
#include "llvm/CodeGen/MachineFunction.h"
16+
#include "llvm/CodeGen/MachineRegisterInfo.h"
17+
#include "llvm/CodeGen/SelectionDAGISel.h"
18+
#include "llvm/Support/Debug.h"
19+
#include "llvm/Support/raw_ostream.h"
20+
21+
using namespace llvm;
22+
23+
#define DEBUG_TYPE "xtensa-isel"
24+
25+
namespace {
26+
27+
class XtensaDAGToDAGISel : public SelectionDAGISel {
28+
public:
29+
static char ID;
30+
31+
XtensaDAGToDAGISel(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel)
32+
: SelectionDAGISel(ID, TM, OptLevel) {}
33+
34+
StringRef getPassName() const override {
35+
return "Xtensa DAG->DAG Pattern Instruction Selection";
36+
}
37+
38+
void Select(SDNode *Node) override;
39+
40+
bool selectMemRegAddr(SDValue Addr, SDValue &Base, SDValue &Offset,
41+
int Scale) {
42+
report_fatal_error("MemReg address is not implemented yet");
43+
}
44+
45+
bool selectMemRegAddrISH1(SDValue Addr, SDValue &Base, SDValue &Offset) {
46+
return selectMemRegAddr(Addr, Base, Offset, 1);
47+
}
48+
49+
bool selectMemRegAddrISH2(SDValue Addr, SDValue &Base, SDValue &Offset) {
50+
return selectMemRegAddr(Addr, Base, Offset, 2);
51+
}
52+
53+
bool selectMemRegAddrISH4(SDValue Addr, SDValue &Base, SDValue &Offset) {
54+
return selectMemRegAddr(Addr, Base, Offset, 4);
55+
}
56+
57+
// Include the pieces autogenerated from the target description.
58+
#include "XtensaGenDAGISel.inc"
59+
}; // namespace
60+
} // end anonymous namespace
61+
62+
char XtensaDAGToDAGISel::ID = 0;
63+
64+
FunctionPass *llvm::createXtensaISelDag(XtensaTargetMachine &TM,
65+
CodeGenOptLevel OptLevel) {
66+
return new XtensaDAGToDAGISel(TM, OptLevel);
67+
}
68+
69+
void XtensaDAGToDAGISel::Select(SDNode *Node) {
70+
SDLoc DL(Node);
71+
72+
// If we have a custom node, we already have selected!
73+
if (Node->isMachineOpcode()) {
74+
Node->setNodeId(-1);
75+
return;
76+
}
77+
78+
SelectCode(Node);
79+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===- XtensaISelLowering.cpp - Xtensa DAG Lowering Implementation --------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines the interfaces that Xtensa uses to lower LLVM code into a
10+
// selection DAG.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "XtensaISelLowering.h"
15+
#include "XtensaSubtarget.h"
16+
#include "XtensaTargetMachine.h"
17+
#include "llvm/CodeGen/CallingConvLower.h"
18+
#include "llvm/CodeGen/MachineFrameInfo.h"
19+
#include "llvm/CodeGen/MachineInstrBuilder.h"
20+
#include "llvm/CodeGen/MachineJumpTableInfo.h"
21+
#include "llvm/CodeGen/MachineRegisterInfo.h"
22+
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
23+
#include "llvm/Support/Debug.h"
24+
#include "llvm/Support/ErrorHandling.h"
25+
#include "llvm/Support/raw_ostream.h"
26+
27+
using namespace llvm;
28+
29+
#define DEBUG_TYPE "xtensa-lower"
30+
31+
XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
32+
const XtensaSubtarget &STI)
33+
: TargetLowering(TM), Subtarget(STI) {
34+
// Set up the register classes.
35+
addRegisterClass(MVT::i32, &Xtensa::ARRegClass);
36+
37+
// Set up special registers.
38+
setStackPointerRegisterToSaveRestore(Xtensa::SP);
39+
40+
setSchedulingPreference(Sched::RegPressure);
41+
42+
setMinFunctionAlignment(Align(4));
43+
44+
// Compute derived properties from the register classes
45+
computeRegisterProperties(STI.getRegisterInfo());
46+
}
47+
48+
SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
49+
SelectionDAG &DAG) const {
50+
switch (Op.getOpcode()) {
51+
default:
52+
report_fatal_error("Unexpected node to lower");
53+
}
54+
}
55+
56+
const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
57+
return nullptr;
58+
}

0 commit comments

Comments
 (0)