mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-05 13:26:55 +00:00
Add 64-bit addressing to PTX backend
- Add '64bit' sub-target option. - Select 32-bit/64-bit loads/stores based on '64bit' option. - Fix function parameter order. Patch by Justin Holewinski git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126837 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -24,6 +24,9 @@ include "llvm/Target/Target.td"
|
||||
def FeatureDouble : SubtargetFeature<"double", "SupportsDouble", "true",
|
||||
"Do not demote .f64 to .f32">;
|
||||
|
||||
def Feature64Bit : SubtargetFeature<"64bit", "Use64BitAddresses", "true",
|
||||
"Use 64-bit integer types for addresses.">;
|
||||
|
||||
//===- PTX Version --------------------------------------------------------===//
|
||||
|
||||
def FeaturePTX14 : SubtargetFeature<"ptx14", "PTXVersion", "PTX_VERSION_1_4",
|
||||
|
@@ -360,20 +360,21 @@ void PTXAsmPrinter::EmitFunctionDeclaration() {
|
||||
if (isKernel) {
|
||||
unsigned cnt = 0;
|
||||
//for (int i = 0, e = MFI->getNumArg(); i != e; ++i) {
|
||||
for(PTXMachineFunctionInfo::reg_iterator
|
||||
i = MFI->argRegBegin(), e = MFI->argRegEnd(), b = i; i != e; ++i) {
|
||||
for(PTXMachineFunctionInfo::reg_reverse_iterator
|
||||
i = MFI->argRegReverseBegin(), e = MFI->argRegReverseEnd(), b = i; i != e; ++i) {
|
||||
reg = *i;
|
||||
assert(reg != PTX::NoRegister && "Not a valid register!");
|
||||
if (i != b)
|
||||
decl += ", ";
|
||||
decl += ".param .u32"; // TODO: Parse type from register map
|
||||
decl += ".param .";
|
||||
decl += getRegisterTypeName(reg);
|
||||
decl += " ";
|
||||
decl += PARAM_PREFIX;
|
||||
decl += utostr(++cnt);
|
||||
}
|
||||
} else {
|
||||
for (PTXMachineFunctionInfo::reg_iterator
|
||||
i = MFI->argRegBegin(), e = MFI->argRegEnd(), b = i; i != e; ++i) {
|
||||
for (PTXMachineFunctionInfo::reg_reverse_iterator
|
||||
i = MFI->argRegReverseBegin(), e = MFI->argRegReverseEnd(), b = i; i != e; ++i) {
|
||||
reg = *i;
|
||||
assert(reg != PTX::NoRegister && "Not a valid register!");
|
||||
if (i != b)
|
||||
|
@@ -45,6 +45,8 @@ class PTXDAGToDAGISel : public SelectionDAGISel {
|
||||
|
||||
bool isImm(const SDValue &operand);
|
||||
bool SelectImm(const SDValue &operand, SDValue &imm);
|
||||
|
||||
const PTXSubtarget& getSubtarget() const;
|
||||
}; // class PTXDAGToDAGISel
|
||||
} // namespace
|
||||
|
||||
@@ -170,3 +172,9 @@ bool PTXDAGToDAGISel::SelectImm(const SDValue &operand, SDValue &imm) {
|
||||
imm = CurDAG->getTargetConstant(*CN->getConstantIntValue(), MVT::i32);
|
||||
return true;
|
||||
}
|
||||
|
||||
const PTXSubtarget& PTXDAGToDAGISel::getSubtarget() const
|
||||
{
|
||||
return TM.getSubtarget<PTXSubtarget>();
|
||||
}
|
||||
|
||||
|
@@ -17,6 +17,13 @@
|
||||
|
||||
include "PTXInstrFormats.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Code Generation Predicates
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def Use32BitAddresses : Predicate<"!getSubtarget().use64BitAddresses()">;
|
||||
def Use64BitAddresses : Predicate<"getSubtarget().use64BitAddresses()">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction Pattern Stuff
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -107,24 +114,39 @@ def store_shared
|
||||
}]>;
|
||||
|
||||
// Addressing modes.
|
||||
def ADDRrr : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;
|
||||
def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [], []>;
|
||||
def ADDRii : ComplexPattern<i32, 2, "SelectADDRii", [], []>;
|
||||
def ADDRrr32 : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;
|
||||
def ADDRrr64 : ComplexPattern<i64, 2, "SelectADDRrr", [], []>;
|
||||
def ADDRri32 : ComplexPattern<i32, 2, "SelectADDRri", [], []>;
|
||||
def ADDRri64 : ComplexPattern<i64, 2, "SelectADDRri", [], []>;
|
||||
def ADDRii32 : ComplexPattern<i32, 2, "SelectADDRii", [], []>;
|
||||
def ADDRii64 : ComplexPattern<i64, 2, "SelectADDRii", [], []>;
|
||||
|
||||
|
||||
// Address operands
|
||||
def MEMri : Operand<i32> {
|
||||
def MEMri32 : Operand<i32> {
|
||||
let PrintMethod = "printMemOperand";
|
||||
let MIOperandInfo = (ops RRegu32, i32imm);
|
||||
}
|
||||
def MEMii : Operand<i32> {
|
||||
def MEMri64 : Operand<i64> {
|
||||
let PrintMethod = "printMemOperand";
|
||||
let MIOperandInfo = (ops RRegu64, i64imm);
|
||||
}
|
||||
def MEMii32 : Operand<i32> {
|
||||
let PrintMethod = "printMemOperand";
|
||||
let MIOperandInfo = (ops i32imm, i32imm);
|
||||
}
|
||||
def MEMii64 : Operand<i64> {
|
||||
let PrintMethod = "printMemOperand";
|
||||
let MIOperandInfo = (ops i64imm, i64imm);
|
||||
}
|
||||
// The operand here does not correspond to an actual address, so we
|
||||
// can use i32 in 64-bit address modes.
|
||||
def MEMpi : Operand<i32> {
|
||||
let PrintMethod = "printParamOperand";
|
||||
let MIOperandInfo = (ops i32imm);
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PTX Specific Node Definitions
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -207,18 +229,30 @@ multiclass INT3ntnc<string opcstr, SDNode opnode> {
|
||||
}
|
||||
|
||||
multiclass PTX_LD<string opstr, string typestr, RegisterClass RC, PatFrag pat_load> {
|
||||
def rr : InstPTX<(outs RC:$d),
|
||||
(ins MEMri:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
||||
[(set RC:$d, (pat_load ADDRrr:$a))]>;
|
||||
def ri : InstPTX<(outs RC:$d),
|
||||
(ins MEMri:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
||||
[(set RC:$d, (pat_load ADDRri:$a))]>;
|
||||
def ii : InstPTX<(outs RC:$d),
|
||||
(ins MEMii:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
||||
[(set RC:$d, (pat_load ADDRii:$a))]>;
|
||||
def rr32 : InstPTX<(outs RC:$d),
|
||||
(ins MEMri32:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
||||
[(set RC:$d, (pat_load ADDRrr32:$a))]>, Requires<[Use32BitAddresses]>;
|
||||
def rr64 : InstPTX<(outs RC:$d),
|
||||
(ins MEMri64:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
||||
[(set RC:$d, (pat_load ADDRrr64:$a))]>, Requires<[Use64BitAddresses]>;
|
||||
def ri32 : InstPTX<(outs RC:$d),
|
||||
(ins MEMri32:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
||||
[(set RC:$d, (pat_load ADDRri32:$a))]>, Requires<[Use32BitAddresses]>;
|
||||
def ri64 : InstPTX<(outs RC:$d),
|
||||
(ins MEMri64:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
||||
[(set RC:$d, (pat_load ADDRri64:$a))]>, Requires<[Use64BitAddresses]>;
|
||||
def ii32 : InstPTX<(outs RC:$d),
|
||||
(ins MEMii32:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
||||
[(set RC:$d, (pat_load ADDRii32:$a))]>, Requires<[Use32BitAddresses]>;
|
||||
def ii64 : InstPTX<(outs RC:$d),
|
||||
(ins MEMii64:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t$d, [$a]")),
|
||||
[(set RC:$d, (pat_load ADDRii64:$a))]>, Requires<[Use64BitAddresses]>;
|
||||
}
|
||||
|
||||
multiclass PTX_LD_ALL<string opstr, PatFrag pat_load> {
|
||||
@@ -230,18 +264,30 @@ multiclass PTX_LD_ALL<string opstr, PatFrag pat_load> {
|
||||
}
|
||||
|
||||
multiclass PTX_ST<string opstr, string typestr, RegisterClass RC, PatFrag pat_store> {
|
||||
def rr : InstPTX<(outs),
|
||||
(ins RC:$d, MEMri:$a),
|
||||
def rr32 : InstPTX<(outs),
|
||||
(ins RC:$d, MEMri32:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
|
||||
[(pat_store RC:$d, ADDRrr32:$a)]>, Requires<[Use32BitAddresses]>;
|
||||
def rr64 : InstPTX<(outs),
|
||||
(ins RC:$d, MEMri64:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
|
||||
[(pat_store RC:$d, ADDRrr64:$a)]>, Requires<[Use64BitAddresses]>;
|
||||
def ri32 : InstPTX<(outs),
|
||||
(ins RC:$d, MEMri32:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
|
||||
[(pat_store RC:$d, ADDRrr:$a)]>;
|
||||
def ri : InstPTX<(outs),
|
||||
(ins RC:$d, MEMri:$a),
|
||||
[(pat_store RC:$d, ADDRri32:$a)]>, Requires<[Use32BitAddresses]>;
|
||||
def ri64 : InstPTX<(outs),
|
||||
(ins RC:$d, MEMri64:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
|
||||
[(pat_store RC:$d, ADDRri:$a)]>;
|
||||
def ii : InstPTX<(outs),
|
||||
(ins RC:$d, MEMii:$a),
|
||||
[(pat_store RC:$d, ADDRri64:$a)]>, Requires<[Use64BitAddresses]>;
|
||||
def ii32 : InstPTX<(outs),
|
||||
(ins RC:$d, MEMii32:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
|
||||
[(pat_store RC:$d, ADDRii:$a)]>;
|
||||
[(pat_store RC:$d, ADDRii32:$a)]>, Requires<[Use32BitAddresses]>;
|
||||
def ii64 : InstPTX<(outs),
|
||||
(ins RC:$d, MEMii64:$a),
|
||||
!strconcat(opstr, !strconcat(typestr, "\t[$a], $d")),
|
||||
[(pat_store RC:$d, ADDRii64:$a)]>, Requires<[Use64BitAddresses]>;
|
||||
}
|
||||
|
||||
multiclass PTX_ST_ALL<string opstr, PatFrag pat_store> {
|
||||
|
@@ -53,14 +53,17 @@ public:
|
||||
|
||||
bool isKernel() const { return is_kernel; }
|
||||
|
||||
typedef std::vector<unsigned>::const_iterator reg_iterator;
|
||||
typedef std::vector<unsigned>::const_iterator reg_iterator;
|
||||
typedef std::vector<unsigned>::const_reverse_iterator reg_reverse_iterator;
|
||||
|
||||
bool argRegEmpty() const { return reg_arg.empty(); }
|
||||
int getNumArg() const { return reg_arg.size(); }
|
||||
bool argRegEmpty() const { return reg_arg.empty(); }
|
||||
int getNumArg() const { return reg_arg.size(); }
|
||||
reg_iterator argRegBegin() const { return reg_arg.begin(); }
|
||||
reg_iterator argRegEnd() const { return reg_arg.end(); }
|
||||
reg_reverse_iterator argRegReverseBegin() const { return reg_arg.rbegin(); }
|
||||
reg_reverse_iterator argRegReverseEnd() const { return reg_arg.rend(); }
|
||||
|
||||
bool localVarRegEmpty() const { return reg_local_var.empty(); }
|
||||
bool localVarRegEmpty() const { return reg_local_var.empty(); }
|
||||
reg_iterator localVarRegBegin() const { return reg_local_var.begin(); }
|
||||
reg_iterator localVarRegEnd() const { return reg_local_var.end(); }
|
||||
|
||||
|
@@ -18,7 +18,9 @@ using namespace llvm;
|
||||
|
||||
PTXSubtarget::PTXSubtarget(const std::string &TT, const std::string &FS)
|
||||
: PTXShaderModel(PTX_SM_1_0),
|
||||
PTXVersion(PTX_VERSION_1_4) {
|
||||
PTXVersion(PTX_VERSION_1_4),
|
||||
SupportsDouble(false),
|
||||
Use64BitAddresses(false) {
|
||||
std::string TARGET = "generic";
|
||||
ParseSubtargetFeatures(FS, TARGET);
|
||||
}
|
||||
|
@@ -40,6 +40,9 @@ namespace llvm {
|
||||
// The native .f64 type is supported on the hardware.
|
||||
bool SupportsDouble;
|
||||
|
||||
// Use .u64 instead of .u32 for addresses.
|
||||
bool Use64BitAddresses;
|
||||
|
||||
public:
|
||||
PTXSubtarget(const std::string &TT, const std::string &FS);
|
||||
|
||||
@@ -49,6 +52,8 @@ namespace llvm {
|
||||
|
||||
bool supportsDouble() const { return SupportsDouble; }
|
||||
|
||||
bool use64BitAddresses() const { return Use64BitAddresses; }
|
||||
|
||||
std::string ParseSubtargetFeatures(const std::string &FS,
|
||||
const std::string &CPU);
|
||||
}; // class PTXSubtarget
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include "PTXTargetMachine.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Target/TargetRegistry.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@@ -34,16 +35,24 @@ extern "C" void LLVMInitializePTXTarget() {
|
||||
TargetRegistry::RegisterAsmStreamer(ThePTXTarget, createPTXAsmStreamer);
|
||||
}
|
||||
|
||||
namespace {
|
||||
const char* DataLayout32 = "e-p:32:32-i64:32:32-f64:32:32-v128:32:128-v64:32:64-n32:64";
|
||||
const char* DataLayout64 = "e-p:64:64-i64:32:32-f64:32:32-v128:32:128-v64:32:64-n32:64";
|
||||
}
|
||||
|
||||
// DataLayout and FrameLowering are filled with dummy data
|
||||
PTXTargetMachine::PTXTargetMachine(const Target &T,
|
||||
const std::string &TT,
|
||||
const std::string &FS)
|
||||
: LLVMTargetMachine(T, TT),
|
||||
DataLayout("e-p:32:32-i64:32:32-f64:32:32-v128:32:128-v64:32:64-n32:64"),
|
||||
: Subtarget(TT, FS),
|
||||
// FIXME: This feels like a dirty hack, but Subtarget does not appear to be
|
||||
// initialized at this point, and we need to finish initialization of
|
||||
// DataLayout.
|
||||
DataLayout((FS.find("64bit") != FS.npos) ? DataLayout64 : DataLayout32),
|
||||
LLVMTargetMachine(T, TT),
|
||||
FrameLowering(Subtarget),
|
||||
InstrInfo(*this),
|
||||
TLInfo(*this),
|
||||
Subtarget(TT, FS) {
|
||||
InstrInfo(*this) {
|
||||
}
|
||||
|
||||
bool PTXTargetMachine::addInstSelector(PassManagerBase &PM,
|
||||
|
@@ -25,11 +25,11 @@
|
||||
namespace llvm {
|
||||
class PTXTargetMachine : public LLVMTargetMachine {
|
||||
private:
|
||||
const TargetData DataLayout;
|
||||
PTXFrameLowering FrameLowering;
|
||||
PTXInstrInfo InstrInfo;
|
||||
const TargetData DataLayout;
|
||||
PTXFrameLowering FrameLowering;
|
||||
PTXInstrInfo InstrInfo;
|
||||
PTXTargetLowering TLInfo;
|
||||
PTXSubtarget Subtarget;
|
||||
PTXSubtarget Subtarget;
|
||||
|
||||
public:
|
||||
PTXTargetMachine(const Target &T, const std::string &TT,
|
||||
|
Reference in New Issue
Block a user