mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +00:00 
			
		
		
		
	switch x86-64 return value lowering over to using same mechanism as argument
lowering uses. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34657 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		@@ -429,79 +429,103 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
 | 
				
			|||||||
//               Return Value Calling Convention Implementation
 | 
					//               Return Value Calling Convention Implementation
 | 
				
			||||||
//===----------------------------------------------------------------------===//
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// X86_RetCC_Assign - Implement the X86 return value conventions.  This returns
 | 
				
			||||||
 | 
					/// true if the value wasn't handled by this CC.
 | 
				
			||||||
 | 
					static bool X86_RetCC_Assign(unsigned ValNo, MVT::ValueType ValVT, 
 | 
				
			||||||
 | 
					                             unsigned ArgFlags, CCState &State) {
 | 
				
			||||||
 | 
					  MVT::ValueType LocVT = ValVT;
 | 
				
			||||||
 | 
					  CCValAssign::LocInfo LocInfo = CCValAssign::Full;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
/// GetRetValueLocs - If we are returning a set of values with the specified
 | 
					  // If this is a 32-bit value, assign to a 32-bit register if any are
 | 
				
			||||||
/// value types, determine the set of registers each one will land in.  This
 | 
					  // available.
 | 
				
			||||||
/// sets one element of the ResultRegs array for each element in the VTs array.
 | 
					  if (LocVT == MVT::i8) {
 | 
				
			||||||
static void GetRetValueLocs(const MVT::ValueType *VTs, unsigned NumVTs,
 | 
					    static const unsigned GPR8ArgRegs[] = { X86::AL, X86::DL };
 | 
				
			||||||
                            unsigned *ResultRegs,
 | 
					    if (unsigned Reg = State.AllocateReg(GPR8ArgRegs, 2)) {
 | 
				
			||||||
                            const X86Subtarget *Subtarget,
 | 
					      State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
 | 
				
			||||||
                            unsigned CC) {
 | 
					      return false;
 | 
				
			||||||
  if (NumVTs == 0) return;
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  if (NumVTs == 2) {
 | 
					 | 
				
			||||||
    ResultRegs[0] = VTs[0] == MVT::i64 ? X86::RAX : X86::EAX;
 | 
					 | 
				
			||||||
    ResultRegs[1] = VTs[1] == MVT::i64 ? X86::RDX : X86::EDX;
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  
 | 
					  }
 | 
				
			||||||
  // Otherwise, NumVTs is 1.
 | 
					  if (LocVT == MVT::i16) {
 | 
				
			||||||
  MVT::ValueType ArgVT = VTs[0];
 | 
					    static const unsigned GPR16ArgRegs[] = { X86::AX, X86::DX };
 | 
				
			||||||
  
 | 
					    if (unsigned Reg = State.AllocateReg(GPR16ArgRegs, 2)) {
 | 
				
			||||||
 | 
					      State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (LocVT == MVT::i32) {
 | 
				
			||||||
 | 
					    static const unsigned GPR32ArgRegs[] = { X86::EAX, X86::EDX };
 | 
				
			||||||
 | 
					    if (unsigned Reg = State.AllocateReg(GPR32ArgRegs, 2)) {
 | 
				
			||||||
 | 
					      State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (LocVT == MVT::i64) {
 | 
				
			||||||
 | 
					    static const unsigned GPR64ArgRegs[] = { X86::RAX, X86::RDX };
 | 
				
			||||||
 | 
					    if (unsigned Reg = State.AllocateReg(GPR64ArgRegs, 2)) {
 | 
				
			||||||
 | 
					      State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (MVT::isVector(LocVT)) {
 | 
				
			||||||
 | 
					    if (unsigned Reg = State.AllocateReg(X86::XMM0)) {
 | 
				
			||||||
 | 
					      State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
 | 
				
			||||||
 | 
					      return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (LocVT == MVT::f32 || LocVT == MVT::f64) {
 | 
				
			||||||
    unsigned Reg;
 | 
					    unsigned Reg;
 | 
				
			||||||
  switch (ArgVT) {
 | 
					    if (State.getTarget().getSubtarget<X86Subtarget>().is64Bit())
 | 
				
			||||||
  case MVT::i8:  Reg = X86::AL; break;
 | 
					 | 
				
			||||||
  case MVT::i16: Reg = X86::AX; break;
 | 
					 | 
				
			||||||
  case MVT::i32: Reg = X86::EAX; break;
 | 
					 | 
				
			||||||
  case MVT::i64: Reg = X86::RAX; break;
 | 
					 | 
				
			||||||
  case MVT::f32:
 | 
					 | 
				
			||||||
  case MVT::f64:
 | 
					 | 
				
			||||||
    if (Subtarget->is64Bit())
 | 
					 | 
				
			||||||
      Reg = X86::XMM0;         // FP values in X86-64 go in XMM0.
 | 
					      Reg = X86::XMM0;         // FP values in X86-64 go in XMM0.
 | 
				
			||||||
    else if (CC == CallingConv::Fast && Subtarget->hasSSE2())
 | 
					    else if (State.getCallingConv() == CallingConv::Fast &&
 | 
				
			||||||
 | 
					             State.getTarget().getSubtarget<X86Subtarget>().hasSSE2())
 | 
				
			||||||
      Reg = X86::XMM0;         // FP values in X86-32 with fastcc go in XMM0.
 | 
					      Reg = X86::XMM0;         // FP values in X86-32 with fastcc go in XMM0.
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      Reg = X86::ST0;          // FP values in X86-32 go in ST0.
 | 
					      Reg = X86::ST0;          // FP values in X86-32 go in ST0.
 | 
				
			||||||
    break;
 | 
					    
 | 
				
			||||||
  default:
 | 
					    if ((Reg = State.AllocateReg(Reg))) {
 | 
				
			||||||
    assert(MVT::isVector(ArgVT) && "Unknown return value type!");
 | 
					      State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
 | 
				
			||||||
    Reg = X86::XMM0; // Int/FP vector result -> XMM0.
 | 
					      return false;
 | 
				
			||||||
    break;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  ResultRegs[0] = Reg;
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
/// LowerRET - Lower an ISD::RET node.
 | 
					/// LowerRET - Lower an ISD::RET node.
 | 
				
			||||||
SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) {
 | 
					SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) {
 | 
				
			||||||
  assert((Op.getNumOperands() & 1) == 1 && "ISD::RET should have odd # args");
 | 
					  assert((Op.getNumOperands() & 1) == 1 && "ISD::RET should have odd # args");
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // Support up returning up to two registers.
 | 
					  SmallVector<CCValAssign, 16> RVLocs;
 | 
				
			||||||
  MVT::ValueType VTs[2];
 | 
					  unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
 | 
				
			||||||
  unsigned DestRegs[2];
 | 
					  CCState CCInfo(CC, getTargetMachine(), RVLocs);
 | 
				
			||||||
  unsigned NumRegs = Op.getNumOperands() / 2;
 | 
					 | 
				
			||||||
  assert(NumRegs <= 2 && "Can only return up to two regs!");
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  for (unsigned i = 0; i != NumRegs; ++i)
 | 
					 | 
				
			||||||
    VTs[i] = Op.getOperand(i*2+1).getValueType();
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // Determine which register each value should be copied into.
 | 
					  // Determine which register each value should be copied into.
 | 
				
			||||||
  GetRetValueLocs(VTs, NumRegs, DestRegs, Subtarget,
 | 
					  for (unsigned i = 0; i != Op.getNumOperands() / 2; ++i) {
 | 
				
			||||||
                  DAG.getMachineFunction().getFunction()->getCallingConv());
 | 
					    if (X86_RetCC_Assign(i, Op.getOperand(i*2+1).getValueType(),
 | 
				
			||||||
 | 
					                         cast<ConstantSDNode>(Op.getOperand(i*2+2))->getValue(),
 | 
				
			||||||
 | 
					                         CCInfo))
 | 
				
			||||||
 | 
					      assert(0 && "Unhandled result type!");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // If this is the first return lowered for this function, add the regs to the
 | 
					  // If this is the first return lowered for this function, add the regs to the
 | 
				
			||||||
  // liveout set for the function.
 | 
					  // liveout set for the function.
 | 
				
			||||||
  if (DAG.getMachineFunction().liveout_empty()) {
 | 
					  if (DAG.getMachineFunction().liveout_empty()) {
 | 
				
			||||||
    for (unsigned i = 0; i != NumRegs; ++i)
 | 
					    for (unsigned i = 0; i != RVLocs.size(); ++i)
 | 
				
			||||||
      DAG.getMachineFunction().addLiveOut(DestRegs[i]);
 | 
					      if (RVLocs[i].isRegLoc())
 | 
				
			||||||
 | 
					        DAG.getMachineFunction().addLiveOut(RVLocs[i].getLocReg());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  SDOperand Chain = Op.getOperand(0);
 | 
					  SDOperand Chain = Op.getOperand(0);
 | 
				
			||||||
  SDOperand Flag;
 | 
					  SDOperand Flag;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // Copy the result values into the output registers.
 | 
					  // Copy the result values into the output registers.
 | 
				
			||||||
  if (NumRegs != 1 || DestRegs[0] != X86::ST0) {
 | 
					  if (RVLocs.size() != 1 || !RVLocs[0].isRegLoc() ||
 | 
				
			||||||
    for (unsigned i = 0; i != NumRegs; ++i) {
 | 
					      RVLocs[0].getLocReg() != X86::ST0) {
 | 
				
			||||||
      Chain = DAG.getCopyToReg(Chain, DestRegs[i], Op.getOperand(i*2+1), Flag);
 | 
					    for (unsigned i = 0; i != RVLocs.size(); ++i) {
 | 
				
			||||||
 | 
					      CCValAssign &VA = RVLocs[i];
 | 
				
			||||||
 | 
					      assert(VA.isRegLoc() && "Can only return in registers!");
 | 
				
			||||||
 | 
					      Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1),
 | 
				
			||||||
 | 
					                               Flag);
 | 
				
			||||||
      Flag = Chain.getValue(1);
 | 
					      Flag = Chain.getValue(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
@@ -522,14 +546,14 @@ SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) {
 | 
				
			|||||||
        MemLoc = Value.getOperand(1);
 | 
					        MemLoc = Value.getOperand(1);
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        // Spill the value to memory and reload it into top of stack.
 | 
					        // Spill the value to memory and reload it into top of stack.
 | 
				
			||||||
        unsigned Size = MVT::getSizeInBits(VTs[0])/8;
 | 
					        unsigned Size = MVT::getSizeInBits(RVLocs[0].getValVT())/8;
 | 
				
			||||||
        MachineFunction &MF = DAG.getMachineFunction();
 | 
					        MachineFunction &MF = DAG.getMachineFunction();
 | 
				
			||||||
        int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
 | 
					        int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
 | 
				
			||||||
        MemLoc = DAG.getFrameIndex(SSFI, getPointerTy());
 | 
					        MemLoc = DAG.getFrameIndex(SSFI, getPointerTy());
 | 
				
			||||||
        Chain = DAG.getStore(Op.getOperand(0), Value, MemLoc, NULL, 0);
 | 
					        Chain = DAG.getStore(Op.getOperand(0), Value, MemLoc, NULL, 0);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      SDVTList Tys = DAG.getVTList(MVT::f64, MVT::Other);
 | 
					      SDVTList Tys = DAG.getVTList(MVT::f64, MVT::Other);
 | 
				
			||||||
      SDOperand Ops[] = { Chain, MemLoc, DAG.getValueType(VTs[0]) };
 | 
					      SDOperand Ops[] = {Chain, MemLoc, DAG.getValueType(RVLocs[0].getValVT())};
 | 
				
			||||||
      Value = DAG.getNode(X86ISD::FLD, Tys, Ops, 3);
 | 
					      Value = DAG.getNode(X86ISD::FLD, Tys, Ops, 3);
 | 
				
			||||||
      Chain = Value.getValue(1);
 | 
					      Chain = Value.getValue(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -558,23 +582,19 @@ LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode *TheCall,
 | 
				
			|||||||
                unsigned CallingConv, SelectionDAG &DAG) {
 | 
					                unsigned CallingConv, SelectionDAG &DAG) {
 | 
				
			||||||
  SmallVector<SDOperand, 8> ResultVals;
 | 
					  SmallVector<SDOperand, 8> ResultVals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // We support returning up to two registers.
 | 
					  SmallVector<CCValAssign, 16> RVLocs;
 | 
				
			||||||
  MVT::ValueType VTs[2];
 | 
					  CCState CCInfo(CallingConv, getTargetMachine(), RVLocs);
 | 
				
			||||||
  unsigned DestRegs[2];
 | 
					 | 
				
			||||||
  unsigned NumRegs = TheCall->getNumValues() - 1;
 | 
					 | 
				
			||||||
  assert(NumRegs <= 2 && "Can only return up to two regs!");
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  for (unsigned i = 0; i != NumRegs; ++i)
 | 
					  for (unsigned i = 0, e = TheCall->getNumValues() - 1; i != e; ++i) {
 | 
				
			||||||
    VTs[i] = TheCall->getValueType(i);
 | 
					    if (X86_RetCC_Assign(i, TheCall->getValueType(i), 0, CCInfo))
 | 
				
			||||||
  
 | 
					      assert(0 && "Unhandled result type!");
 | 
				
			||||||
  // Determine which register each value should be copied into.
 | 
					  }
 | 
				
			||||||
  GetRetValueLocs(VTs, NumRegs, DestRegs, Subtarget, CallingConv);
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // Copy all of the result registers out of their specified physreg.
 | 
					  // Copy all of the result registers out of their specified physreg.
 | 
				
			||||||
  if (NumRegs != 1 || DestRegs[0] != X86::ST0) {
 | 
					  if (RVLocs.size() != 1 || RVLocs[0].getLocReg() != X86::ST0) {
 | 
				
			||||||
    for (unsigned i = 0; i != NumRegs; ++i) {
 | 
					    for (unsigned i = 0; i != RVLocs.size(); ++i) {
 | 
				
			||||||
      Chain = DAG.getCopyFromReg(Chain, DestRegs[i], VTs[i],
 | 
					      Chain = DAG.getCopyFromReg(Chain, RVLocs[i].getLocReg(),
 | 
				
			||||||
                                 InFlag).getValue(1);
 | 
					                                 RVLocs[i].getValVT(), InFlag).getValue(1);
 | 
				
			||||||
      InFlag = Chain.getValue(2);
 | 
					      InFlag = Chain.getValue(2);
 | 
				
			||||||
      ResultVals.push_back(Chain.getValue(0));
 | 
					      ResultVals.push_back(Chain.getValue(0));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -599,14 +619,14 @@ LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode *TheCall,
 | 
				
			|||||||
      int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
 | 
					      int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
 | 
				
			||||||
      SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
 | 
					      SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
 | 
				
			||||||
      SDOperand Ops[] = {
 | 
					      SDOperand Ops[] = {
 | 
				
			||||||
        Chain, RetVal, StackSlot, DAG.getValueType(VTs[0]), InFlag
 | 
					        Chain, RetVal, StackSlot, DAG.getValueType(RVLocs[0].getValVT()), InFlag
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
      Chain = DAG.getNode(X86ISD::FST, MVT::Other, Ops, 5);
 | 
					      Chain = DAG.getNode(X86ISD::FST, MVT::Other, Ops, 5);
 | 
				
			||||||
      RetVal = DAG.getLoad(VTs[0], Chain, StackSlot, NULL, 0);
 | 
					      RetVal = DAG.getLoad(RVLocs[0].getValVT(), Chain, StackSlot, NULL, 0);
 | 
				
			||||||
      Chain = RetVal.getValue(1);
 | 
					      Chain = RetVal.getValue(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (VTs[0] == MVT::f32 && !X86ScalarSSE)
 | 
					    if (RVLocs[0].getValVT() == MVT::f32 && !X86ScalarSSE)
 | 
				
			||||||
      // FIXME: we would really like to remember that this FP_ROUND
 | 
					      // FIXME: we would really like to remember that this FP_ROUND
 | 
				
			||||||
      // operation is okay to eliminate if we allow excess FP precision.
 | 
					      // operation is okay to eliminate if we allow excess FP precision.
 | 
				
			||||||
      RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal);
 | 
					      RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user