mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-17 03:30:28 +00:00
ptx: add ld instruction
support register and register-immediate addressing mode todo: immediate and register-register addressing mode git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120407 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cf82dc376a
commit
3f8e617891
@ -49,6 +49,8 @@ public:
|
||||
virtual void EmitInstruction(const MachineInstr *MI);
|
||||
|
||||
void printOperand(const MachineInstr *MI, int opNum, raw_ostream &OS);
|
||||
void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &OS,
|
||||
const char *Modifier = 0);
|
||||
|
||||
// autogen'd.
|
||||
void printInstruction(const MachineInstr *MI, raw_ostream &OS);
|
||||
@ -61,7 +63,7 @@ private:
|
||||
|
||||
static const char PARAM_PREFIX[] = "__param_";
|
||||
|
||||
static const char *getRegisterTypeName(unsigned RegNo){
|
||||
static const char *getRegisterTypeName(unsigned RegNo) {
|
||||
#define TEST_REGCLS(cls, clsstr) \
|
||||
if (PTX::cls ## RegisterClass->contains(RegNo)) return # clsstr;
|
||||
TEST_REGCLS(RRegs32, s32);
|
||||
@ -72,8 +74,7 @@ static const char *getRegisterTypeName(unsigned RegNo){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *getInstructionTypeName(const MachineInstr *MI)
|
||||
{
|
||||
static const char *getInstructionTypeName(const MachineInstr *MI) {
|
||||
for (int i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||
const MachineOperand &MO = MI->getOperand(i);
|
||||
if (MO.getType() == MachineOperand::MO_Register)
|
||||
@ -119,13 +120,13 @@ void PTXAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
// Replace "%type" if found
|
||||
StringRef strref = OS.str();
|
||||
size_t pos;
|
||||
if ((pos = strref.find("%type")) == StringRef::npos) {
|
||||
OutStreamer.EmitRawText(strref);
|
||||
return;
|
||||
if ((pos = strref.find("%type")) != StringRef::npos) {
|
||||
std::string str = strref;
|
||||
str.replace(pos, /*strlen("%type")==*/5, getInstructionTypeName(MI));
|
||||
strref = StringRef(str);
|
||||
}
|
||||
std::string str = strref;
|
||||
str.replace(pos, /*strlen("%type")==*/5, getInstructionTypeName(MI));
|
||||
OutStreamer.EmitRawText(StringRef(str));
|
||||
|
||||
OutStreamer.EmitRawText(strref);
|
||||
}
|
||||
|
||||
void PTXAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
|
||||
@ -145,6 +146,17 @@ void PTXAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
|
||||
}
|
||||
}
|
||||
|
||||
void PTXAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
|
||||
raw_ostream &OS, const char *Modifier) {
|
||||
printOperand(MI, opNum, OS);
|
||||
|
||||
if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() == 0)
|
||||
return; // don't print "+0"
|
||||
|
||||
OS << "+";
|
||||
printOperand(MI, opNum+1, OS);
|
||||
}
|
||||
|
||||
void PTXAsmPrinter::EmitFunctionDeclaration() {
|
||||
// The function label could have already been emitted if two symbols end up
|
||||
// conflicting due to asm renaming. Detect this and emit an error.
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "PTX.h"
|
||||
#include "PTXTargetMachine.h"
|
||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -30,9 +31,16 @@ class PTXDAGToDAGISel : public SelectionDAGISel {
|
||||
|
||||
SDNode *Select(SDNode *Node);
|
||||
|
||||
// Complex Pattern Selectors.
|
||||
bool SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset);
|
||||
bool SelectADDRii(SDValue &Addr, SDValue &Base, SDValue &Offset);
|
||||
|
||||
// Include the pieces auto'gened from the target description
|
||||
#include "PTXGenDAGISel.inc"
|
||||
|
||||
private:
|
||||
bool isImm (const SDValue &operand);
|
||||
bool SelectImm (const SDValue &operand, SDValue &imm);
|
||||
}; // class PTXDAGToDAGISel
|
||||
} // namespace
|
||||
|
||||
@ -51,3 +59,54 @@ SDNode *PTXDAGToDAGISel::Select(SDNode *Node) {
|
||||
// SelectCode() is auto'gened
|
||||
return SelectCode(Node);
|
||||
}
|
||||
|
||||
// Match memory operand of the form [reg+reg] and [reg+imm]
|
||||
bool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base,
|
||||
SDValue &Offset) {
|
||||
if (Addr.getNumOperands() >= 2 &&
|
||||
isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1)))
|
||||
return false; // let SelectADDRii handle the [imm+imm] case
|
||||
|
||||
// try [reg+imm] and [imm+reg]
|
||||
if (Addr.getOpcode() == ISD::ADD)
|
||||
for (int i = 0; i < 2; i ++)
|
||||
if (SelectImm(Addr.getOperand(1-i), Offset)) {
|
||||
Base = Addr.getOperand(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
// okay, it's [reg+reg]
|
||||
Base = Addr;
|
||||
Offset = CurDAG->getTargetConstant(0, MVT::i32);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Match memory operand of the form [imm+imm] and [imm]
|
||||
bool PTXDAGToDAGISel::SelectADDRii(SDValue &Addr, SDValue &Base,
|
||||
SDValue &Offset) {
|
||||
if (Addr.getOpcode() == ISD::ADD) {
|
||||
return SelectImm(Addr.getOperand(0), Base) &&
|
||||
SelectImm(Addr.getOperand(1), Offset);
|
||||
}
|
||||
|
||||
if (SelectImm(Addr, Base)) {
|
||||
Offset = CurDAG->getTargetConstant(0, MVT::i32);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PTXDAGToDAGISel::isImm(const SDValue &operand) {
|
||||
return ConstantSDNode::classof(operand.getNode());
|
||||
}
|
||||
|
||||
bool PTXDAGToDAGISel::SelectImm(const SDValue &operand, SDValue &imm) {
|
||||
SDNode *node = operand.getNode();
|
||||
if (!ConstantSDNode::classof(node))
|
||||
return false;
|
||||
|
||||
ConstantSDNode *CN = cast<ConstantSDNode>(node);
|
||||
imm = CurDAG->getTargetConstant(*CN->getConstantIntValue(), MVT::i32);
|
||||
return true;
|
||||
}
|
||||
|
@ -17,6 +17,31 @@
|
||||
|
||||
include "PTXInstrFormats.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction Pattern Stuff
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def load_global : PatFrag<(ops node:$ptr), (load node:$ptr), [{
|
||||
if (const Value *Src = cast<LoadSDNode>(N)->getSrcValue())
|
||||
if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
|
||||
return PT->getAddressSpace() <= 255;
|
||||
return false;
|
||||
}]>;
|
||||
|
||||
// Addressing modes.
|
||||
def ADDRri : ComplexPattern<i32, 2, "SelectADDRri", [], []>;
|
||||
def ADDRii : ComplexPattern<i32, 2, "SelectADDRii", [], []>;
|
||||
|
||||
// Address operands
|
||||
def MEMri : Operand<i32> {
|
||||
let PrintMethod = "printMemOperand";
|
||||
let MIOperandInfo = (ops RRegs32, i32imm);
|
||||
}
|
||||
def MEMii : Operand<i32> {
|
||||
let PrintMethod = "printMemOperand";
|
||||
let MIOperandInfo = (ops i32imm, i32imm);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PTX Specific Node Definitions
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -41,6 +66,17 @@ multiclass INT3<string opcstr, SDNode opnode> {
|
||||
[(set RRegs32:$d, (opnode RRegs32:$a, imm:$b))]>;
|
||||
}
|
||||
|
||||
multiclass PTX_LD<string opstr, RegisterClass RC, PatFrag pat_load> {
|
||||
def ri : InstPTX<(outs RC:$d),
|
||||
(ins MEMri:$a),
|
||||
!strconcat(opstr, ".%type\t$d, [$a]"),
|
||||
[(set RC:$d, (pat_load ADDRri:$a))]>;
|
||||
def ii : InstPTX<(outs RC:$d),
|
||||
(ins MEMii:$a),
|
||||
!strconcat(opstr, ".%type\t$d, [$a]"),
|
||||
[(set RC:$d, (pat_load ADDRii:$a))]>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -69,6 +105,8 @@ let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
|
||||
[(set RRegs32:$d, imm:$a)]>;
|
||||
}
|
||||
|
||||
defm LDg : PTX_LD<"ld.global", RRegs32, load_global>;
|
||||
|
||||
///===- Control Flow Instructions -----------------------------------------===//
|
||||
|
||||
let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
|
||||
|
Loading…
Reference in New Issue
Block a user