Lots of basic infrastructure. And get it compiling.

This commit is contained in:
Jeremy Rand 2015-07-17 20:05:36 -05:00
parent 51e5e090e2
commit 8c1a0d70be
40 changed files with 4914 additions and 298 deletions

View File

@ -110,6 +110,7 @@ set(LLVM_ALL_TARGETS
R600
Sparc
SystemZ
WDC65816
X86
XCore
)

View File

@ -71,7 +71,8 @@ public:
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
amdil, // amdil: amd IL
spir, // SPIR: standard portable IR for OpenCL 32-bit version
spir64 // SPIR: standard portable IR for OpenCL 64-bit version
spir64, // SPIR: standard portable IR for OpenCL 64-bit version
wdc65816
};
enum VendorType {
UnknownVendor,

View File

@ -45,6 +45,7 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case amdil: return "amdil";
case spir: return "spir";
case spir64: return "spir64";
case wdc65816: return "wdc65816";
}
llvm_unreachable("Invalid ArchType!");
@ -671,6 +672,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
return 0;
case llvm::Triple::msp430:
case llvm::Triple::wdc65816:
return 16;
case llvm::Triple::amdil:
@ -725,6 +727,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::msp430:
case Triple::systemz:
case Triple::ppc64le:
case Triple::wdc65816:
T.setArch(UnknownArch);
break;
@ -770,6 +773,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::tce:
case Triple::thumb:
case Triple::xcore:
case Triple::wdc65816:
T.setArch(UnknownArch);
break;

View File

@ -0,0 +1,26 @@
set(LLVM_TARGET_DEFINITIONS WDC65816.td)
tablegen(LLVM WDC65816GenRegisterInfo.inc -gen-register-info)
tablegen(LLVM WDC65816GenInstrInfo.inc -gen-instr-info)
tablegen(LLVM WDC65816GenAsmWriter.inc -gen-asm-writer)
tablegen(LLVM WDC65816GenDAGISel.inc -gen-dag-isel)
tablegen(LLVM WDC65816GenSubtargetInfo.inc -gen-subtarget)
tablegen(LLVM WDC65816GenCallingConv.inc -gen-callingconv)
add_public_tablegen_target(WDC65816CommonTableGen)
add_llvm_target(WDC65816CodeGen
WDC65816AsmPrinter.cpp
WDC65816InstrInfo.cpp
WDC65816ISelDAGToDAG.cpp
WDC65816ISelLowering.cpp
WDC65816FrameLowering.cpp
WDC65816MachineFunctionInfo.cpp
WDC65816RegisterInfo.cpp
WDC65816TargetMachine.cpp
WDC65816SelectionDAGInfo.cpp
)
add_dependencies(LLVMWDC65816CodeGen WDC65816CommonTableGen intrinsics_gen)
add_subdirectory(TargetInfo)
add_subdirectory(MCTargetDesc)

View File

@ -1,4 +1,4 @@
;===- ./lib/Target/WDC65816/LLVMBuild.txt -------------------------*- Conf -*--===;
;===- ./lib/Target/WDC65816/LLVMBuild.txt ----------------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
@ -16,19 +16,19 @@
;===------------------------------------------------------------------------===;
[common]
subdirectories =
subdirectories = MCTargetDesc TargetInfo
[component_0]
type = TargetGroup
name = WDC65816
parent = Target
has_asmprinter = 0
has_asmprinter = 1
has_jit = 0
[component_1]
type = Library
name = WDC65816CodeGen
parent = WDC65816
required_libraries = AsmPrinter CodeGen Core MC SelectionDAG
Support Target
required_libraries = AsmPrinter CodeGen Core MC SelectionDAG WDC65816Desc
WDC65816Info Support Target
add_to_library_groups = WDC65816

View File

@ -0,0 +1,6 @@
add_llvm_library(LLVMWDC65816Desc
WDC65816MCTargetDesc.cpp
WDC65816MCAsmInfo.cpp
)
add_dependencies(LLVMWDC65816Desc WDC65816CommonTableGen)

View File

@ -0,0 +1,23 @@
;===- ./lib/Target/WDC65816/MCTargetDesc/LLVMBuild.txt ---------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
[component_0]
type = Library
name = WDC65816Desc
parent = WDC65816
required_libraries = MC WDC65816Info Support
add_to_library_groups = WDC65816

View File

@ -0,0 +1,16 @@
##===- lib/Target/WDC65816/TargetDesc/Makefile -------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMWDC65816Desc
# Hack: we need to include 'main' target directory to grab private headers
CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common

View File

@ -0,0 +1,84 @@
//===-- WDC65816BaseInfo.h - Top level definitions for 65816 - --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains small standalone helper functions and enum definitions
// for the WDC65816 target useful for the compiler back-end and the MC libraries.
// As such, it deliberately does not include references to LLVM core code gen
// types, passes, etc..
//
//===----------------------------------------------------------------------===//
#ifndef WDC65816BASEINFO_H
#define WDC65816BASEINFO_H
namespace llvm {
/// SPII - This namespace holds target specific flags for instruction info.
namespace SPII {
#if 0 // WDC_TODO - Do I need any of this?
/// Target Operand Flags. Sparc specific TargetFlags for MachineOperands and
/// SDNodes.
enum TOF {
MO_NO_FLAG,
// Extract the low 10 bits of an address.
// Assembler: %lo(addr)
MO_LO,
// Extract bits 31-10 of an address. Only for sethi.
// Assembler: %hi(addr) or %lm(addr)
MO_HI,
// Extract bits 43-22 of an adress. Only for sethi.
// Assembler: %h44(addr)
MO_H44,
// Extract bits 21-12 of an address.
// Assembler: %m44(addr)
MO_M44,
// Extract bits 11-0 of an address.
// Assembler: %l44(addr)
MO_L44,
// Extract bits 63-42 of an address. Only for sethi.
// Assembler: %hh(addr)
MO_HH,
// Extract bits 41-32 of an address.
// Assembler: %hm(addr)
MO_HM,
// TargetFlags for Thread Local Storage.
MO_TLS_GD_HI22,
MO_TLS_GD_LO10,
MO_TLS_GD_ADD,
MO_TLS_GD_CALL,
MO_TLS_LDM_HI22,
MO_TLS_LDM_LO10,
MO_TLS_LDM_ADD,
MO_TLS_LDM_CALL,
MO_TLS_LDO_HIX22,
MO_TLS_LDO_LOX10,
MO_TLS_LDO_ADD,
MO_TLS_IE_HI22,
MO_TLS_IE_LO10,
MO_TLS_IE_LD,
MO_TLS_IE_LDX,
MO_TLS_IE_ADD,
MO_TLS_LE_HIX22,
MO_TLS_LE_LOX10
};
#endif
} // end namespace SPII
} // end namespace llvm
#endif

View File

@ -0,0 +1,46 @@
//===-- WDC65816MCAsmInfo.cpp - WDC65816 asm properties -------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declarations of the WDC65816MCAsmInfo properties.
//
//===----------------------------------------------------------------------===//
#include "WDC65816MCAsmInfo.h"
#include "llvm/ADT/Triple.h"
using namespace llvm;
void WDC65816ELFMCAsmInfo::anchor() { }
WDC65816ELFMCAsmInfo::WDC65816ELFMCAsmInfo(StringRef TT) {
IsLittleEndian = true;
Triple TheTriple(TT);
PointerSize = CalleeSaveStackSlotSize = 4;
#if 0 // WDC_TODO - Do I need any of this?
Data16bitsDirective = "\t.half\t";
Data32bitsDirective = "\t.word\t";
// .xword is only supported by V9.
Data64bitsDirective = (isV9) ? "\t.xword\t" : 0;
ZeroDirective = "\t.skip\t";
CommentString = "!";
HasLEB128 = true;
SupportsDebugInformation = true;
ExceptionsType = ExceptionHandling::DwarfCFI;
SunStyleELFSectionSwitchSyntax = true;
UsesELFSectionDirectiveForBSS = true;
PrivateGlobalPrefix = ".L";
#endif
}

View File

@ -0,0 +1,30 @@
//===-- WDC65816MCAsmInfo.h - WDC65816 asm properties ----------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the WDC65816MCAsmInfo class.
//
//===----------------------------------------------------------------------===//
#ifndef WDC65816TARGETASMINFO_H
#define WDC65816TARGETASMINFO_H
#include "llvm/MC/MCAsmInfoELF.h"
namespace llvm {
class StringRef;
class WDC65816ELFMCAsmInfo : public MCAsmInfoELF {
virtual void anchor();
public:
explicit WDC65816ELFMCAsmInfo(StringRef TT);
};
} // namespace llvm
#endif

View File

@ -0,0 +1,85 @@
//===-- WDC65816MCTargetDesc.cpp - WDC65816 Target Descriptions -----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides WDC65816 specific target descriptions.
//
//===----------------------------------------------------------------------===//
#include "WDC65816MCTargetDesc.h"
#include "WDC65816MCAsmInfo.h"
#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#define GET_INSTRINFO_MC_DESC
#include "WDC65816GenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC
#include "WDC65816GenSubtargetInfo.inc"
#define GET_REGINFO_MC_DESC
#include "WDC65816GenRegisterInfo.inc"
using namespace llvm;
static MCInstrInfo *createWDC65816MCInstrInfo() {
MCInstrInfo *X = new MCInstrInfo();
InitWDC65816MCInstrInfo(X);
return X;
}
static MCRegisterInfo *createWDC65816MCRegisterInfo(StringRef TT) {
MCRegisterInfo *X = new MCRegisterInfo();
InitWDC65816MCRegisterInfo(X, WDC::FP);
return X;
}
static MCSubtargetInfo *createWDC65816MCSubtargetInfo(StringRef TT, StringRef CPU,
StringRef FS) {
MCSubtargetInfo *X = new MCSubtargetInfo();
InitWDC65816MCSubtargetInfo(X, TT, CPU, FS);
return X;
}
static MCCodeGenInfo *createWDC65816MCCodeGenInfo(StringRef TT, Reloc::Model RM,
CodeModel::Model CM,
CodeGenOpt::Level OL) {
MCCodeGenInfo *X = new MCCodeGenInfo();
// The default 32-bit code model is abs32/pic32.
if (CM == CodeModel::Default)
CM = CodeModel::Medium;
X->InitMCCodeGenInfo(RM, CM, OL);
return X;
}
extern "C" void LLVMInitializeWDC65816TargetMC() {
// Register the MC asm info.
RegisterMCAsmInfo<WDC65816ELFMCAsmInfo> X(TheWDC65816Target);
// Register the MC codegen info.
TargetRegistry::RegisterMCCodeGenInfo(TheWDC65816Target,
createWDC65816MCCodeGenInfo);
// Register the MC instruction info.
TargetRegistry::RegisterMCInstrInfo(TheWDC65816Target, createWDC65816MCInstrInfo);
// Register the MC register info.
TargetRegistry::RegisterMCRegInfo(TheWDC65816Target, createWDC65816MCRegisterInfo);
// Register the MC subtarget info.
TargetRegistry::RegisterMCSubtargetInfo(TheWDC65816Target,
createWDC65816MCSubtargetInfo);
}

View File

@ -0,0 +1,38 @@
//===-- WDC65816MCTargetDesc.h - WDC65816 Target Descriptions ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides WDC65816 specific target descriptions.
//
//===----------------------------------------------------------------------===//
#ifndef WDC65816MCTARGETDESC_H
#define WDC65816MCTARGETDESC_H
namespace llvm {
class Target;
extern Target TheWDC65816Target;
} // End llvm namespace
// Defines symbolic names for WDC65816 registers. This defines a mapping from
// register name to register number.
//
#define GET_REGINFO_ENUM
#include "WDC65816GenRegisterInfo.inc"
// Defines symbolic names for the WDC65816 instructions.
//
#define GET_INSTRINFO_ENUM
#include "WDC65816GenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM
#include "WDC65816GenSubtargetInfo.inc"
#endif

View File

@ -14,10 +14,9 @@ TARGET = WDC65816
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = WDC65816GenRegisterInfo.inc WDC65816GenInstrInfo.inc \
WDC65816GenAsmWriter.inc WDC65816GenDAGISel.inc \
WDC65816GenSubtargetInfo.inc WDC65816GenCallingConv.inc \
WDC65816GenCodeEmitter.inc
WDC65816GenSubtargetInfo.inc WDC65816GenCallingConv.inc
# DIRS = InstPrinter Disassembler AsmParser TargetInfo MCTargetDesc
DIRS = TargetInfo MCTargetDesc
include $(LEVEL)/Makefile.common

View File

@ -0,0 +1,7 @@
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
add_llvm_library(LLVMWDC65816Info
WDC65816TargetInfo.cpp
)
add_dependencies(LLVMWDC65816Info WDC65816CommonTableGen)

View File

@ -0,0 +1,23 @@
;===- ./lib/Target/WDC65816/TargetInfo/LLVMBuild.txt -----------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
[component_0]
type = Library
name = WDC65816Info
parent = WDC65816
required_libraries = MC Support Target
add_to_library_groups = WDC65816

View File

@ -0,0 +1,15 @@
##===- lib/Target/WDC65816/TargetInfo/Makefile -------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMWDC65816Info
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common

View File

@ -0,0 +1,24 @@
//===-- WDC65816TargetInfo.cpp - WDC65816 Target Implementation -----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
#include "WDC65816.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
Target llvm::TheWDC65816Target;
extern "C" void LLVMInitializeWDC65816TargetInfo() {
printf("I got called!\n");
RegisterTarget<Triple::wdc65816, /*HasJIT=*/ false>
X(TheWDC65816Target, "wdc65816", "WDC65816");
TargetRegistry::printRegisteredTargetsForVersion();
}

View File

@ -1,4 +1,4 @@
//===-- WDC65816.h - Top-level interface for WDC65816 representation --*- C++ -*-===//
//===- WDC65816.h - Top-level interface for WDC65816 representation -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -15,6 +15,7 @@
#ifndef WDC65816_H
#define WDC65816_H
#include "MCTargetDesc/WDC65816MCTargetDesc.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetMachine.h"
@ -28,7 +29,7 @@ namespace llvm {
} // end namespace llvm;
namespace llvm {
#if 0 // JSR_TODO - Something here?
#if 0 // WDC_TODO - Something here?
// Enums corresponding to Sparc condition codes, both icc's and fcc's. These
// values must be kept in sync with the ones in the .td file.
namespace SPCC {

View File

@ -1,4 +1,4 @@
//===-- WDC65816.td - Describe the WDC65816 Target Machine -------*- tablegen -*-===//
//===-- WDC65816.td - Describe the WDC65816 Target Machine -*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//

View File

@ -0,0 +1,361 @@
//===-- WDC65816AsmPrinter.cpp - WDC65816 LLVM assembly writer ------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
// of machine-dependent LLVM code to GAS-format SPARC assembly language.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "asm-printer"
#include "WDC65816.h"
#include "WDC65816InstrInfo.h"
#include "WDC65816TargetMachine.h"
#include "MCTargetDesc/WDC65816BaseInfo.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/Mangler.h"
using namespace llvm;
namespace {
class WDC65816AsmPrinter : public AsmPrinter {
public:
explicit WDC65816AsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
: AsmPrinter(TM, Streamer) {}
virtual const char *getPassName() const {
return "WDC65816 Assembly Printer";
}
void printInstruction(const MachineInstr *MI, raw_ostream &OS);// autogen'd.
void printOperand(const MachineInstr *MI, int opNum, raw_ostream &OS);
void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &OS,
const char *Modifier = 0);
bool printGetPCX(const MachineInstr *MI, unsigned OpNo, raw_ostream &OS);
static const char *getRegisterName(unsigned RegNo);
#if 0 // WDC_TODO - How much of this do we need?
void printCCOperand(const MachineInstr *MI, int opNum, raw_ostream &OS);
virtual void EmitFunctionBodyStart();
virtual void EmitInstruction(const MachineInstr *MI) {
SmallString<128> Str;
raw_svector_ostream OS(Str);
printInstruction(MI, OS);
OutStreamer.EmitRawText(OS.str());
}
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode,
raw_ostream &O);
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode,
raw_ostream &O);
virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
const;
void EmitGlobalRegisterDecl(unsigned reg) {
SmallString<128> Str;
raw_svector_ostream OS(Str);
OS << "\t.register "
<< "%" << StringRef(getRegisterName(reg)).lower()
<< ", "
<< ((reg == SP::G6 || reg == SP::G7)? "#ignore" : "#scratch");
OutStreamer.EmitRawText(OS.str());
}
#endif
};
} // end of anonymous namespace
#include "WDC65816GenAsmWriter.inc"
void WDC65816AsmPrinter::printOperand(const MachineInstr *MI, int opNum,
raw_ostream &O) {
// WDC_TODO - print the operand here...
}
void WDC65816AsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
raw_ostream &O, const char *Modifier) {
// WDC_TODO - print the memory operand here...
}
bool WDC65816AsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum,
raw_ostream &O) {
// WDC_TODO - print whatever this is here...
}
#if 0 // WDC_TODO - How much of this do we need?
void WDC65816AsmPrinter::EmitFunctionBodyStart() {
const MachineRegisterInfo &MRI = MF->getRegInfo();
const unsigned globalRegs[] = { SP::G2, SP::G3, SP::G6, SP::G7, 0 };
for (unsigned i = 0; globalRegs[i] != 0; ++i) {
unsigned reg = globalRegs[i];
if (MRI.use_empty(reg))
continue;
EmitGlobalRegisterDecl(reg);
}
}
void WDC65816AsmPrinter::printOperand(const MachineInstr *MI, int opNum,
raw_ostream &O) {
const MachineOperand &MO = MI->getOperand (opNum);
unsigned TF = MO.getTargetFlags();
#ifndef NDEBUG
// Verify the target flags.
if (MO.isGlobal() || MO.isSymbol() || MO.isCPI()) {
if (MI->getOpcode() == SP::CALL)
assert(TF == SPII::MO_NO_FLAG &&
"Cannot handle target flags on call address");
else if (MI->getOpcode() == SP::SETHIi)
assert((TF == SPII::MO_HI || TF == SPII::MO_H44 || TF == SPII::MO_HH
|| TF == SPII::MO_TLS_GD_HI22
|| TF == SPII::MO_TLS_LDM_HI22
|| TF == SPII::MO_TLS_LDO_HIX22
|| TF == SPII::MO_TLS_IE_HI22
|| TF == SPII::MO_TLS_LE_HIX22) &&
"Invalid target flags for address operand on sethi");
else if (MI->getOpcode() == SP::TLS_CALL)
assert((TF == SPII::MO_NO_FLAG
|| TF == SPII::MO_TLS_GD_CALL
|| TF == SPII::MO_TLS_LDM_CALL) &&
"Cannot handle target flags on tls call address");
else if (MI->getOpcode() == SP::TLS_ADDrr)
assert((TF == SPII::MO_TLS_GD_ADD || TF == SPII::MO_TLS_LDM_ADD
|| TF == SPII::MO_TLS_LDO_ADD || TF == SPII::MO_TLS_IE_ADD) &&
"Cannot handle target flags on add for TLS");
else if (MI->getOpcode() == SP::TLS_LDrr)
assert(TF == SPII::MO_TLS_IE_LD &&
"Cannot handle target flags on ld for TLS");
else if (MI->getOpcode() == SP::TLS_LDXrr)
assert(TF == SPII::MO_TLS_IE_LDX &&
"Cannot handle target flags on ldx for TLS");
else if (MI->getOpcode() == SP::XORri)
assert((TF == SPII::MO_TLS_LDO_LOX10 || TF == SPII::MO_TLS_LE_LOX10) &&
"Cannot handle target flags on xor for TLS");
else
assert((TF == SPII::MO_LO || TF == SPII::MO_M44 || TF == SPII::MO_L44
|| TF == SPII::MO_HM
|| TF == SPII::MO_TLS_GD_LO10
|| TF == SPII::MO_TLS_LDM_LO10
|| TF == SPII::MO_TLS_IE_LO10 ) &&
"Invalid target flags for small address operand");
}
#endif
bool CloseParen = true;
switch (TF) {
default:
llvm_unreachable("Unknown target flags on operand");
case SPII::MO_NO_FLAG:
CloseParen = false;
break;
case SPII::MO_LO: O << "%lo("; break;
case SPII::MO_HI: O << "%hi("; break;
case SPII::MO_H44: O << "%h44("; break;
case SPII::MO_M44: O << "%m44("; break;
case SPII::MO_L44: O << "%l44("; break;
case SPII::MO_HH: O << "%hh("; break;
case SPII::MO_HM: O << "%hm("; break;
case SPII::MO_TLS_GD_HI22: O << "%tgd_hi22("; break;
case SPII::MO_TLS_GD_LO10: O << "%tgd_lo10("; break;
case SPII::MO_TLS_GD_ADD: O << "%tgd_add("; break;
case SPII::MO_TLS_GD_CALL: O << "%tgd_call("; break;
case SPII::MO_TLS_LDM_HI22: O << "%tldm_hi22("; break;
case SPII::MO_TLS_LDM_LO10: O << "%tldm_lo10("; break;
case SPII::MO_TLS_LDM_ADD: O << "%tldm_add("; break;
case SPII::MO_TLS_LDM_CALL: O << "%tldm_call("; break;
case SPII::MO_TLS_LDO_HIX22: O << "%tldo_hix22("; break;
case SPII::MO_TLS_LDO_LOX10: O << "%tldo_lox10("; break;
case SPII::MO_TLS_LDO_ADD: O << "%tldo_add("; break;
case SPII::MO_TLS_IE_HI22: O << "%tie_hi22("; break;
case SPII::MO_TLS_IE_LO10: O << "%tie_lo10("; break;
case SPII::MO_TLS_IE_LD: O << "%tie_ld("; break;
case SPII::MO_TLS_IE_LDX: O << "%tie_ldx("; break;
case SPII::MO_TLS_IE_ADD: O << "%tie_add("; break;
case SPII::MO_TLS_LE_HIX22: O << "%tle_hix22("; break;
case SPII::MO_TLS_LE_LOX10: O << "%tle_lox10("; break;
}
switch (MO.getType()) {
case MachineOperand::MO_Register:
O << "%" << StringRef(getRegisterName(MO.getReg())).lower();
break;
case MachineOperand::MO_Immediate:
O << (int)MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_GlobalAddress:
O << *getSymbol(MO.getGlobal());
break;
case MachineOperand::MO_BlockAddress:
O << GetBlockAddressSymbol(MO.getBlockAddress())->getName();
break;
case MachineOperand::MO_ExternalSymbol:
O << MO.getSymbolName();
break;
case MachineOperand::MO_ConstantPoolIndex:
O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
<< MO.getIndex();
break;
default:
llvm_unreachable("<unknown operand type>");
}
if (CloseParen) O << ")";
}
void WDC65816AsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
raw_ostream &O, const char *Modifier) {
printOperand(MI, opNum, O);
// If this is an ADD operand, emit it like normal operands.
if (Modifier && !strcmp(Modifier, "arith")) {
O << ", ";
printOperand(MI, opNum+1, O);
return;
}
if (MI->getOperand(opNum+1).isReg() &&
MI->getOperand(opNum+1).getReg() == SP::G0)
return; // don't print "+%g0"
if (MI->getOperand(opNum+1).isImm() &&
MI->getOperand(opNum+1).getImm() == 0)
return; // don't print "+0"
O << "+";
printOperand(MI, opNum+1, O);
}
bool WDC65816AsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum,
raw_ostream &O) {
std::string operand = "";
const MachineOperand &MO = MI->getOperand(opNum);
switch (MO.getType()) {
default: llvm_unreachable("Operand is not a register");
case MachineOperand::MO_Register:
assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
"Operand is not a physical register ");
assert(MO.getReg() != SP::O7 &&
"%o7 is assigned as destination for getpcx!");
operand = "%" + StringRef(getRegisterName(MO.getReg())).lower();
break;
}
unsigned mfNum = MI->getParent()->getParent()->getFunctionNumber();
unsigned bbNum = MI->getParent()->getNumber();
O << '\n' << ".LLGETPCH" << mfNum << '_' << bbNum << ":\n";
O << "\tcall\t.LLGETPC" << mfNum << '_' << bbNum << '\n' ;
O << "\t sethi\t"
<< "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
<< ")), " << operand << '\n' ;
O << ".LLGETPC" << mfNum << '_' << bbNum << ":\n" ;
O << "\tor\t" << operand
<< ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << mfNum << '_' << bbNum
<< ")), " << operand << '\n';
O << "\tadd\t" << operand << ", %o7, " << operand << '\n';
return true;
}
void WDC65816AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum,
raw_ostream &O) {
int CC = (int)MI->getOperand(opNum).getImm();
O << SPARCCondCodeToString((SPCC::CondCodes)CC);
}
/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool WDC65816AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant,
const char *ExtraCode,
raw_ostream &O) {
if (ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0) return true; // Unknown modifier.
switch (ExtraCode[0]) {
default:
// See if this is a generic print operand
return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
case 'r':
break;
}
}
printOperand(MI, OpNo, O);
return false;
}
bool WDC65816AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
unsigned OpNo, unsigned AsmVariant,
const char *ExtraCode,
raw_ostream &O) {
if (ExtraCode && ExtraCode[0])
return true; // Unknown modifier
O << '[';
printMemOperand(MI, OpNo, O);
O << ']';
return false;
}
/// isBlockOnlyReachableByFallthough - Return true if the basic block has
/// exactly one predecessor and the control transfer mechanism between
/// the predecessor and this block is a fall-through.
///
/// This overrides AsmPrinter's implementation to handle delay slots.
bool WDC65816AsmPrinter::
isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
// If this is a landing pad, it isn't a fall through. If it has no preds,
// then nothing falls through to it.
if (MBB->isLandingPad() || MBB->pred_empty())
return false;
// If there isn't exactly one predecessor, it can't be a fall through.
MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
++PI2;
if (PI2 != MBB->pred_end())
return false;
// The predecessor has to be immediately before this block.
const MachineBasicBlock *Pred = *PI;
if (!Pred->isLayoutSuccessor(MBB))
return false;
// Check if the last terminator is an unconditional branch.
MachineBasicBlock::const_iterator I = Pred->end();
while (I != Pred->begin() && !(--I)->isTerminator())
; // Noop
return I == Pred->end() || !I->isBarrier();
}
#endif
// Force static initialization.
extern "C" void LLVMInitializeWDC65816AsmPrinter() {
RegisterAsmPrinter<WDC65816AsmPrinter> X(TheWDC65816Target);
}

View File

@ -1,4 +1,4 @@
//===- WDCCallingConv.td - Calling Conventions WDC65816 -----*- tablegen -*-===//
//===- WDCCallingConv.td - Calling Conventions WDC65816 ----*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -27,3 +27,6 @@ def CC_WDC : CallingConv<[
CCIfType<[i16], CCAssignToStack<2, 1>>,
CCIfType<[i32, f32], CCAssignToStack<4, 1>>
]>;
def CSR_NoRegs : CalleeSavedRegs<(add)>;

View File

@ -1,4 +1,4 @@
//===-- WDC65816FrameLowering.cpp - WDC65816 Frame Information ------------------===//
//===-- WDC65816FrameLowering.cpp - WDC65816 Frame Information ------------===//
//
// The LLVM Compiler Infrastructure
//
@ -24,6 +24,22 @@
using namespace llvm;
// hasFP - Whether or not there is a frame pointer.
// WDC_TODO - for now we will say we always have a frame pointer.
bool WDC65816FrameLowering::hasFP(const MachineFunction &MF) const {
return true;
}
void WDC65816FrameLowering::emitPrologue(MachineFunction &MF) const {
}
void WDC65816FrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
}
#if 0 // JSR TODO - Do I need any of this?
static cl::opt<bool>
DisableLeafProc("disable-sparc-leaf-proc",

View File

@ -1,4 +1,4 @@
//===-- WDC65816FrameLowering.h - Define frame lowering for Sparc --*- C++ -*-===//
//===- WDC65816FrameLowering.h - Define frame lowering for Sparc -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -23,18 +23,20 @@ namespace llvm {
public:
explicit WDC65816FrameLowering(void)
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 1, 0) {}
#if 0 // JSR TODO - do I need any of this?
bool hasFP(const MachineFunction &MF) const;
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
/// the function.
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
#if 0 // JSR TODO - do I need any of this?
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
bool hasReservedCallFrame(const MachineFunction &MF) const;
bool hasFP(const MachineFunction &MF) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const;

View File

@ -0,0 +1,251 @@
//===- WDC65816ISelDAGToDAG.cpp - A dag to dag inst selector for WDC65816 -===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines an instruction selector for the WDC65816 target.
//
//===----------------------------------------------------------------------===//
#include "WDC65816TargetMachine.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
// Instruction Selector Implementation
//===----------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//
/// WDC65816DAGToDAGISel - WDC65816 specific code to select WDC65816 machine
/// instructions for SelectionDAG operations.
///
namespace {
class WDC65816DAGToDAGISel : public SelectionDAGISel {
WDC65816TargetMachine &TM;
public:
explicit WDC65816DAGToDAGISel(WDC65816TargetMachine &tm)
: SelectionDAGISel(tm),
TM(tm) {
}
SDNode *Select(SDNode *N);
bool SelectAbs(SDValue N, SDValue &R1);
bool SelectAbsLong(SDValue N, SDValue &R1);
bool SelectDirectPage(SDValue N, SDValue &R1);
#if 0 // WDC_TODO - we don't need these pattern selectors but we will need some
// Complex Pattern Selectors.
bool SelectADDRrr(SDValue N, SDValue &R1, SDValue &R2);
bool SelectADDRri(SDValue N, SDValue &Base, SDValue &Offset);
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
/// inline asm expressions.
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
char ConstraintCode,
std::vector<SDValue> &OutOps);
#endif
virtual const char *getPassName() const {
return "WDC65816 DAG->DAG Pattern Instruction Selection";
}
// Include the pieces autogenerated from the target description.
#include "WDC65816GenDAGISel.inc"
private:
SDNode* getGlobalBaseReg();
};
} // end anonymous namespace
SDNode* WDC65816DAGToDAGISel::getGlobalBaseReg() {
unsigned GlobalBaseReg = TM.getInstrInfo()->getGlobalBaseReg(MF);
return CurDAG->getRegister(GlobalBaseReg,
getTargetLowering()->getPointerTy()).getNode();
}
bool WDC65816DAGToDAGISel::SelectAbs(SDValue N, SDValue &R1) {
// WDC_TODO - Write something here
return false;
}
bool WDC65816DAGToDAGISel::SelectAbsLong(SDValue N, SDValue &R1) {
// WDC_TODO - Write something here
return false;
}
bool WDC65816DAGToDAGISel::SelectDirectPage(SDValue N, SDValue &R1) {
// WDC_TODO - Write something here
return false;
}
#if 0 // WDC_TODO - we don't need these exactly, we need out own
bool SparcDAGToDAGISel::SelectADDRri(SDValue Addr,
SDValue &Base, SDValue &Offset) {
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(),
getTargetLowering()->getPointerTy());
Offset = CurDAG->getTargetConstant(0, MVT::i32);
return true;
}
if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
Addr.getOpcode() == ISD::TargetGlobalAddress ||
Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
return false; // direct calls.
if (Addr.getOpcode() == ISD::ADD) {
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
if (isInt<13>(CN->getSExtValue())) {
if (FrameIndexSDNode *FIN =
dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
// Constant offset from frame ref.
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(),
getTargetLowering()->getPointerTy());
} else {
Base = Addr.getOperand(0);
}
Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32);
return true;
}
}
if (Addr.getOperand(0).getOpcode() == SPISD::Lo) {
Base = Addr.getOperand(1);
Offset = Addr.getOperand(0).getOperand(0);
return true;
}
if (Addr.getOperand(1).getOpcode() == SPISD::Lo) {
Base = Addr.getOperand(0);
Offset = Addr.getOperand(1).getOperand(0);
return true;
}
}
Base = Addr;
Offset = CurDAG->getTargetConstant(0, MVT::i32);
return true;
}
bool SparcDAGToDAGISel::SelectADDRrr(SDValue Addr, SDValue &R1, SDValue &R2) {
if (Addr.getOpcode() == ISD::FrameIndex) return false;
if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
Addr.getOpcode() == ISD::TargetGlobalAddress ||
Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
return false; // direct calls.
if (Addr.getOpcode() == ISD::ADD) {
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
if (isInt<13>(CN->getSExtValue()))
return false; // Let the reg+imm pattern catch this!
if (Addr.getOperand(0).getOpcode() == SPISD::Lo ||
Addr.getOperand(1).getOpcode() == SPISD::Lo)
return false; // Let the reg+imm pattern catch this!
R1 = Addr.getOperand(0);
R2 = Addr.getOperand(1);
return true;
}
R1 = Addr;
R2 = CurDAG->getRegister(SP::G0, getTargetLowering()->getPointerTy());
return true;
}
#endif
SDNode *WDC65816DAGToDAGISel::Select(SDNode *N) {
return NULL;
#if 0 // WDC_TODO - we will definitely need something here
SDLoc dl(N);
if (N->isMachineOpcode()) {
N->setNodeId(-1);
return NULL; // Already selected.
}
switch (N->getOpcode()) {
default: break;
case SPISD::GLOBAL_BASE_REG:
return getGlobalBaseReg();
case ISD::SDIV:
case ISD::UDIV: {
// sdivx / udivx handle 64-bit divides.
if (N->getValueType(0) == MVT::i64)
break;
// FIXME: should use a custom expander to expose the SRA to the dag.
SDValue DivLHS = N->getOperand(0);
SDValue DivRHS = N->getOperand(1);
// Set the Y register to the high-part.
SDValue TopPart;
if (N->getOpcode() == ISD::SDIV) {
TopPart = SDValue(CurDAG->getMachineNode(SP::SRAri, dl, MVT::i32, DivLHS,
CurDAG->getTargetConstant(31, MVT::i32)), 0);
} else {
TopPart = CurDAG->getRegister(SP::G0, MVT::i32);
}
TopPart = SDValue(CurDAG->getMachineNode(SP::WRYrr, dl, MVT::Glue, TopPart,
CurDAG->getRegister(SP::G0, MVT::i32)), 0);
// FIXME: Handle div by immediate.
unsigned Opcode = N->getOpcode() == ISD::SDIV ? SP::SDIVrr : SP::UDIVrr;
return CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS,
TopPart);
}
case ISD::MULHU:
case ISD::MULHS: {
// FIXME: Handle mul by immediate.
SDValue MulLHS = N->getOperand(0);
SDValue MulRHS = N->getOperand(1);
unsigned Opcode = N->getOpcode() == ISD::MULHU ? SP::UMULrr : SP::SMULrr;
SDNode *Mul = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::Glue,
MulLHS, MulRHS);
// The high part is in the Y register.
return CurDAG->SelectNodeTo(N, SP::RDY, MVT::i32, SDValue(Mul, 1));
}
}
return SelectCode(N);
#endif
}
#if 0 // WDC_TODO - Not sure what this is about...
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
/// inline asm expressions.
bool
SparcDAGToDAGISel::SelectInlineAsmMemoryOperand(const SDValue &Op,
char ConstraintCode,
std::vector<SDValue> &OutOps) {
SDValue Op0, Op1;
switch (ConstraintCode) {
default: return true;
case 'm': // memory
if (!SelectADDRrr(Op, Op0, Op1))
SelectADDRri(Op, Op0, Op1);
break;
}
OutOps.push_back(Op0);
OutOps.push_back(Op1);
return false;
}
#endif
/// createWDC65816ISelDag - This pass converts a legalized DAG into a
/// WDC65816-specific DAG, ready for instruction scheduling.
///
FunctionPass *llvm::createWDC65816ISelDag(WDC65816TargetMachine &TM) {
return new WDC65816DAGToDAGISel(TM);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,166 @@
//===- WDC65816ISelLowering.h - WDC65816 DAG Lowering Interface -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the interfaces that WDC65816 uses to lower LLVM code into a
// selection DAG.
//
//===----------------------------------------------------------------------===//
#ifndef WDC65816_ISELLOWERING_H
#define WDC65816_ISELLOWERING_H
#include "WDC65816.h"
#include "llvm/Target/TargetLowering.h"
namespace llvm {
#if 0 // WDC_TODO - Do I need any of this?
namespace SPISD {
enum {
FIRST_NUMBER = ISD::BUILTIN_OP_END,
CMPICC, // Compare two GPR operands, set icc+xcc.
CMPFCC, // Compare two FP operands, set fcc.
BRICC, // Branch to dest on icc condition
BRXCC, // Branch to dest on xcc condition (64-bit only).
BRFCC, // Branch to dest on fcc condition
SELECT_ICC, // Select between two values using the current ICC flags.
SELECT_XCC, // Select between two values using the current XCC flags.
SELECT_FCC, // Select between two values using the current FCC flags.
Hi, Lo, // Hi/Lo operations, typically on a global address.
FTOI, // FP to Int within a FP register.
ITOF, // Int to FP within a FP register.
FTOX, // FP to Int64 within a FP register.
XTOF, // Int64 to FP within a FP register.
CALL, // A call instruction.
RET_FLAG, // Return with a flag operand.
GLOBAL_BASE_REG, // Global base reg for PIC.
FLUSHW, // FLUSH register windows to stack.
TLS_ADD, // For Thread Local Storage (TLS).
TLS_LD,
TLS_CALL
};
}
#endif
class WDC65816TargetLowering : public TargetLowering {
public:
WDC65816TargetLowering(TargetMachine &TM);
#if 0 // WDC_TODO - Do I need any of this?
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
/// computeMaskedBitsForTargetNode - Determine which of the bits specified
/// in Mask are known to be either zero or one and return them in the
/// KnownZero/KnownOne bitsets.
virtual void computeMaskedBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,
unsigned Depth = 0) const;
virtual MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *MBB) const;
virtual const char *getTargetNodeName(unsigned Opcode) const;
ConstraintType getConstraintType(const std::string &Constraint) const;
std::pair<unsigned, const TargetRegisterClass*>
getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const;
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
virtual MVT getScalarShiftAmountTy(EVT LHSTy) const { return MVT::i32; }
/// getSetCCResultType - Return the ISD::SETCC ValueType
virtual EVT getSetCCResultType(LLVMContext &Context, EVT VT) const;
virtual SDValue
LowerFormalArguments(SDValue Chain,
CallingConv::ID CallConv,
bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
SDLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerFormalArguments_32(SDValue Chain,
CallingConv::ID CallConv,
bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
SDLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerFormalArguments_64(SDValue Chain,
CallingConv::ID CallConv,
bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
SDLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
virtual SDValue
LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerCall_64(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const;
virtual SDValue
LowerReturn(SDValue Chain,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals,
SDLoc dl, SelectionDAG &DAG) const;
SDValue LowerReturn_32(SDValue Chain,
CallingConv::ID CallConv, bool IsVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals,
SDLoc DL, SelectionDAG &DAG) const;
SDValue LowerReturn_64(SDValue Chain,
CallingConv::ID CallConv, bool IsVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals,
SDLoc DL, SelectionDAG &DAG) const;
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
unsigned getSRetArgSize(SelectionDAG &DAG, SDValue Callee) const;
SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const;
SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF,
SelectionDAG &DAG) const;
SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerF128_LibCallArg(SDValue Chain, ArgListTy &Args,
SDValue Arg, SDLoc DL,
SelectionDAG &DAG) const;
SDValue LowerF128Op(SDValue Op, SelectionDAG &DAG,
const char *LibFuncName,
unsigned numArgs) const;
SDValue LowerF128Compare(SDValue LHS, SDValue RHS,
unsigned &SPCC,
SDLoc DL,
SelectionDAG &DAG) const;
bool ShouldShrinkFPConstant(EVT VT) const {
// Do not shrink FP constpool if VT == MVT::f128.
// (ldd, call _Q_fdtoq) is more expensive than two ldds.
return VT != MVT::f128;
}
virtual void ReplaceNodeResults(SDNode *N,
SmallVectorImpl<SDValue>& Results,
SelectionDAG &DAG) const;
#endif
};
} // end namespace llvm
#endif // WDC65816_ISELLOWERING_H

View File

@ -1,4 +1,4 @@
//===- WDCInstrFormats.td - WDC 65816 Instruction Formats ----*- tablegen -*-===//
//===- WDCInstrFormats.td - WDC 65816 Instruction Formats --*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//

View File

@ -0,0 +1,65 @@
//===-- WDC65816InstrInfo.cpp - WDC65816 Instruction Information ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the WDC65816 implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//
#include "WDC65816InstrInfo.h"
#include "WDC65816.h"
#include "WDC65816MachineFunctionInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#define GET_INSTRINFO_CTOR_DTOR
#include "WDC65816GenInstrInfo.inc"
using namespace llvm;
// Pin the vtable to this file.
void WDC65816InstrInfo::anchor() {}
WDC65816InstrInfo::WDC65816InstrInfo(void)
: WDC65816GenInstrInfo(WDC::ADJCALLSTACKDOWN, WDC::ADJCALLSTACKUP),
RI() {
}
unsigned WDC65816InstrInfo::getGlobalBaseReg(MachineFunction *MF) const
{
WDC65816MachineFunctionInfo *WDC65816FI = MF->getInfo<WDC65816MachineFunctionInfo>();
return WDC65816FI->getGlobalBaseReg();
#if 0 // WDC_TODO - Do something better here...
unsigned GlobalBaseReg = WDC65816FI->getGlobalBaseReg();
if (GlobalBaseReg != 0)
return GlobalBaseReg;
// Insert the set of GlobalBaseReg into the first MBB of the function
MachineBasicBlock &FirstMBB = MF->front();
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
MachineRegisterInfo &RegInfo = MF->getRegInfo();
GlobalBaseReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
DebugLoc dl;
BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg);
SparcFI->setGlobalBaseReg(GlobalBaseReg);
return GlobalBaseReg;
#endif
}

View File

@ -0,0 +1,43 @@
//===-- WDC65816InstrInfo.h - WDC65816 Instruction Information --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the WDC65816 implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//
#ifndef WDC65816INSTRUCTIONINFO_H
#define WDC65816INSTRUCTIONINFO_H
#include "WDC65816RegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#define GET_INSTRINFO_HEADER
#include "WDC65816GenInstrInfo.inc"
namespace llvm {
class WDC65816InstrInfo : public WDC65816GenInstrInfo {
const WDC65816RegisterInfo RI;
virtual void anchor();
public:
explicit WDC65816InstrInfo(void);
/// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
/// such, whenever a client has an instance of instruction info, it should
/// always be able to get register info as well (through this method).
///
virtual const WDC65816RegisterInfo &getRegisterInfo() const { return RI; }
unsigned getGlobalBaseReg(MachineFunction *MF) const;
};
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
//===- WDC65816MachineFunctionInfo.cpp - WDC65816 Machine Function Info ---===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "WDC65816MachineFunctionInfo.h"
using namespace llvm;
void WDC65816MachineFunctionInfo::anchor() { }

View File

@ -0,0 +1,69 @@
//===- WDC65816MachineFunctionInfo.h - WDC65816 Machine Function Info -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares WDC65816 specific per-machine-function information.
//
//===----------------------------------------------------------------------===//
#ifndef WDC65816MACHINEFUNCTIONINFO_H
#define WDC65816MACHINEFUNCTIONINFO_H
#include "llvm/CodeGen/MachineFunction.h"
namespace llvm {
class WDC65816MachineFunctionInfo : public MachineFunctionInfo {
virtual void anchor();
private:
unsigned GlobalBaseReg;
#if 0 // WDC_TODO - Do I need any of this
/// VarArgsFrameOffset - Frame offset to start of varargs area.
int VarArgsFrameOffset;
/// SRetReturnReg - Holds the virtual register into which the sret
/// argument is passed.
unsigned SRetReturnReg;
/// IsLeafProc - True if the function is a leaf procedure.
bool IsLeafProc;
#endif
public:
WDC65816MachineFunctionInfo()
{}
#if 0 // WDC_TODO - Disable these members for now
: GlobalBaseReg(0), VarArgsFrameOffset(0), SRetReturnReg(0),
IsLeafProc(false) {}
#endif
unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
explicit WDC65816MachineFunctionInfo(MachineFunction &MF)
{}
#if 0 // WDC_TODO - Disable these members for now
: GlobalBaseReg(0), VarArgsFrameOffset(0), SRetReturnReg(0),
IsLeafProc(false) {}
int getVarArgsFrameOffset() const { return VarArgsFrameOffset; }
void setVarArgsFrameOffset(int Offset) { VarArgsFrameOffset = Offset; }
unsigned getSRetReturnReg() const { return SRetReturnReg; }
void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
void setLeafProc(bool rhs) { IsLeafProc = rhs; }
bool isLeafProc() const { return IsLeafProc; }
#endif
};
}
#endif

View File

@ -0,0 +1,210 @@
//===-- WDC65816RegisterInfo.cpp - WDC65816 Register Information ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the WDC65816 implementation of the TargetRegisterInfo class.
//
//===----------------------------------------------------------------------===//
#include "WDC65816RegisterInfo.h"
#include "WDC65816.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetInstrInfo.h"
#define GET_REGINFO_TARGET_DESC
#include "WDC65816GenRegisterInfo.inc"
using namespace llvm;
#if 0 // TODO - What is this?
static cl::opt<bool>
ReserveAppRegisters("sparc-reserve-app-registers", cl::Hidden, cl::init(false),
cl::desc("Reserve application registers (%g2-%g4)"));
#endif
WDC65816RegisterInfo::WDC65816RegisterInfo(void)
: WDC65816GenRegisterInfo(WDC::P) {
}
const uint16_t* WDC65816RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
const {
return CSR_NoRegs_SaveList;
}
const uint32_t*
WDC65816RegisterInfo::getCallPreservedMask(CallingConv::ID CC) const {
return CSR_NoRegs_RegMask;
}
const uint32_t*
WDC65816RegisterInfo::getRTCallPreservedMask(CallingConv::ID CC) const {
return CSR_NoRegs_RegMask;
}
BitVector WDC65816RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
BitVector Reserved(getNumRegs());
// FIXME: G1 reserved for now for large imm generation by frame code.
Reserved.set(WDC::P);
Reserved.set(WDC::S);
Reserved.set(WDC::D);
Reserved.set(WDC::K);
Reserved.set(WDC::B);
Reserved.set(WDC::PC);
Reserved.set(WDC::FP);
return Reserved;
}
unsigned WDC65816RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
return WDC::FP;
}
const TargetRegisterClass*
WDC65816RegisterInfo::getPointerRegClass(const MachineFunction &MF,
unsigned Kind) const {
// WDC_TODO - this is not a pointer reg actually. This should end up being the
// 32-bit direct page registers which are not defined yet.
return &WDC::IndexRegsRegClass;
}
void
WDC65816RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS) const {
// WDC_TODO - Write something here...
}
#if 0 // TODO - How much of this stuff do I need?
static void replaceFI(MachineFunction &MF,
MachineBasicBlock::iterator II,
MachineInstr &MI,
DebugLoc dl,
unsigned FIOperandNum, int Offset,
unsigned FramePtr)
{
// Replace frame index with a frame pointer reference.
if (Offset >= -4096 && Offset <= 4095) {
// If the offset is small enough to fit in the immediate field, directly
// encode it.
MI.getOperand(FIOperandNum).ChangeToRegister(FramePtr, false);
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
return;
}
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
// FIXME: it would be better to scavenge a register here instead of
// reserving G1 all of the time.
if (Offset >= 0) {
// Emit nonnegaive immediates with sethi + or.
// sethi %hi(Offset), %g1
// add %g1, %fp, %g1
// Insert G1+%lo(offset) into the user.
BuildMI(*MI.getParent(), II, dl, TII.get(SP::SETHIi), SP::G1)
.addImm(HI22(Offset));
// Emit G1 = G1 + I6
BuildMI(*MI.getParent(), II, dl, TII.get(SP::ADDrr), SP::G1).addReg(SP::G1)
.addReg(FramePtr);
// Insert: G1+%lo(offset) into the user.
MI.getOperand(FIOperandNum).ChangeToRegister(SP::G1, false);
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(LO10(Offset));
return;
}
// Emit Negative numbers with sethi + xor
// sethi %hix(Offset), %g1
// xor %g1, %lox(offset), %g1
// add %g1, %fp, %g1
// Insert: G1 + 0 into the user.
BuildMI(*MI.getParent(), II, dl, TII.get(SP::SETHIi), SP::G1)
.addImm(HIX22(Offset));
BuildMI(*MI.getParent(), II, dl, TII.get(SP::XORri), SP::G1)
.addReg(SP::G1).addImm(LOX10(Offset));
BuildMI(*MI.getParent(), II, dl, TII.get(SP::ADDrr), SP::G1).addReg(SP::G1)
.addReg(FramePtr);
// Insert: G1+%lo(offset) into the user.
MI.getOperand(FIOperandNum).ChangeToRegister(SP::G1, false);
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
}
void
SparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS) const {
assert(SPAdj == 0 && "Unexpected");
MachineInstr &MI = *II;
DebugLoc dl = MI.getDebugLoc();
int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
// Addressable stack objects are accessed using neg. offsets from %fp
MachineFunction &MF = *MI.getParent()->getParent();
int64_t Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
MI.getOperand(FIOperandNum + 1).getImm() +
Subtarget.getStackPointerBias();
SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
unsigned FramePtr = SP::I6;
if (FuncInfo->isLeafProc()) {
// Use %sp and adjust offset if needed.
FramePtr = SP::O6;
int stackSize = MF.getFrameInfo()->getStackSize();
Offset += (stackSize) ? Subtarget.getAdjustedFrameSize(stackSize) : 0 ;
}
if (!Subtarget.isV9() || !Subtarget.hasHardQuad()) {
if (MI.getOpcode() == SP::STQFri) {
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
unsigned SrcReg = MI.getOperand(2).getReg();
unsigned SrcEvenReg = getSubReg(SrcReg, SP::sub_even64);
unsigned SrcOddReg = getSubReg(SrcReg, SP::sub_odd64);
MachineInstr *StMI =
BuildMI(*MI.getParent(), II, dl, TII.get(SP::STDFri))
.addReg(FramePtr).addImm(0).addReg(SrcEvenReg);
replaceFI(MF, II, *StMI, dl, 0, Offset, FramePtr);
MI.setDesc(TII.get(SP::STDFri));
MI.getOperand(2).setReg(SrcOddReg);
Offset += 8;
} else if (MI.getOpcode() == SP::LDQFri) {
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
unsigned DestReg = MI.getOperand(0).getReg();
unsigned DestEvenReg = getSubReg(DestReg, SP::sub_even64);
unsigned DestOddReg = getSubReg(DestReg, SP::sub_odd64);
MachineInstr *StMI =
BuildMI(*MI.getParent(), II, dl, TII.get(SP::LDDFri), DestEvenReg)
.addReg(FramePtr).addImm(0);
replaceFI(MF, II, *StMI, dl, 1, Offset, FramePtr);
MI.setDesc(TII.get(SP::LDDFri));
MI.getOperand(0).setReg(DestOddReg);
Offset += 8;
}
}
replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FramePtr);
}
unsigned SparcRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
return SP::I6;
}
#endif

View File

@ -0,0 +1,55 @@
//===- WDC65816RegisterInfo.h - WDC65816 Register Information Impl -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the WDC65816 implementation of the TargetRegisterInfo class.
//
//===----------------------------------------------------------------------===//
#ifndef WDC65816REGISTERINFO_H
#define WDC65816REGISTERINFO_H
#include "llvm/Target/TargetRegisterInfo.h"
#define GET_REGINFO_HEADER
#include "WDC65816GenRegisterInfo.inc"
namespace llvm {
class TargetInstrInfo;
class Type;
struct WDC65816RegisterInfo : public WDC65816GenRegisterInfo {
WDC65816RegisterInfo(void);
/// Code Generation virtual methods...
const uint16_t *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
const uint32_t* getCallPreservedMask(CallingConv::ID CC) const;
const uint32_t* getRTCallPreservedMask(CallingConv::ID CC) const;
BitVector getReservedRegs(const MachineFunction &MF) const;
const TargetRegisterClass *getPointerRegClass(const MachineFunction &MF,
unsigned Kind) const;
void eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS = NULL) const;
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS = NULL) const;
// Debug information queries.
unsigned getFrameRegister(const MachineFunction &MF) const;
};
} // end namespace llvm
#endif

View File

@ -1,4 +1,4 @@
//===- WDC65816RegisterInfo.td - WDC65816 Register defs ----------*- tablegen -*-===//
//===- WDC65816RegisterInfo.td - WDC65816 Register defs ----*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -21,8 +21,12 @@ let Namespace = "WDC" in {
def K : Register<"K">;
def B : Register<"B">;
def PC : Register<"PC">;
def FP : Register<"FP">; // WDC_TODO - this will end up being a 32-bit zero page value
}
// WDC_TODO - model all zero page values as a series of 16-bit, 32-bit, 64-bit registers
// Also model them as floating point registers.
def IntRegs : RegisterClass<"WDC", [i16], 8,
(add A, X, Y)>;

View File

@ -0,0 +1,23 @@
//===- WDC65816SelectionDAGInfo.cpp - WDC 65816 SelectionDAG Info ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the WDC65816SelectionDAGInfo class.
//
//===----------------------------------------------------------------------===//
//#define DEBUG_TYPE "sparc-selectiondag-info"
#include "WDC65816TargetMachine.h"
using namespace llvm;
WDC65816SelectionDAGInfo::WDC65816SelectionDAGInfo(const WDC65816TargetMachine &TM)
: TargetSelectionDAGInfo(TM) {
}
WDC65816SelectionDAGInfo::~WDC65816SelectionDAGInfo() {
}

View File

@ -0,0 +1,31 @@
//===- WDC65816SelectionDAGInfo.h - WDC 65816 SelectionDAG Info -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the WDC 65816 subclass for TargetSelectionDAGInfo.
//
//===----------------------------------------------------------------------===//
#ifndef WDC65816SELECTIONDAGINFO_H
#define WDC65816SELECTIONDAGINFO_H
#include "llvm/Target/TargetSelectionDAGInfo.h"
namespace llvm {
class WDC65816TargetMachine;
class WDC65816SelectionDAGInfo : public TargetSelectionDAGInfo {
public:
explicit WDC65816SelectionDAGInfo(const WDC65816TargetMachine &TM);
~WDC65816SelectionDAGInfo();
};
}
#endif

View File

@ -1,4 +1,4 @@
//===-- WDC65816TargetMachine.cpp - Define TargetMachine for WDC65816 -----------===//
//===- WDC65816TargetMachine.cpp - Define TargetMachine for WDC65816 ------===//
//
// The LLVM Compiler Infrastructure
//
@ -54,10 +54,6 @@ namespace {
};
} // namespace
TargetPassConfig *WDC65816TargetMachine::createPassConfig(PassManagerBase &PM) {
return new WDC65816PassConfig(this, PM);
}
bool WDC65816PassConfig::addInstSelector() {
addPass(createWDC65816ISelDag(getWDC65816TargetMachine()));
return false;

View File

@ -1,4 +1,4 @@
//===-- WDC65816TargetMachine.h - Define TargetMachine for WDC65816 ---*- C++ -*-===//
//===- WDC65816TargetMachine.h - Define TargetMachine for WDC65816 -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -25,7 +25,7 @@
namespace llvm {
class WDC65816TargetMachine : public LLVMTargetMachine {
// SparcSubtarget Subtarget; JSR_TODO - Do I need this?
// SparcSubtarget Subtarget; WDC_TODO - Do I need this?
const DataLayout DL; // Calculates type size & alignment
WDC65816InstrInfo InstrInfo;
WDC65816TargetLowering TLInfo;
@ -52,9 +52,11 @@ namespace llvm {
}
virtual const DataLayout *getDataLayout() const { return &DL; }
#if 0 // WDC_TODO - Do I need this? I think these are both related to JIT
// Pass Pipeline Configuration
virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
virtual bool addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &JCE);
#endif
};
} // end namespace llvm