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);
}
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);
}
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);
}
}
}
- 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)) {
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);
}
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();
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;
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
}
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();
// 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;
Cmp.getValue(1));
}
-
[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.
[(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))]>;
}
//-------------------