1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

skeleton of a lowerCall implementation for ARM

llvm-svn: 29159
This commit is contained in:
Rafael Espindola 2006-07-16 01:02:57 +00:00
parent ff3dc2868c
commit 40073f5767
3 changed files with 79 additions and 5 deletions

View File

@ -156,9 +156,11 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
assert(0 && "not implemented");
abort();
return;
case MachineOperand::MO_GlobalAddress:
assert(0 && "not implemented");
abort();
case MachineOperand::MO_GlobalAddress: {
GlobalValue *GV = MO.getGlobal();
std::string Name = Mang->getValueName(GV);
O << Name;
}
break;
case MachineOperand::MO_ExternalSymbol:
assert(0 && "not implemented");

View File

@ -13,6 +13,7 @@
#include "ARM.h"
#include "ARMTargetMachine.h"
#include "llvm/CallingConv.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Intrinsics.h"
@ -33,6 +34,7 @@ namespace {
public:
ARMTargetLowering(TargetMachine &TM);
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
virtual const char *getTargetNodeName(unsigned Opcode) const;
};
}
@ -42,9 +44,73 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
setOperationAction(ISD::RET, MVT::Other, Custom);
}
namespace llvm {
namespace ARMISD {
enum NodeType {
// Start the numbering where the builting ops and target ops leave off.
FIRST_NUMBER = ISD::BUILTIN_OP_END+ARM::INSTRUCTION_LIST_END,
/// CALL - A direct function call.
CALL
};
}
}
const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
switch (Opcode) {
default: return 0;
case ARMISD::CALL: return "ARMISD::CALL";
}
}
// This transforms a ISD::CALL node into a
// callseq_star <- ARMISD:CALL <- callseq_end
// chain
static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
assert(0 && "Not implemented");
abort();
SDOperand Chain = Op.getOperand(0);
unsigned CallConv = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
assert(CallConv == CallingConv::C && "unknown calling convention");
bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
assert(isVarArg == false && "VarArg not supported");
bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
assert(isTailCall == false && "tail call not supported");
SDOperand Callee = Op.getOperand(4);
unsigned NumOps = (Op.getNumOperands() - 5) / 2;
assert(NumOps == 0);
// Count how many bytes are to be pushed on the stack. Initially
// only the link register.
unsigned NumBytes = 4;
// Adjust the stack pointer for the new arguments...
// These operations are automatically eliminated by the prolog/epilog pass
Chain = DAG.getCALLSEQ_START(Chain,
DAG.getConstant(NumBytes, MVT::i32));
std::vector<MVT::ValueType> NodeTys;
NodeTys.push_back(MVT::Other); // Returns a chain
NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
// If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
// direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
// node so that legalize doesn't hack it.
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), Callee.getValueType());
// If this is a direct call, pass the chain and the callee.
assert (Callee.Val);
std::vector<SDOperand> Ops;
Ops.push_back(Chain);
Ops.push_back(Callee);
unsigned CallOpc = ARMISD::CALL;
Chain = DAG.getNode(CallOpc, NodeTys, Ops);
assert(Op.Val->getValueType(0) == MVT::Other);
Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
DAG.getConstant(NumBytes, MVT::i32));
return Chain;
}
static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {

View File

@ -41,6 +41,10 @@ def SDT_ARMCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeq, [SDNPHasChain]>;
def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeq, [SDNPHasChain]>;
def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
def ADJCALLSTACKUP : InstARM<(ops i32imm:$amt),
"!ADJCALLSTACKUP $amt",
[(callseq_end imm:$amt)]>;
@ -51,6 +55,8 @@ def ADJCALLSTACKDOWN : InstARM<(ops i32imm:$amt),
def bxr: InstARM<(ops IntRegs:$dst), "bx $dst", [(brind IntRegs:$dst)]>;
def bl: InstARM<(ops i32imm:$func, variable_ops), "bl $func", [(ARMcall tglobaladdr:$func)]>;
def ldr : InstARM<(ops IntRegs:$dst, memri:$addr),
"ldr $dst, [$addr]",
[(set IntRegs:$dst, (load iaddr:$addr))]>;