aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuraid Madina <duraid@octopus.com.au>2005-11-01 05:46:16 +0000
committerDuraid Madina <duraid@octopus.com.au>2005-11-01 05:46:16 +0000
commit9b61d3c1e2fdbda0004f2e27ca4fa52184c2c43f (patch)
tree62ffb9ef100e38ff43ef0aeddeb0686c348a32d3
parentb81b61330e4523c6b194c2b85581cf8a230f6e84 (diff)
downloadllvm-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.cpp20
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));
+ }
}
}