mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-01 00:33:09 +00:00
Handle aggregate type arguments to direct and indirect calls.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69022 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
442b7bfc80
commit
85be408a32
@ -227,6 +227,11 @@ void PIC16AsmPrinter::EmitExternsAndGlobals (Module &M) {
|
||||
std::string Name = Mang->getValueName(I);
|
||||
if (Name.compare("abort") == 0)
|
||||
continue;
|
||||
|
||||
// If it is llvm intrinsic call then don't emit
|
||||
if (Name.find("llvm.") != std::string::npos)
|
||||
continue;
|
||||
|
||||
if (I->isDeclaration()) {
|
||||
O << "\textern " <<Name << "\n";
|
||||
O << "\textern " << Name << ".retval\n";
|
||||
@ -396,6 +401,11 @@ void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) {
|
||||
}
|
||||
O << CurrentFnName << ".args RES " << ArgSize << "\n";
|
||||
|
||||
// Emit temporary space
|
||||
int TempSize = PTLI->GetTmpSize();
|
||||
if (TempSize > 0 )
|
||||
O << CurrentFnName << ".tmp RES " << TempSize <<"\n";
|
||||
|
||||
// Emit the function variables.
|
||||
|
||||
// In PIC16 all the function arguments and local variables are global.
|
||||
@ -423,7 +433,4 @@ void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) {
|
||||
O << VarName << " RES " << Size << "\n";
|
||||
}
|
||||
|
||||
int TempSize = PTLI->GetTmpSize();
|
||||
if (TempSize > 0 )
|
||||
O << CurrentFnName << ".tmp RES " << TempSize <<"\n";
|
||||
}
|
||||
|
@ -326,10 +326,14 @@ SDValue PIC16TargetLowering::ExpandFrameIndex(SDNode *N, SelectionDAG &DAG) {
|
||||
DebugLoc dl = FR->getDebugLoc();
|
||||
int Index = FR->getIndex();
|
||||
|
||||
SDValue FI[2];
|
||||
FI[0] = DAG.getTargetFrameIndex(Index, MVT::i8);
|
||||
FI[1] = DAG.getTargetFrameIndex(Index + 1, MVT::i8);
|
||||
return DAG.getNode(ISD::BUILD_PAIR, dl, N->getValueType(0), FI[0], FI[1]);
|
||||
// Expand FrameIndex like GlobalAddress and ExternalSymbol
|
||||
// Also use Offset field for lo and hi parts. The default
|
||||
// offset is zero.
|
||||
SDValue Offset = DAG.getConstant(0, MVT::i8);
|
||||
SDValue FI = DAG.getTargetFrameIndex(Index, MVT::i8);
|
||||
SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, FI, Offset);
|
||||
SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, FI, Offset);
|
||||
return DAG.getNode(ISD::BUILD_PAIR, dl, N->getValueType(0), Lo, Hi);
|
||||
}
|
||||
|
||||
|
||||
@ -433,9 +437,9 @@ SDValue PIC16TargetLowering::ExpandExternalSymbol(SDNode *N, SelectionDAG &DAG)
|
||||
DebugLoc dl = ES->getDebugLoc();
|
||||
|
||||
SDValue TES = DAG.getTargetExternalSymbol(ES->getSymbol(), MVT::i8);
|
||||
|
||||
SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TES);
|
||||
SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TES);
|
||||
SDValue Offset = DAG.getConstant(0, MVT::i8);
|
||||
SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TES, Offset);
|
||||
SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TES, Offset);
|
||||
|
||||
return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i16, Lo, Hi);
|
||||
}
|
||||
@ -449,8 +453,9 @@ SDValue PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) {
|
||||
SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i8,
|
||||
G->getOffset());
|
||||
|
||||
SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TGA);
|
||||
SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TGA);
|
||||
SDValue Offset = DAG.getConstant(0, MVT::i8);
|
||||
SDValue Lo = DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, TGA, Offset);
|
||||
SDValue Hi = DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, TGA, Offset);
|
||||
|
||||
return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i16, Lo, Hi);
|
||||
}
|
||||
@ -587,14 +592,16 @@ void PIC16TargetLowering::LegalizeAddress(SDValue Ptr, SelectionDAG &DAG,
|
||||
}
|
||||
}
|
||||
|
||||
if (Ptr.getOpcode() == ISD::BUILD_PAIR &&
|
||||
Ptr.getOperand(0).getOpcode() == ISD::TargetFrameIndex) {
|
||||
|
||||
int FrameOffset;
|
||||
LegalizeFrameIndex(Ptr.getOperand(0), DAG, Lo, FrameOffset);
|
||||
Hi = DAG.getConstant(1, MVT::i8);
|
||||
Offset += FrameOffset;
|
||||
return;
|
||||
// Expansion of FrameIndex has Lo/Hi parts
|
||||
if (isDirectAddress(Ptr)) {
|
||||
SDValue TFI = Ptr.getOperand(0).getOperand(0);
|
||||
if (TFI.getOpcode() == ISD::TargetFrameIndex) {
|
||||
int FrameOffset;
|
||||
LegalizeFrameIndex(TFI, DAG, Lo, FrameOffset);
|
||||
Hi = DAG.getConstant(1, MVT::i8);
|
||||
Offset += FrameOffset;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDirectAddress(Ptr) && !isRomAddress(Ptr)) {
|
||||
@ -884,6 +891,12 @@ LowerIndirectCallArguments(SDValue Op, SDValue Chain, SDValue InFlag,
|
||||
for (unsigned i = 0, ArgOffset = RetVals; i < NumOps; i++) {
|
||||
// Get the arguments
|
||||
Arg = TheCall->getArg(i);
|
||||
// If argument is FrameIndex then map it with temporary
|
||||
if (Arg.getOpcode() == PIC16ISD::Lo || Arg.getOpcode() == PIC16ISD::Hi) {
|
||||
if (Arg.getOperand(0).getOpcode() == ISD::TargetFrameIndex) {
|
||||
Arg = LegalizeFrameArgument(Arg, dl, DAG);
|
||||
}
|
||||
}
|
||||
Ops.clear();
|
||||
Ops.push_back(Chain);
|
||||
Ops.push_back(Arg);
|
||||
@ -900,9 +913,39 @@ LowerIndirectCallArguments(SDValue Op, SDValue Chain, SDValue InFlag,
|
||||
}
|
||||
return Chain;
|
||||
}
|
||||
|
||||
|
||||
SDValue PIC16TargetLowering::
|
||||
LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue FrameAddress,
|
||||
LegalizeFrameArgument(SDValue Arg, DebugLoc dl, SelectionDAG &DAG) {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
const Function *Func = MF.getFunction();
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
const std::string Name = Func->getName();
|
||||
|
||||
// Caller creates the stack storage to pass the aggregate type
|
||||
// as argument. So it should be relative to tmp variable.
|
||||
SDValue FI = Arg.getOperand(0);
|
||||
char *tmpName = new char [strlen(Name.c_str()) + 8];
|
||||
sprintf(tmpName, "%s.tmp", Name.c_str());
|
||||
SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
|
||||
FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(FI);
|
||||
|
||||
unsigned FIndex = FR->getIndex();
|
||||
// Reserve space in tmp variable for the aggregate type
|
||||
int FrameOffset = GetTmpOffsetForFI(FIndex, MFI->getObjectSize(FIndex));
|
||||
|
||||
if (Arg.getOpcode() == PIC16ISD::Lo) {
|
||||
// Lo part of frame index
|
||||
SDValue FrameConst = DAG.getConstant(FrameOffset, MVT::i8);
|
||||
return DAG.getNode(PIC16ISD::Lo, dl, MVT::i8, ES, FrameConst);
|
||||
} else {
|
||||
// Hi part of frame index
|
||||
SDValue FrameConst = DAG.getConstant(FrameOffset + 1, MVT::i8);
|
||||
return DAG.getNode(PIC16ISD::Hi, dl, MVT::i8, ES, FrameConst);
|
||||
}
|
||||
}
|
||||
|
||||
SDValue PIC16TargetLowering::
|
||||
LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue ArgLabel,
|
||||
SDValue InFlag, SelectionDAG &DAG) {
|
||||
CallSDNode *TheCall = dyn_cast<CallSDNode>(Op);
|
||||
unsigned NumOps = TheCall->getNumArgs();
|
||||
@ -924,7 +967,7 @@ LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue FrameAddress,
|
||||
SDValue PtrLo, PtrHi;
|
||||
unsigned AddressOffset;
|
||||
int StoreOffset = 0;
|
||||
LegalizeAddress(FrameAddress, DAG, PtrLo, PtrHi, AddressOffset, dl);
|
||||
LegalizeAddress(ArgLabel, DAG, PtrLo, PtrHi, AddressOffset, dl);
|
||||
SDValue StoreRet;
|
||||
|
||||
std::vector<SDValue> Ops;
|
||||
@ -932,7 +975,12 @@ LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue FrameAddress,
|
||||
for (unsigned i=ArgCount, Offset = 0; i<NumOps; i++) {
|
||||
// Get the argument
|
||||
Arg = TheCall->getArg(i);
|
||||
|
||||
// If argument is FrameIndex then map it with temporary
|
||||
if (Arg.getOpcode() == PIC16ISD::Lo || Arg.getOpcode() == PIC16ISD::Hi) {
|
||||
if (Arg.getOperand(0).getOpcode() == ISD::TargetFrameIndex) {
|
||||
Arg = LegalizeFrameArgument(Arg, dl, DAG);
|
||||
}
|
||||
}
|
||||
StoreOffset = (Offset + AddressOffset);
|
||||
|
||||
// Store the argument on frame
|
||||
@ -991,7 +1039,7 @@ LowerIndirectCallReturn (SDValue Op, SDValue Chain, SDValue InFlag,
|
||||
}
|
||||
|
||||
SDValue PIC16TargetLowering::
|
||||
LowerDirectCallReturn(SDValue Op, SDValue Chain, SDValue FrameAddress,
|
||||
LowerDirectCallReturn(SDValue Op, SDValue Chain, SDValue RetLabel,
|
||||
SDValue InFlag, SelectionDAG &DAG) {
|
||||
CallSDNode *TheCall = dyn_cast<CallSDNode>(Op);
|
||||
DebugLoc dl = TheCall->getDebugLoc();
|
||||
@ -1010,7 +1058,7 @@ LowerDirectCallReturn(SDValue Op, SDValue Chain, SDValue FrameAddress,
|
||||
// Legalize the address before use
|
||||
SDValue LdLo, LdHi;
|
||||
unsigned LdOffset;
|
||||
LegalizeAddress(FrameAddress, DAG, LdLo, LdHi, LdOffset, dl);
|
||||
LegalizeAddress(RetLabel, DAG, LdLo, LdHi, LdOffset, dl);
|
||||
|
||||
SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag);
|
||||
SDValue LoadRet;
|
||||
@ -1698,4 +1746,3 @@ SDValue PIC16TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) {
|
||||
Cmp.getValue(1));
|
||||
}
|
||||
|
||||
|
||||
|
@ -168,6 +168,8 @@ namespace llvm {
|
||||
void LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG, SDValue &ES,
|
||||
int &Offset);
|
||||
|
||||
SDValue LegalizeFrameArgument(SDValue Arg, DebugLoc dl, SelectionDAG &DAG);
|
||||
|
||||
// CALL node should have all legal operands only. Legalize all non-legal
|
||||
// operands of CALL node and then return the new call will all operands
|
||||
// legal.
|
||||
|
@ -72,10 +72,10 @@ def PIC16callseq_end : SDNode<"ISD::CALLSEQ_END", SDTI8VoidOp,
|
||||
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
|
||||
|
||||
// Low 8-bits of GlobalAddress.
|
||||
def PIC16Lo : SDNode<"PIC16ISD::Lo", SDTI8UnaryOp>;
|
||||
def PIC16Lo : SDNode<"PIC16ISD::Lo", SDTI8BinOp>;
|
||||
|
||||
// High 8-bits of GlobalAddress.
|
||||
def PIC16Hi : SDNode<"PIC16ISD::Hi", SDTI8UnaryOp>;
|
||||
def PIC16Hi : SDNode<"PIC16ISD::Hi", SDTI8BinOp>;
|
||||
|
||||
// The MTHI and MTLO nodes are used only to match them in the incoming
|
||||
// DAG for replacement by corresponding set_fsrhi, set_fsrlo insntructions.
|
||||
@ -187,14 +187,24 @@ def movlw : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
|
||||
[(set GPR:$dst, (i8 imm:$src))]>;
|
||||
|
||||
// Move a Lo(TGA) to W.
|
||||
def movlw_lo : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
|
||||
"movlw LOW(${src})",
|
||||
[(set GPR:$dst, (PIC16Lo tglobaladdr:$src))]>;
|
||||
def movlw_lo_1 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2),
|
||||
"movlw LOW(${src}) + ${src2}",
|
||||
[(set GPR:$dst, (PIC16Lo tglobaladdr:$src, imm:$src2 ))]>;
|
||||
|
||||
// Move a Lo(TES) to W.
|
||||
def movlw_lo_2 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2),
|
||||
"movlw LOW(${src}) + ${src2}",
|
||||
[(set GPR:$dst, (PIC16Lo texternalsym:$src, imm:$src2 ))]>;
|
||||
|
||||
// Move a Hi(TGA) to W.
|
||||
def movlw_hi : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src),
|
||||
"movlw HIGH(${src})",
|
||||
[(set GPR:$dst, (PIC16Hi tglobaladdr:$src))]>;
|
||||
def movlw_hi_1 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2),
|
||||
"movlw HIGH(${src}) + ${src2}",
|
||||
[(set GPR:$dst, (PIC16Hi tglobaladdr:$src, imm:$src2))]>;
|
||||
|
||||
// Move a Hi(TES) to W.
|
||||
def movlw_hi_2 : BitFormat<12, (outs GPR:$dst), (ins i8imm:$src, i8imm:$src2),
|
||||
"movlw HIGH(${src}) + ${src2}",
|
||||
[(set GPR:$dst, (PIC16Hi texternalsym:$src, imm:$src2))]>;
|
||||
}
|
||||
|
||||
//-------------------
|
||||
|
Loading…
Reference in New Issue
Block a user