diff options
author | Duraid Madina <duraid@octopus.com.au> | 2005-11-01 05:46:16 +0000 |
---|---|---|
committer | Duraid Madina <duraid@octopus.com.au> | 2005-11-01 05:46:16 +0000 |
commit | 9b61d3c1e2fdbda0004f2e27ca4fa52184c2c43f (patch) | |
tree | 62ffb9ef100e38ff43ef0aeddeb0686c348a32d3 | |
parent | b81b61330e4523c6b194c2b85581cf8a230f6e84 (diff) | |
download | llvm-9b61d3c1e2fdbda0004f2e27ca4fa52184c2c43f.zip llvm-9b61d3c1e2fdbda0004f2e27ca4fa52184c2c43f.tar.gz llvm-9b61d3c1e2fdbda0004f2e27ca4fa52184c2c43f.tar.bz2 |
FORTRAN!!! :( and other similarly unfortunate things mean that on ia64
one sometimes needs to pass FP args in both FP *and* integer registers.
llvm-svn: 24134
-rw-r--r-- | llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp b/llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp index a22c6b1..1a83d89 100644 --- a/llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp @@ -208,7 +208,13 @@ SDOperand IA64DAGToDAGISel::SelectCALL(SDOperand Op) { CallOpcode = IA64::BRCALL_INDIRECT; } + // see section 8.5.8 of "Itanium Software Conventions and + // Runtime Architecture Guide to see some examples of what's going + // on here. (in short: int args get mapped 1:1 'slot-wise' to out0->out7, + // while FP args get mapped to F8->F15 as needed) + // TODO: support in-memory arguments + unsigned used_FPArgs=0; // how many FP args have been used so far? unsigned intArgs[] = {IA64::out0, IA64::out1, IA64::out2, IA64::out3, @@ -236,6 +242,20 @@ SDOperand IA64DAGToDAGISel::SelectCALL(SDOperand Op) { Chain = CurDAG->getCopyToReg(Chain, DestReg, Val, InFlag); InFlag = Chain.getValue(1); CallOperands.push_back(CurDAG->getRegister(DestReg, RegTy)); + // some functions (e.g. printf) want floating point arguments + // *also* passed as in-memory representations in integer registers + // this is FORTRAN legacy junk which we don't _always_ need + // to do, but to be on the safe side, we do. + if(MVT::isFloatingPoint(N->getOperand(i).getValueType())) { + assert((i-2) < 8 && "FP args alone would fit, but no int regs left"); + DestReg = intArgs[i-2]; // this FP arg goes in an int reg + // GETFD takes an FP reg and writes a GP reg + Chain = CurDAG->getTargetNode(IA64::GETFD, MVT::i64, Val, InFlag); + // FIXME: this next line is a bit unfortunate + Chain = CurDAG->getCopyToReg(Chain, DestReg, Chain, InFlag); + InFlag = Chain.getValue(1); + CallOperands.push_back(CurDAG->getRegister(DestReg, MVT::i64)); + } } } |