Lots of basic infrastructure. And get it compiling.
This commit is contained in:
parent
51e5e090e2
commit
8c1a0d70be
|
@ -110,6 +110,7 @@ set(LLVM_ALL_TARGETS
|
||||||
R600
|
R600
|
||||||
Sparc
|
Sparc
|
||||||
SystemZ
|
SystemZ
|
||||||
|
WDC65816
|
||||||
X86
|
X86
|
||||||
XCore
|
XCore
|
||||||
)
|
)
|
||||||
|
|
|
@ -71,7 +71,8 @@ public:
|
||||||
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
|
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
|
||||||
amdil, // amdil: amd IL
|
amdil, // amdil: amd IL
|
||||||
spir, // SPIR: standard portable IR for OpenCL 32-bit version
|
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 {
|
enum VendorType {
|
||||||
UnknownVendor,
|
UnknownVendor,
|
||||||
|
|
|
@ -45,6 +45,7 @@ const char *Triple::getArchTypeName(ArchType Kind) {
|
||||||
case amdil: return "amdil";
|
case amdil: return "amdil";
|
||||||
case spir: return "spir";
|
case spir: return "spir";
|
||||||
case spir64: return "spir64";
|
case spir64: return "spir64";
|
||||||
|
case wdc65816: return "wdc65816";
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm_unreachable("Invalid ArchType!");
|
llvm_unreachable("Invalid ArchType!");
|
||||||
|
@ -671,6 +672,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case llvm::Triple::msp430:
|
case llvm::Triple::msp430:
|
||||||
|
case llvm::Triple::wdc65816:
|
||||||
return 16;
|
return 16;
|
||||||
|
|
||||||
case llvm::Triple::amdil:
|
case llvm::Triple::amdil:
|
||||||
|
@ -725,6 +727,7 @@ Triple Triple::get32BitArchVariant() const {
|
||||||
case Triple::msp430:
|
case Triple::msp430:
|
||||||
case Triple::systemz:
|
case Triple::systemz:
|
||||||
case Triple::ppc64le:
|
case Triple::ppc64le:
|
||||||
|
case Triple::wdc65816:
|
||||||
T.setArch(UnknownArch);
|
T.setArch(UnknownArch);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -770,6 +773,7 @@ Triple Triple::get64BitArchVariant() const {
|
||||||
case Triple::tce:
|
case Triple::tce:
|
||||||
case Triple::thumb:
|
case Triple::thumb:
|
||||||
case Triple::xcore:
|
case Triple::xcore:
|
||||||
|
case Triple::wdc65816:
|
||||||
T.setArch(UnknownArch);
|
T.setArch(UnknownArch);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
@ -1,4 +1,4 @@
|
||||||
;===- ./lib/Target/WDC65816/LLVMBuild.txt -------------------------*- Conf -*--===;
|
;===- ./lib/Target/WDC65816/LLVMBuild.txt ----------------------*- Conf -*--===;
|
||||||
;
|
;
|
||||||
; The LLVM Compiler Infrastructure
|
; The LLVM Compiler Infrastructure
|
||||||
;
|
;
|
||||||
|
@ -16,19 +16,19 @@
|
||||||
;===------------------------------------------------------------------------===;
|
;===------------------------------------------------------------------------===;
|
||||||
|
|
||||||
[common]
|
[common]
|
||||||
subdirectories =
|
subdirectories = MCTargetDesc TargetInfo
|
||||||
|
|
||||||
[component_0]
|
[component_0]
|
||||||
type = TargetGroup
|
type = TargetGroup
|
||||||
name = WDC65816
|
name = WDC65816
|
||||||
parent = Target
|
parent = Target
|
||||||
has_asmprinter = 0
|
has_asmprinter = 1
|
||||||
has_jit = 0
|
has_jit = 0
|
||||||
|
|
||||||
[component_1]
|
[component_1]
|
||||||
type = Library
|
type = Library
|
||||||
name = WDC65816CodeGen
|
name = WDC65816CodeGen
|
||||||
parent = WDC65816
|
parent = WDC65816
|
||||||
required_libraries = AsmPrinter CodeGen Core MC SelectionDAG
|
required_libraries = AsmPrinter CodeGen Core MC SelectionDAG WDC65816Desc
|
||||||
Support Target
|
WDC65816Info Support Target
|
||||||
add_to_library_groups = WDC65816
|
add_to_library_groups = WDC65816
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
add_llvm_library(LLVMWDC65816Desc
|
||||||
|
WDC65816MCTargetDesc.cpp
|
||||||
|
WDC65816MCAsmInfo.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_dependencies(LLVMWDC65816Desc WDC65816CommonTableGen)
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
|
@ -14,10 +14,9 @@ TARGET = WDC65816
|
||||||
# Make sure that tblgen is run, first thing.
|
# Make sure that tblgen is run, first thing.
|
||||||
BUILT_SOURCES = WDC65816GenRegisterInfo.inc WDC65816GenInstrInfo.inc \
|
BUILT_SOURCES = WDC65816GenRegisterInfo.inc WDC65816GenInstrInfo.inc \
|
||||||
WDC65816GenAsmWriter.inc WDC65816GenDAGISel.inc \
|
WDC65816GenAsmWriter.inc WDC65816GenDAGISel.inc \
|
||||||
WDC65816GenSubtargetInfo.inc WDC65816GenCallingConv.inc \
|
WDC65816GenSubtargetInfo.inc WDC65816GenCallingConv.inc
|
||||||
WDC65816GenCodeEmitter.inc
|
|
||||||
|
|
||||||
# DIRS = InstPrinter Disassembler AsmParser TargetInfo MCTargetDesc
|
DIRS = TargetInfo MCTargetDesc
|
||||||
|
|
||||||
include $(LEVEL)/Makefile.common
|
include $(LEVEL)/Makefile.common
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
|
||||||
|
|
||||||
|
add_llvm_library(LLVMWDC65816Info
|
||||||
|
WDC65816TargetInfo.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_dependencies(LLVMWDC65816Info WDC65816CommonTableGen)
|
|
@ -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
|
|
@ -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
|
|
@ -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();
|
||||||
|
}
|
|
@ -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
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
|
@ -15,6 +15,7 @@
|
||||||
#ifndef WDC65816_H
|
#ifndef WDC65816_H
|
||||||
#define WDC65816_H
|
#define WDC65816_H
|
||||||
|
|
||||||
|
#include "MCTargetDesc/WDC65816MCTargetDesc.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
|
|
||||||
|
@ -28,7 +29,7 @@ namespace llvm {
|
||||||
} // end namespace llvm;
|
} // end namespace llvm;
|
||||||
|
|
||||||
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
|
// 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.
|
// values must be kept in sync with the ones in the .td file.
|
||||||
namespace SPCC {
|
namespace SPCC {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//===-- WDC65816.td - Describe the WDC65816 Target Machine -------*- tablegen -*-===//
|
//===-- WDC65816.td - Describe the WDC65816 Target Machine -*- tablegen -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
//===- WDCCallingConv.td - Calling Conventions WDC65816 -----*- tablegen -*-===//
|
//===- WDCCallingConv.td - Calling Conventions WDC65816 ----*- tablegen -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
|
@ -27,3 +27,6 @@ def CC_WDC : CallingConv<[
|
||||||
CCIfType<[i16], CCAssignToStack<2, 1>>,
|
CCIfType<[i16], CCAssignToStack<2, 1>>,
|
||||||
CCIfType<[i32, f32], CCAssignToStack<4, 1>>
|
CCIfType<[i32, f32], CCAssignToStack<4, 1>>
|
||||||
]>;
|
]>;
|
||||||
|
|
||||||
|
|
||||||
|
def CSR_NoRegs : CalleeSavedRegs<(add)>;
|
|
@ -1,4 +1,4 @@
|
||||||
//===-- WDC65816FrameLowering.cpp - WDC65816 Frame Information ------------------===//
|
//===-- WDC65816FrameLowering.cpp - WDC65816 Frame Information ------------===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
|
@ -24,6 +24,22 @@
|
||||||
|
|
||||||
using namespace llvm;
|
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?
|
#if 0 // JSR TODO - Do I need any of this?
|
||||||
static cl::opt<bool>
|
static cl::opt<bool>
|
||||||
DisableLeafProc("disable-sparc-leaf-proc",
|
DisableLeafProc("disable-sparc-leaf-proc",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//===-- WDC65816FrameLowering.h - Define frame lowering for Sparc --*- C++ -*-===//
|
//===- WDC65816FrameLowering.h - Define frame lowering for Sparc -*- C++ -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
|
@ -23,18 +23,20 @@ namespace llvm {
|
||||||
public:
|
public:
|
||||||
explicit WDC65816FrameLowering(void)
|
explicit WDC65816FrameLowering(void)
|
||||||
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 1, 0) {}
|
: 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
|
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
|
||||||
/// the function.
|
/// the function.
|
||||||
void emitPrologue(MachineFunction &MF) const;
|
void emitPrologue(MachineFunction &MF) const;
|
||||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||||
|
#if 0 // JSR TODO - do I need any of this?
|
||||||
|
|
||||||
void eliminateCallFramePseudoInstr(MachineFunction &MF,
|
void eliminateCallFramePseudoInstr(MachineFunction &MF,
|
||||||
MachineBasicBlock &MBB,
|
MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator I) const;
|
MachineBasicBlock::iterator I) const;
|
||||||
|
|
||||||
bool hasReservedCallFrame(const MachineFunction &MF) const;
|
bool hasReservedCallFrame(const MachineFunction &MF) const;
|
||||||
bool hasFP(const MachineFunction &MF) const;
|
|
||||||
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||||
RegScavenger *RS = NULL) const;
|
RegScavenger *RS = NULL) const;
|
||||||
|
|
||||||
|
|
|
@ -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
|
@ -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
|
|
@ -1,4 +1,4 @@
|
||||||
//===- WDCInstrFormats.td - WDC 65816 Instruction Formats ----*- tablegen -*-===//
|
//===- WDCInstrFormats.td - WDC 65816 Instruction Formats --*- tablegen -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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
|
@ -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() { }
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -1,4 +1,4 @@
|
||||||
//===- WDC65816RegisterInfo.td - WDC65816 Register defs ----------*- tablegen -*-===//
|
//===- WDC65816RegisterInfo.td - WDC65816 Register defs ----*- tablegen -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
|
@ -21,8 +21,12 @@ let Namespace = "WDC" in {
|
||||||
def K : Register<"K">;
|
def K : Register<"K">;
|
||||||
def B : Register<"B">;
|
def B : Register<"B">;
|
||||||
def PC : Register<"PC">;
|
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,
|
def IntRegs : RegisterClass<"WDC", [i16], 8,
|
||||||
(add A, X, Y)>;
|
(add A, X, Y)>;
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
}
|
|
@ -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
|
|
@ -1,4 +1,4 @@
|
||||||
//===-- WDC65816TargetMachine.cpp - Define TargetMachine for WDC65816 -----------===//
|
//===- WDC65816TargetMachine.cpp - Define TargetMachine for WDC65816 ------===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
|
@ -54,10 +54,6 @@ namespace {
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TargetPassConfig *WDC65816TargetMachine::createPassConfig(PassManagerBase &PM) {
|
|
||||||
return new WDC65816PassConfig(this, PM);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WDC65816PassConfig::addInstSelector() {
|
bool WDC65816PassConfig::addInstSelector() {
|
||||||
addPass(createWDC65816ISelDag(getWDC65816TargetMachine()));
|
addPass(createWDC65816ISelDag(getWDC65816TargetMachine()));
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//===-- WDC65816TargetMachine.h - Define TargetMachine for WDC65816 ---*- C++ -*-===//
|
//===- WDC65816TargetMachine.h - Define TargetMachine for WDC65816 -*- C++ -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class WDC65816TargetMachine : public LLVMTargetMachine {
|
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
|
const DataLayout DL; // Calculates type size & alignment
|
||||||
WDC65816InstrInfo InstrInfo;
|
WDC65816InstrInfo InstrInfo;
|
||||||
WDC65816TargetLowering TLInfo;
|
WDC65816TargetLowering TLInfo;
|
||||||
|
@ -52,9 +52,11 @@ namespace llvm {
|
||||||
}
|
}
|
||||||
virtual const DataLayout *getDataLayout() const { return &DL; }
|
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
|
// Pass Pipeline Configuration
|
||||||
virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
|
virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
|
||||||
virtual bool addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &JCE);
|
virtual bool addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &JCE);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
Loading…
Reference in New Issue