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] Initial codegen support from IR #78548

Merged
merged 1 commit into from
Feb 12, 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
9 changes: 9 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 XtensaGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM XtensaGenDisassemblerTables.inc -gen-disassembler)
tablegen(LLVM XtensaGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM XtensaGenMCCodeEmitter.inc -gen-emitter)
Expand All @@ -13,13 +14,21 @@ tablegen(LLVM XtensaGenSubtargetInfo.inc -gen-subtarget)
add_public_tablegen_target(XtensaCommonTableGen)

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

LINK_COMPONENTS
AsmPrinter
CodeGen
Core
MC
SelectionDAG
Support
Target
XtensaDesc
Expand Down
28 changes: 28 additions & 0 deletions llvm/lib/Target/Xtensa/Xtensa.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//===- Xtensa.h - Top-level interface for Xtensa representation -*- C++ -*-===//
//
// 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 contains the entry points for global functions defined in
// the LLVM Xtensa back-end.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_XTENSA_XTENSA_H
#define LLVM_LIB_TARGET_XTENSA_XTENSA_H

#include "MCTargetDesc/XtensaMCTargetDesc.h"
#include "llvm/PassRegistry.h"
#include "llvm/Support/CodeGen.h"

namespace llvm {
class XtensaTargetMachine;
class FunctionPass;

FunctionPass *createXtensaISelDag(XtensaTargetMachine &TM,
CodeGenOptLevel OptLevel);
} // namespace llvm
#endif // LLVM_LIB_TARGET_XTENSA_XTENSA_H
70 changes: 70 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//===- XtensaAsmPrinter.cpp Xtensa LLVM Assembly Printer ------------------===//
//
// 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 contains a printer that converts from our internal representation
// of machine-dependent LLVM code to GAS-format Xtensa assembly language.
//
//===----------------------------------------------------------------------===//

#include "XtensaAsmPrinter.h"
#include "TargetInfo/XtensaTargetInfo.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/TargetRegistry.h"

using namespace llvm;

void XtensaAsmPrinter::emitInstruction(const MachineInstr *MI) {
MCInst LoweredMI;
lowerToMCInst(MI, LoweredMI);
EmitToStreamer(*OutStreamer, LoweredMI);
}

MCOperand XtensaAsmPrinter::lowerOperand(const MachineOperand &MO,
unsigned Offset) const {
MachineOperand::MachineOperandType MOTy = MO.getType();

switch (MOTy) {
case MachineOperand::MO_Register:
// Ignore all implicit register operands.
if (MO.isImplicit())
break;
return MCOperand::createReg(MO.getReg());
case MachineOperand::MO_Immediate:
return MCOperand::createImm(MO.getImm() + Offset);
case MachineOperand::MO_RegisterMask:
break;
default:
report_fatal_error("unknown operand type");
}

return MCOperand();
}

void XtensaAsmPrinter::lowerToMCInst(const MachineInstr *MI,
MCInst &OutMI) const {
OutMI.setOpcode(MI->getOpcode());

for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
MCOperand MCOp = lowerOperand(MO);

if (MCOp.isValid())
OutMI.addOperand(MCOp);
}
}

extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmPrinter() {
RegisterAsmPrinter<XtensaAsmPrinter> A(getTheXtensaTarget());
}
46 changes: 46 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaAsmPrinter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//===- XtensaAsmPrinter.h - Xtensa LLVM Assembly Printer --------*- C++-*--===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Xtensa Assembly printer class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_XTENSA_XTENSAASMPRINTER_H
#define LLVM_LIB_TARGET_XTENSA_XTENSAASMPRINTER_H

#include "XtensaTargetMachine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/Support/Compiler.h"

namespace llvm {
class MCStreamer;
class MachineBasicBlock;
class MachineInstr;
class Module;
class raw_ostream;

class LLVM_LIBRARY_VISIBILITY XtensaAsmPrinter : public AsmPrinter {
const MCSubtargetInfo *STI;

public:
explicit XtensaAsmPrinter(TargetMachine &TM,
std::unique_ptr<MCStreamer> Streamer)
: AsmPrinter(TM, std::move(Streamer)), STI(TM.getMCSubtargetInfo()) {}

StringRef getPassName() const override { return "Xtensa Assembly Printer"; }
void emitInstruction(const MachineInstr *MI) override;

// Lower MachineInstr MI to MCInst OutMI.
void lowerToMCInst(const MachineInstr *MI, MCInst &OutMI) const;

// Return an MCOperand for MO. Return an empty operand if MO is implicit.
MCOperand lowerOperand(const MachineOperand &MO, unsigned Offset = 0) const;
};
} // end namespace llvm

#endif /* LLVM_LIB_TARGET_XTENSA_XTENSAASMPRINTER_H */
39 changes: 39 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//===- XtensaFrameLowering.cpp - Xtensa Frame Information -----------------===//
//
// 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 contains the Xtensa implementation of TargetFrameLowering class.
//
//===----------------------------------------------------------------------===//

#include "XtensaFrameLowering.h"
#include "XtensaInstrInfo.h"
#include "XtensaSubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/IR/Function.h"

using namespace llvm;

XtensaFrameLowering::XtensaFrameLowering()
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(4), 0,
Align(4)) {}

bool XtensaFrameLowering::hasFP(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
return MF.getTarget().Options.DisableFramePointerElim(MF) ||
MFI.hasVarSizedObjects();
}

void XtensaFrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {}

void XtensaFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {}
32 changes: 32 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaFrameLowering.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//===- XtensaFrameLowering.h - Define frame lowering for Xtensa --*- C++ -*-==//
//
// 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_XTENSAFRAMELOWERING_H
#define LLVM_LIB_TARGET_XTENSA_XTENSAFRAMELOWERING_H

#include "llvm/CodeGen/TargetFrameLowering.h"

namespace llvm {
class XtensaTargetMachine;
class XtensaSubtarget;

class XtensaFrameLowering : public TargetFrameLowering {
public:
XtensaFrameLowering();

bool hasFP(const MachineFunction &MF) const override;

/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
/// the function.
void emitPrologue(MachineFunction &, MachineBasicBlock &) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
};

} // namespace llvm

#endif /* LLVM_LIB_TARGET_XTENSA_XTENSAFRAMELOWERING_H */
79 changes: 79 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//===- XtensaISelDAGToDAG.cpp - A dag to dag inst selector for Xtensa -----===//
//
// 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 defines an instruction selector for the Xtensa target.
//
//===----------------------------------------------------------------------===//

#include "Xtensa.h"
#include "XtensaTargetMachine.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

#define DEBUG_TYPE "xtensa-isel"

namespace {

class XtensaDAGToDAGISel : public SelectionDAGISel {
public:
static char ID;

XtensaDAGToDAGISel(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel)
: SelectionDAGISel(ID, TM, OptLevel) {}

StringRef getPassName() const override {
return "Xtensa DAG->DAG Pattern Instruction Selection";
}

void Select(SDNode *Node) override;

bool selectMemRegAddr(SDValue Addr, SDValue &Base, SDValue &Offset,
int Scale) {
report_fatal_error("MemReg address is not implemented yet");
}

bool selectMemRegAddrISH1(SDValue Addr, SDValue &Base, SDValue &Offset) {
return selectMemRegAddr(Addr, Base, Offset, 1);
}

bool selectMemRegAddrISH2(SDValue Addr, SDValue &Base, SDValue &Offset) {
return selectMemRegAddr(Addr, Base, Offset, 2);
}

bool selectMemRegAddrISH4(SDValue Addr, SDValue &Base, SDValue &Offset) {
return selectMemRegAddr(Addr, Base, Offset, 4);
}

// Include the pieces autogenerated from the target description.
#include "XtensaGenDAGISel.inc"
}; // namespace
} // end anonymous namespace

char XtensaDAGToDAGISel::ID = 0;

FunctionPass *llvm::createXtensaISelDag(XtensaTargetMachine &TM,
CodeGenOptLevel OptLevel) {
return new XtensaDAGToDAGISel(TM, OptLevel);
}

void XtensaDAGToDAGISel::Select(SDNode *Node) {
SDLoc DL(Node);

// If we have a custom node, we already have selected!
if (Node->isMachineOpcode()) {
Node->setNodeId(-1);
return;
}

SelectCode(Node);
}
58 changes: 58 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//===- XtensaISelLowering.cpp - Xtensa DAG Lowering Implementation --------===//
//
// 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 defines the interfaces that Xtensa uses to lower LLVM code into a
// selection DAG.
//
//===----------------------------------------------------------------------===//

#include "XtensaISelLowering.h"
#include "XtensaSubtarget.h"
#include "XtensaTargetMachine.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

#define DEBUG_TYPE "xtensa-lower"

XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
const XtensaSubtarget &STI)
: TargetLowering(TM), Subtarget(STI) {
// Set up the register classes.
addRegisterClass(MVT::i32, &Xtensa::ARRegClass);

// Set up special registers.
setStackPointerRegisterToSaveRestore(Xtensa::SP);

setSchedulingPreference(Sched::RegPressure);

setMinFunctionAlignment(Align(4));

// Compute derived properties from the register classes
computeRegisterProperties(STI.getRegisterInfo());
}

SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
SelectionDAG &DAG) const {
switch (Op.getOpcode()) {
default:
report_fatal_error("Unexpected node to lower");
}
}

const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
return nullptr;
}
Loading
Loading