+ case MVT::f32:
+ if (I->use_empty()) { // Argument is dead.
+ if (CurArgReg < ArgRegEnd) ++CurArgReg;
+ ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT));
+ } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
+ // FP value is passed in an integer register.
+ unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
+ MF.addLiveIn(*CurArgReg++, VReg);
+ SDOperand Arg = DAG.getCopyFromReg(Root, VReg, MVT::i32);
+
+ // We use the stack space that is already reserved for this reg.
+ int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
+ SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
+
+ SDOperand SV = DAG.getSrcValue(0);
+ SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Root,
+ Arg, FIPtr, SV);
+ ArgValues.push_back(DAG.getLoad(MVT::f32, Store, FIPtr, SV));
+ }
+ ArgOffset += 4;
+ break;
+
+ case MVT::i64:
+ case MVT::f64:
+ if (I->use_empty()) { // Argument is dead.
+ if (CurArgReg < ArgRegEnd) ++CurArgReg;
+ if (CurArgReg < ArgRegEnd) ++CurArgReg;
+ ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT));
+ } else if (CurArgReg == ArgRegEnd && ObjectVT == MVT::f64 &&
+ ((CurArgReg-ArgRegs) & 1) == 0) {
+ // If this is a double argument and the whole thing lives on the stack,
+ // and the argument is aligned, load the double straight from the stack.
+ // We can't do a load in cases like void foo([6ints], int,double),
+ // because the double wouldn't be aligned!
+ int FrameIdx = MF.getFrameInfo()->CreateFixedObject(8, ArgOffset);
+ SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
+ ArgValues.push_back(DAG.getLoad(MVT::f64, Root, FIPtr,
+ DAG.getSrcValue(0)));
+ } else {
+ SDOperand HiVal;
+ if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
+ unsigned VRegHi = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
+ MF.addLiveIn(*CurArgReg++, VRegHi);
+ HiVal = DAG.getCopyFromReg(Root, VRegHi, MVT::i32);
+ } else {
+ int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
+ SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
+ HiVal = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0));
+ }
+
+ SDOperand LoVal;
+ if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR
+ unsigned VRegLo = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
+ MF.addLiveIn(*CurArgReg++, VRegLo);
+ LoVal = DAG.getCopyFromReg(Root, VRegLo, MVT::i32);
+ } else {
+ int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset+4);
+ SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
+ LoVal = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0));
+ }
+
+ // Compose the two halves together into an i64 unit.
+ SDOperand WholeValue =
+ DAG.getNode(ISD::BUILD_PAIR, MVT::i64, LoVal, HiVal);
+
+ if (ObjectVT == MVT::i64) {
+ // If we are emitting an i64, this is what we want.
+ ArgValues.push_back(WholeValue);
+ } else {
+ assert(ObjectVT == MVT::f64);
+ // Otherwise, emit a store to the stack and reload into FPR.
+ int FrameIdx = MF.getFrameInfo()->CreateStackObject(8, 8);
+ SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
+ SDOperand SV = DAG.getSrcValue(0);
+ SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Root,
+ WholeValue, FIPtr, SV);
+ ArgValues.push_back(DAG.getLoad(MVT::f64, Store, FIPtr, SV));
+ }
+ }
+ ArgOffset += 8;