[llvm] r198480 - [SparcV9]: Implement RETURNADDR and FRAMEADDR lowering in SPARC64.

Venkatraman Govindaraju venkatra at cs.wisc.edu
Fri Jan 3 23:17:21 PST 2014


Author: venkatra
Date: Sat Jan  4 01:17:21 2014
New Revision: 198480

URL: http://llvm.org/viewvc/llvm-project?rev=198480&view=rev
Log:
[SparcV9]: Implement RETURNADDR and FRAMEADDR lowering in SPARC64. 

Fixes PR18356.

Modified:
    llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp
    llvm/trunk/test/CodeGen/SPARC/2011-01-11-FrameAddr.ll

Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp?rev=198480&r1=198479&r2=198480&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp Sat Jan  4 01:17:21 2014
@@ -2415,39 +2415,57 @@ static SDValue getFLUSHW(SDValue Op, Sel
   return Chain;
 }
 
-static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
+static SDValue getFRAMEADDR(uint64_t depth, SDValue Op, SelectionDAG &DAG,
+                            const SparcSubtarget *Subtarget) {
   MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
   MFI->setFrameAddressIsTaken(true);
 
   EVT VT = Op.getValueType();
   SDLoc dl(Op);
   unsigned FrameReg = SP::I6;
-
-  uint64_t depth = Op.getConstantOperandVal(0);
+  unsigned stackBias = Subtarget->getStackPointerBias();
 
   SDValue FrameAddr;
-  if (depth == 0)
+
+  if (depth == 0) {
     FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
-  else {
-    // flush first to make sure the windowed registers' values are in stack
-    SDValue Chain = getFLUSHW(Op, DAG);
-    FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT);
-
-    for (uint64_t i = 0; i != depth; ++i) {
-      SDValue Ptr = DAG.getNode(ISD::ADD,
-                                dl, MVT::i32,
-                                FrameAddr, DAG.getIntPtrConstant(56));
-      FrameAddr = DAG.getLoad(MVT::i32, dl,
-                              Chain,
-                              Ptr,
-                              MachinePointerInfo(), false, false, false, 0);
-    }
+    if (Subtarget->is64Bit())
+      FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
+                              DAG.getIntPtrConstant(stackBias));
+    return FrameAddr;
   }
+
+  // flush first to make sure the windowed registers' values are in stack
+  SDValue Chain = getFLUSHW(Op, DAG);
+  FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT);
+
+  unsigned Offset = (Subtarget->is64Bit()) ? (stackBias + 112) : 56;
+
+  while (depth--) {
+    SDValue Ptr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
+                              DAG.getIntPtrConstant(Offset));
+    FrameAddr = DAG.getLoad(VT, dl, Chain, Ptr, MachinePointerInfo(),
+                            false, false, false, 0);
+  }
+  if (Subtarget->is64Bit())
+    FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
+                            DAG.getIntPtrConstant(stackBias));
   return FrameAddr;
 }
 
+
+static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG,
+                              const SparcSubtarget *Subtarget) {
+
+  uint64_t depth = Op.getConstantOperandVal(0);
+
+  return getFRAMEADDR(depth, Op, DAG, Subtarget);
+
+}
+
 static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG,
-                               const SparcTargetLowering &TLI) {
+                               const SparcTargetLowering &TLI,
+                               const SparcSubtarget *Subtarget) {
   MachineFunction &MF = DAG.getMachineFunction();
   MachineFrameInfo *MFI = MF.getFrameInfo();
   MFI->setReturnAddressIsTaken(true);
@@ -2461,25 +2479,20 @@ static SDValue LowerRETURNADDR(SDValue O
     unsigned RetReg = MF.addLiveIn(SP::I7,
                                    TLI.getRegClassFor(TLI.getPointerTy()));
     RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT);
-  } else {
-    // Need frame address to find return address of the caller.
-    MFI->setFrameAddressIsTaken(true);
-
-    // flush first to make sure the windowed registers' values are in stack
-    SDValue Chain = getFLUSHW(Op, DAG);
-    RetAddr = DAG.getCopyFromReg(Chain, dl, SP::I6, VT);
-
-    for (uint64_t i = 0; i != depth; ++i) {
-      SDValue Ptr = DAG.getNode(ISD::ADD,
-                                dl, MVT::i32,
-                                RetAddr,
-                                DAG.getIntPtrConstant((i == depth-1)?60:56));
-      RetAddr = DAG.getLoad(MVT::i32, dl,
-                            Chain,
-                            Ptr,
-                            MachinePointerInfo(), false, false, false, 0);
-    }
+    return RetAddr;
   }
+
+  // Need frame address to find return address of the caller.
+  SDValue FrameAddr = getFRAMEADDR(depth - 1, Op, DAG, Subtarget);
+
+  unsigned Offset = (Subtarget->is64Bit()) ? 120 : 60;
+  SDValue Ptr = DAG.getNode(ISD::ADD,
+                            dl, VT,
+                            FrameAddr,
+                            DAG.getIntPtrConstant(Offset));
+  RetAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), Ptr,
+                        MachinePointerInfo(), false, false, false, 0);
+
   return RetAddr;
 }
 
@@ -2763,8 +2776,10 @@ LowerOperation(SDValue Op, SelectionDAG
   switch (Op.getOpcode()) {
   default: llvm_unreachable("Should not custom lower this!");
 
-  case ISD::RETURNADDR:         return LowerRETURNADDR(Op, DAG, *this);
-  case ISD::FRAMEADDR:          return LowerFRAMEADDR(Op, DAG);
+  case ISD::RETURNADDR:         return LowerRETURNADDR(Op, DAG, *this,
+                                                       Subtarget);
+  case ISD::FRAMEADDR:          return LowerFRAMEADDR(Op, DAG,
+                                                      Subtarget);
   case ISD::GlobalTLSAddress:   return LowerGlobalTLSAddress(Op, DAG);
   case ISD::GlobalAddress:      return LowerGlobalAddress(Op, DAG);
   case ISD::BlockAddress:       return LowerBlockAddress(Op, DAG);

Modified: llvm/trunk/test/CodeGen/SPARC/2011-01-11-FrameAddr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SPARC/2011-01-11-FrameAddr.ll?rev=198480&r1=198479&r2=198480&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SPARC/2011-01-11-FrameAddr.ll (original)
+++ llvm/trunk/test/CodeGen/SPARC/2011-01-11-FrameAddr.ll Sat Jan  4 01:17:21 2014
@@ -2,6 +2,7 @@
 ;RUN: llc -march=sparc -mattr=v9 < %s | FileCheck %s -check-prefix=V9
 ;RUN: llc -march=sparc -regalloc=basic < %s | FileCheck %s -check-prefix=V8
 ;RUN: llc -march=sparc -regalloc=basic -mattr=v9 < %s | FileCheck %s -check-prefix=V9
+;RUN: llc -march=sparcv9  < %s | FileCheck %s -check-prefix=SPARC64
 
 
 define i8* @frameaddr() nounwind readnone {
@@ -15,6 +16,13 @@ entry:
 ;V9: save %sp, -96, %sp
 ;V9: jmp %i7+8
 ;V9: restore %g0, %fp, %o0
+
+;SPARC64-LABEL: frameaddr
+;SPARC64:       save %sp, -128, %sp
+;SPARC64:       add  %fp, 2047, %i0
+;SPARC64:       jmp %i7+8
+;SPARC64:       restore %g0, %g0, %g0
+
   %0 = tail call i8* @llvm.frameaddress(i32 0)
   ret i8* %0
 }
@@ -32,6 +40,14 @@ entry:
 ;V9: ld [%fp+56], {{.+}}
 ;V9: ld [{{.+}}+56], {{.+}}
 ;V9: ld [{{.+}}+56], {{.+}}
+
+;SPARC64-LABEL: frameaddr2
+;SPARC64: flushw
+;SPARC64: ldx [%fp+2159],     %[[R0:[goli][0-7]]]
+;SPARC64: ldx [%[[R0]]+2159], %[[R1:[goli][0-7]]]
+;SPARC64: ldx [%[[R1]]+2159], %[[R2:[goli][0-7]]]
+;SPARC64: add %[[R2]], 2047, {{.+}}
+
   %0 = tail call i8* @llvm.frameaddress(i32 3)
   ret i8* %0
 }
@@ -48,6 +64,9 @@ entry:
 ;V9-LABEL: retaddr:
 ;V9: or %g0, %o7, {{.+}}
 
+;SPARC64-LABEL: retaddr
+;SPARC64:       or %g0, %o7, {{.+}}
+
   %0 = tail call i8* @llvm.returnaddress(i32 0)
   ret i8* %0
 }
@@ -66,17 +85,11 @@ entry:
 ;V9: ld [{{.+}}+56], {{.+}}
 ;V9: ld [{{.+}}+60], {{.+}}
 
-;V8LEAF-LABEL: retaddr2:
-;V8LEAF: ta 3
-;V8LEAF: ld [%fp+56], %[[R:[goli][0-7]]]
-;V8LEAF: ld [%[[R]]+56], %[[R1:[goli][0-7]]]
-;V8LEAF: ld [%[[R1]]+60], {{.+}}
-
-;V9LEAF-LABEL: retaddr2:
-;V9LEAF: flushw
-;V9LEAF: ld [%fp+56], %[[R:[goli][0-7]]]
-;V9LEAF: ld [%[[R]]+56], %[[R1:[goli][0-7]]]
-;V9LEAF: ld [%[[R1]]+60], {{.+}}
+;SPARC64-LABEL: retaddr2
+;SPARC64:       flushw
+;SPARC64: ldx [%fp+2159],     %[[R0:[goli][0-7]]]
+;SPARC64: ldx [%[[R0]]+2159], %[[R1:[goli][0-7]]]
+;SPARC64: ldx [%[[R1]]+2167], {{.+}}
 
   %0 = tail call i8* @llvm.returnaddress(i32 3)
   ret i8* %0





More information about the llvm-commits mailing list