@@ -208,7 +208,13 @@ SDOperand IA64DAGToDAGISel::SelectCALL(SDOperand Op) {
208
208
CallOpcode = IA64::BRCALL_INDIRECT;
209
209
}
210
210
211
+ // see section 8.5.8 of "Itanium Software Conventions and
212
+ // Runtime Architecture Guide to see some examples of what's going
213
+ // on here. (in short: int args get mapped 1:1 'slot-wise' to out0->out7,
214
+ // while FP args get mapped to F8->F15 as needed)
215
+
211
216
// TODO: support in-memory arguments
217
+
212
218
unsigned used_FPArgs=0 ; // how many FP args have been used so far?
213
219
214
220
unsigned intArgs[] = {IA64::out0, IA64::out1, IA64::out2, IA64::out3,
@@ -236,6 +242,20 @@ SDOperand IA64DAGToDAGISel::SelectCALL(SDOperand Op) {
236
242
Chain = CurDAG->getCopyToReg (Chain, DestReg, Val, InFlag);
237
243
InFlag = Chain.getValue (1 );
238
244
CallOperands.push_back (CurDAG->getRegister (DestReg, RegTy));
245
+ // some functions (e.g. printf) want floating point arguments
246
+ // *also* passed as in-memory representations in integer registers
247
+ // this is FORTRAN legacy junk which we don't _always_ need
248
+ // to do, but to be on the safe side, we do.
249
+ if (MVT::isFloatingPoint (N->getOperand (i).getValueType ())) {
250
+ assert ((i-2 ) < 8 && " FP args alone would fit, but no int regs left" );
251
+ DestReg = intArgs[i-2 ]; // this FP arg goes in an int reg
252
+ // GETFD takes an FP reg and writes a GP reg
253
+ Chain = CurDAG->getTargetNode (IA64::GETFD, MVT::i64 , Val, InFlag);
254
+ // FIXME: this next line is a bit unfortunate
255
+ Chain = CurDAG->getCopyToReg (Chain, DestReg, Chain, InFlag);
256
+ InFlag = Chain.getValue (1 );
257
+ CallOperands.push_back (CurDAG->getRegister (DestReg, MVT::i64 ));
258
+ }
239
259
}
240
260
}
241
261
0 commit comments