PPC64 passes arguments of integral type in i64 registers, not i32. Reflect this
authorBill Wendling <isanbard@gmail.com>
Fri, 7 Mar 2008 20:49:02 +0000 (20:49 +0000)
committerBill Wendling <isanbard@gmail.com>
Fri, 7 Mar 2008 20:49:02 +0000 (20:49 +0000)
by promoting smaller integral values (i32 at this point) to i64, then truncating
to get the wanted size.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48030 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCISelLowering.cpp

index dffbf7cb2774ca0a8dd4cef59f607690e49d247f..7773fc9ee50b3a45be06beef20ea239f5a4cc4c8 100644 (file)
@@ -1296,13 +1296,14 @@ static const unsigned *GetFPR(const PPCSubtarget &Subtarget) {
   return FPR;
 }
 
-SDOperand PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, 
-                                       SelectionDAG &DAG,
-                                       int &VarArgsFrameIndex,
-                                       int &VarArgsStackOffset,
-                                       unsigned &VarArgsNumGPR,
-                                       unsigned &VarArgsNumFPR,
-                                       const PPCSubtarget &Subtarget) {
+SDOperand
+PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, 
+                                         SelectionDAG &DAG,
+                                         int &VarArgsFrameIndex,
+                                         int &VarArgsStackOffset,
+                                         unsigned &VarArgsNumGPR,
+                                         unsigned &VarArgsNumFPR,
+                                         const PPCSubtarget &Subtarget) {
   // TODO: add description of PPC stack frame format, or at least some docs.
   //
   MachineFunction &MF = DAG.getMachineFunction();
@@ -1408,29 +1409,46 @@ SDOperand PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op,
     switch (ObjectVT) {
     default: assert(0 && "Unhandled argument type!");
     case MVT::i32:
-      // Double word align in ELF
-      if (Expand && isELF32_ABI) GPR_idx += (GPR_idx % 2);
-      if (GPR_idx != Num_GPR_Regs) {
-        unsigned VReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
-        RegInfo.addLiveIn(GPR[GPR_idx], VReg);
-        ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32);
-        ++GPR_idx;
-      } else {
-        needsLoad = true;
-        ArgSize = PtrByteSize;
+      if (!isPPC64) {
+        // Double word align in ELF
+        if (Expand && isELF32_ABI) GPR_idx += (GPR_idx % 2);
+
+        if (GPR_idx != Num_GPR_Regs) {
+          unsigned VReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
+          RegInfo.addLiveIn(GPR[GPR_idx], VReg);
+          ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32);
+          ++GPR_idx;
+        } else {
+          needsLoad = true;
+          ArgSize = PtrByteSize;
+        }
+        // Stack align in ELF
+        if (needsLoad && Expand && isELF32_ABI) 
+          ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize;
+        // All int arguments reserve stack space in Macho ABI.
+        if (isMachoABI || needsLoad) ArgOffset += PtrByteSize;
+        break;
       }
-      // Stack align in ELF
-      if (needsLoad && Expand && isELF32_ABI) 
-        ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize;
-      // All int arguments reserve stack space in Macho ABI.
-      if (isMachoABI || needsLoad) ArgOffset += PtrByteSize;
-      break;
-      
+      // FALLTHROUGH
     case MVT::i64:  // PPC64
       if (GPR_idx != Num_GPR_Regs) {
         unsigned VReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
         RegInfo.addLiveIn(GPR[GPR_idx], VReg);
         ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64);
+
+        if (ObjectVT == MVT::i32) {
+          // PPC64 passes i8, i16, and i32 values in i64 registers. Promote
+          // value to MVT::i64 and then truncate to the correct register size.
+          if (Flags & ISD::ParamFlags::SExt)
+            ArgVal = DAG.getNode(ISD::AssertSext, MVT::i64, ArgVal,
+                                 DAG.getValueType(ObjectVT));
+          else if (Flags & ISD::ParamFlags::ZExt)
+            ArgVal = DAG.getNode(ISD::AssertZext, MVT::i64, ArgVal,
+                                 DAG.getValueType(ObjectVT));
+
+          ArgVal = DAG.getNode(ISD::TRUNCATE, MVT::i32, ArgVal);
+        }
+
         ++GPR_idx;
       } else {
         needsLoad = true;
@@ -1620,7 +1638,7 @@ static SDNode *isBLACompatibleAddress(SDOperand Op, SelectionDAG &DAG) {
 /// does not fit in registers.
 static SDOperand 
 CreateCopyOfByValArgument(SDOperand Src, SDOperand Dst, SDOperand Chain,
-                           unsigned Flags, SelectionDAG &DAG, unsigned Size) {
+                          unsigned Flags, SelectionDAG &DAG, unsigned Size) {
   unsigned Align = 1 <<
     ((Flags & ISD::ParamFlags::ByValAlign) >> ISD::ParamFlags::ByValAlignOffs);
   SDOperand AlignNode    = DAG.getConstant(Align, MVT::i32);
@@ -1742,7 +1760,6 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG,
     // On PPC64, promote integers to 64-bit values.
     if (isPPC64 && Arg.getValueType() == MVT::i32) {
       unsigned ExtOp = (Flags & 1) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
-
       Arg = DAG.getNode(ExtOp, MVT::i64, Arg);
     }