Blame sysdeps/ia64/dl-trampoline.S

Packit 6c4009
/* PLT trampolines.  ia64 version.
Packit 6c4009
   Copyright (C) 2005-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <sysdep.h>
Packit 6c4009
#undef ret
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
   This code is used in dl-runtime.c to call the `_dl_fixup' function
Packit 6c4009
   and then redirect to the address it returns. `_dl_fixup()' takes two
Packit 6c4009
   arguments, however _dl_profile_fixup() takes five.
Packit 6c4009
Packit 6c4009
   The ABI specifies that we will never see more than 8 input
Packit 6c4009
   registers to a function call, thus it is safe to simply allocate
Packit 6c4009
   those, and simpler than playing stack games.  */
Packit 6c4009
Packit 6c4009
/* Used to save and restore 8 incoming fp registers */
Packit 6c4009
#define RESOLVE_FRAME_SIZE (16*8)
Packit 6c4009
Packit 6c4009
ENTRY(_dl_runtime_resolve)
Packit 6c4009
	{ .mmi
Packit 6c4009
	  .prologue
Packit 6c4009
	  .save ar.pfs, r40
Packit 6c4009
	  alloc loc0 = ar.pfs, 8, 6, 2, 0
Packit 6c4009
	  /* Use the 16 byte scratch area. r2 will start at f8 and
Packit 6c4009
	     r3 will start at f9.  */
Packit 6c4009
	  adds r2 = -(RESOLVE_FRAME_SIZE - 16), r12
Packit 6c4009
	  adds r3 = -(RESOLVE_FRAME_SIZE - 32), r12
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  .fframe RESOLVE_FRAME_SIZE
Packit 6c4009
	  adds r12 = -RESOLVE_FRAME_SIZE, r12
Packit 6c4009
	  .save rp, loc1
Packit 6c4009
	  mov loc1 = b0
Packit 6c4009
	  .body
Packit 6c4009
	  mov loc2 = r8		/* preserve struct value register */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  mov loc3 = r9		/* preserve language specific register */
Packit 6c4009
	  mov loc4 = r10	/* preserve language specific register */
Packit 6c4009
	  mov loc5 = r11	/* preserve language specific register */
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  stf.spill [r2] = f8, 32
Packit 6c4009
	  stf.spill [r3] = f9, 32
Packit 6c4009
	  mov out0 = r16
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  stf.spill [r2] = f10, 32
Packit 6c4009
	  stf.spill [r3] = f11, 32
Packit 6c4009
	  shl out1 = r15, 4
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  stf.spill [r2] = f12, 32
Packit 6c4009
	  stf.spill [r3] = f13, 32
Packit 6c4009
	  /* Relocation record is 24 byte. */
Packit 6c4009
	  shladd out1 = r15, 3, out1
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmb
Packit 6c4009
	  stf.spill [r2] = f14
Packit 6c4009
	  stf.spill [r3] = f15
Packit 6c4009
	  br.call.sptk.many b0 = _dl_fixup
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  /* Skip the 16byte scratch area.  */
Packit 6c4009
	  adds r2 = 16, r12
Packit 6c4009
	  adds r3 = 32, r12
Packit 6c4009
	  mov b6 = ret0
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ldf.fill f8 = [r2], 32
Packit 6c4009
	  ldf.fill f9 = [r3], 32
Packit 6c4009
	  mov b0 = loc1
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ldf.fill f10 = [r2], 32
Packit 6c4009
	  ldf.fill f11 = [r3], 32
Packit 6c4009
	  mov gp = ret1
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ldf.fill f12 = [r2], 32
Packit 6c4009
	  ldf.fill f13 = [r3], 32
Packit 6c4009
	  mov ar.pfs = loc0
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ldf.fill f14 = [r2], 32
Packit 6c4009
	  ldf.fill f15 = [r3], 32
Packit 6c4009
	  .restore sp		/* pop the unwind frame state */
Packit 6c4009
	  adds r12 = RESOLVE_FRAME_SIZE, r12
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  mov r9 = loc3		/* restore language specific register */
Packit 6c4009
	  mov r10 = loc4	/* restore language specific register */
Packit 6c4009
	  mov r11 = loc5	/* restore language specific register */
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  mov r8 = loc2		/* restore struct value register */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	/* An alloc is needed for the break system call to work.
Packit 6c4009
	   We don't care about the old value of the pfs register.  */
Packit 6c4009
	{ .mmb
Packit 6c4009
	  .prologue
Packit 6c4009
	  .body
Packit 6c4009
	  alloc r2 = ar.pfs, 0, 0, 8, 0
Packit 6c4009
	  br.sptk.many b6
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
END(_dl_runtime_resolve)
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* The fourth argument to _dl_profile_fixup and the third one to
Packit 6c4009
   _dl_call_pltexit are a pointer to La_ia64_regs:
Packit 6c4009
Packit 6c4009
   8byte r8
Packit 6c4009
   8byte r9
Packit 6c4009
   8byte r10
Packit 6c4009
   8byte r11
Packit 6c4009
   8byte in0
Packit 6c4009
   8byte in1
Packit 6c4009
   8byte in2
Packit 6c4009
   8byte in3
Packit 6c4009
   8byte in4
Packit 6c4009
   8byte in5
Packit 6c4009
   8byte in6
Packit 6c4009
   8byte in7
Packit 6c4009
   16byte f8
Packit 6c4009
   16byte f9
Packit 6c4009
   16byte f10
Packit 6c4009
   16byte f11
Packit 6c4009
   16byte f12
Packit 6c4009
   16byte f13
Packit 6c4009
   16byte f14
Packit 6c4009
   16byte f15
Packit 6c4009
   8byte ar.unat
Packit 6c4009
   8byte sp
Packit 6c4009
Packit 6c4009
   The fifth argument to _dl_profile_fixup is a pointer to long int.
Packit 6c4009
   The fourth argument to _dl_call_pltexit is a pointer to
Packit 6c4009
   La_ia64_retval:
Packit 6c4009
Packit 6c4009
   8byte r8
Packit 6c4009
   8byte r9
Packit 6c4009
   8byte r10
Packit 6c4009
   8byte r11
Packit 6c4009
   16byte f8
Packit 6c4009
   16byte f9
Packit 6c4009
   16byte f10
Packit 6c4009
   16byte f11
Packit 6c4009
   16byte f12
Packit 6c4009
   16byte f13
Packit 6c4009
   16byte f14
Packit 6c4009
   16byte f15
Packit 6c4009
Packit 6c4009
  Since stack has to be 16 byte aligned, the stack allocation is in
Packit 6c4009
  16byte increment. Before calling _dl_profile_fixup, the stack will
Packit 6c4009
  look like
Packit 6c4009
Packit 6c4009
  psp	new frame_size
Packit 6c4009
  +16	La_ia64_regs
Packit 6c4009
  sp	scratch
Packit 6c4009
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
#define PLTENTER_FRAME_SIZE (4*8 + 8*8 + 8*16 + 2*8 + 16)
Packit 6c4009
#define PLTEXIT_FRAME_SIZE (PLTENTER_FRAME_SIZE + 4*8 + 8*16)
Packit 6c4009
Packit 6c4009
#ifndef PROF
Packit 6c4009
ENTRY(_dl_runtime_profile)
Packit 6c4009
	{ .mii
Packit 6c4009
	  .prologue
Packit 6c4009
	  .save ar.pfs, r40
Packit 6c4009
	  alloc loc0 = ar.pfs, 8, 12, 8, 0
Packit 6c4009
	  .vframe loc10
Packit 6c4009
	  mov loc10 = r12
Packit 6c4009
	  .save rp, loc1
Packit 6c4009
	  mov loc1 = b0
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  .save ar.unat, r17
Packit 6c4009
	  mov r17 = ar.unat
Packit 6c4009
	  .save ar.lc, loc6
Packit 6c4009
	  mov loc6 = ar.lc
Packit 6c4009
	  mov loc11 = gp
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  .body
Packit 6c4009
	  /* There is a 16 byte scratch area. r2 will start at r8 and
Packit 6c4009
	     r3 will start at r9 for La_ia64_regs.  */
Packit 6c4009
	  adds r2 = -(PLTENTER_FRAME_SIZE - 16), r12
Packit 6c4009
	  adds r3 = -(PLTENTER_FRAME_SIZE - 24), r12
Packit 6c4009
	  adds r12 = -PLTENTER_FRAME_SIZE, r12
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  st8 [r2] = r8, 16;
Packit 6c4009
	  st8 [r3] = r9, 16;
Packit 6c4009
	  mov out2 = b0		/* needed by _dl_fixup_profile */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  st8 [r2] = r10, 16;
Packit 6c4009
	  st8 [r3] = r11, 16;
Packit 6c4009
	  adds out3 = 16, r12	/* pointer to La_ia64_regs */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  .mem.offset 0, 0
Packit 6c4009
	  st8.spill [r2] = in0, 16
Packit 6c4009
	  .mem.offset 8, 0
Packit 6c4009
	  st8.spill [r3] = in1, 16
Packit 6c4009
	  mov out4 = loc10	/* pointer to new frame size  */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  .mem.offset 0, 0
Packit 6c4009
	  st8.spill [r2] = in2, 16
Packit 6c4009
	  .mem.offset 8, 0
Packit 6c4009
	  st8.spill [r3] = in3, 16
Packit 6c4009
	  mov loc2 = r8		/* preserve struct value register */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  .mem.offset 0, 0
Packit 6c4009
	  st8.spill [r2] = in4, 16
Packit 6c4009
	  .mem.offset 8, 0
Packit 6c4009
	  st8.spill [r3] = in5, 16
Packit 6c4009
	  mov loc3 = r9		/* preserve language specific register */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  .mem.offset 0, 0
Packit 6c4009
	  st8 [r2] = in6, 16
Packit 6c4009
	  .mem.offset 8, 0
Packit 6c4009
	  st8 [r3] = in7, 24	/* adjust for f9 */
Packit 6c4009
	  mov loc4 = r10	/* preserve language specific register */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  mov r18 = ar.unat	/* save it in La_ia64_regs */
Packit 6c4009
	  mov loc7 = out3	/* save it for _dl_call_pltexit */
Packit 6c4009
	  mov loc5 = r11	/* preserve language specific register */
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  stf.spill [r2] = f8, 32
Packit 6c4009
	  stf.spill [r3] = f9, 32
Packit 6c4009
	  mov out0 = r16	/* needed by _dl_fixup_profile */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  mov ar.unat = r17	/* restore it for function call */
Packit 6c4009
	  mov loc8 = r16	/* save it for _dl_call_pltexit */
Packit 6c4009
	  nop.i 0x0
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  stf.spill [r2] = f10, 32
Packit 6c4009
	  stf.spill [r3] = f11, 32
Packit 6c4009
	  shl out1 = r15, 4
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  stf.spill [r2] = f12, 32
Packit 6c4009
	  stf.spill [r3] = f13, 32
Packit 6c4009
	  /* Relocation record is 24 byte. */
Packit 6c4009
	  shladd out1 = r15, 3, out1
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  stf.spill [r2] = f14, 32
Packit 6c4009
	  stf.spill [r3] = f15, 24
Packit 6c4009
	  mov loc9 = out1	/* save it for _dl_call_pltexit */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmb
Packit 6c4009
	  st8 [r2] = r18	/* store ar.unat */
Packit 6c4009
	  st8 [r3] = loc10	/* store sp */
Packit 6c4009
	  br.call.sptk.many b0 = _dl_profile_fixup
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  /* Skip the 16byte scratch area, 4 language specific GRs and
Packit 6c4009
	     8 incoming GRs to restore incoming fp registers.  */
Packit 6c4009
	  adds r2 = (4*8 + 8*8 + 16), r12
Packit 6c4009
	  adds r3 = (4*8 + 8*8 + 32), r12
Packit 6c4009
	  mov b6 = ret0
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ldf.fill f8 = [r2], 32
Packit 6c4009
	  ldf.fill f9 = [r3], 32
Packit 6c4009
	  mov gp = ret1
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ldf.fill f10 = [r2], 32
Packit 6c4009
	  ldf.fill f11 = [r3], 32
Packit 6c4009
	  mov r8 = loc2		/* restore struct value register */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ldf.fill f12 = [r2], 32
Packit 6c4009
	  ldf.fill f13 = [r3], 32
Packit 6c4009
	  mov r9 = loc3		/* restore language specific register */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ldf.fill f14 = [r2], 32
Packit 6c4009
	  ldf.fill f15 = [r3], 32
Packit 6c4009
	  mov r10 = loc4	/* restore language specific register */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  ld8 r15 = [loc10]	/* load the new frame size */
Packit 6c4009
	  mov r11 = loc5	/* restore language specific register */
Packit 6c4009
	  ;;
Packit 6c4009
	  cmp.eq p6, p7 = -1, r15
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
(p7)	  cmp.eq p8, p9 = 0, r15
Packit 6c4009
(p6)	  mov b0 = loc1
Packit 6c4009
(p6)	  mov ar.lc = loc6
Packit 6c4009
	}
Packit 6c4009
	{ .mib
Packit 6c4009
	  nop.m 0x0
Packit 6c4009
(p6)	  mov ar.pfs = loc0
Packit 6c4009
(p6)	  br.cond.dptk.many .Lresolved
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
	/* At this point, the stack looks like
Packit 6c4009
Packit 6c4009
	  +psp	free
Packit 6c4009
	  +16	La_ia64_regs
Packit 6c4009
	  sp	scratch
Packit 6c4009
Packit 6c4009
	  We need to keep the current stack and call the resolved
Packit 6c4009
	  function by copying the r15 byte from sp + PLTENTER_FRAME_SIZE
Packit 6c4009
	  + 16 (scratch area) to sp + 16 (scratch area). Since stack
Packit 6c4009
	  has to be 16byte aligned, we around r15 up to 16byte.  */
Packit 6c4009
Packit 6c4009
	{ .mbb
Packit 6c4009
(p9)	  adds r15 = 15, r15
Packit 6c4009
(p8)	  br.cond.dptk.many .Lno_new_frame
Packit 6c4009
	  nop.b 0x0
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  and r15 = -16, r15
Packit 6c4009
	  ;;
Packit 6c4009
	  /* We don't copy the 16byte scatch area. Prepare r16/r17 as
Packit 6c4009
	     destination.  */
Packit 6c4009
	  sub r16 = r12, r15
Packit 6c4009
	  sub r17 = r12, r15
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  adds r16 = 16, r16
Packit 6c4009
	  adds r17 = 24, r17
Packit 6c4009
	  sub r12 = r12, r15		/* Adjust stack  */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  nop.m 0x0
Packit 6c4009
	  shr r15 = r15, 4
Packit 6c4009
	  ;;
Packit 6c4009
	  adds r15 = -1, r15
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  /* Skip the 16byte scatch area. Prepare r2/r3 as source.  */
Packit 6c4009
	  adds r2 = 16, loc10
Packit 6c4009
	  adds r3 = 24, loc10
Packit 6c4009
	  mov ar.lc = r15
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
.Lcopy:
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ld8 r18 = [r2], 16
Packit 6c4009
	  ld8 r19 = [r3], 16
Packit 6c4009
	  nop.i 0x0
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmb
Packit 6c4009
	  st8 [r16] = r18, 16
Packit 6c4009
	  st8 [r17] = r19, 16
Packit 6c4009
	  br.cloop.sptk.few .Lcopy
Packit 6c4009
	}
Packit 6c4009
.Lno_new_frame:
Packit 6c4009
	{ .mii
Packit 6c4009
	  mov out0 = in0
Packit 6c4009
	  mov out1 = in1
Packit 6c4009
	  mov out2 = in2
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  mov out3 = in3
Packit 6c4009
	  mov out4 = in4
Packit 6c4009
	  mov out5 = in5
Packit 6c4009
	}
Packit 6c4009
	{ .mib
Packit 6c4009
	  mov out6 = in6
Packit 6c4009
	  mov out7 = in7
Packit 6c4009
	  /* Call the resolved function  */
Packit 6c4009
	  br.call.sptk.many b0 = b6
Packit 6c4009
	}
Packit 6c4009
	{ .mii
Packit 6c4009
	  /* Prepare stack for _dl_call_pltexit. Loc10 has the original
Packit 6c4009
	     stack pointer.  */
Packit 6c4009
	  adds r12 = -PLTEXIT_FRAME_SIZE, loc10
Packit 6c4009
	  adds r2 = -(PLTEXIT_FRAME_SIZE - 16), loc10
Packit 6c4009
	  adds r3 = -(PLTEXIT_FRAME_SIZE - 24), loc10
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  /* Load all possible return values into buffer.  */
Packit 6c4009
	  st8 [r2] = r8, 16
Packit 6c4009
	  st8 [r3] = r9, 16
Packit 6c4009
	  mov out0 = loc8
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  st8 [r2] = r10, 16
Packit 6c4009
	  st8 [r3] = r11, 24
Packit 6c4009
	  mov out1 = loc9
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  stf.spill [r2] = f8, 32
Packit 6c4009
	  stf.spill [r3] = f9, 32
Packit 6c4009
	  mov out2 = loc7		/* Pointer to La_ia64_regs */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  stf.spill [r2] = f10, 32
Packit 6c4009
	  stf.spill [r3] = f11, 32
Packit 6c4009
	  adds out3 = 16, r12		/* Pointer to La_ia64_retval */
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  stf.spill [r2] = f12, 32
Packit 6c4009
	  stf.spill [r3] = f13, 32
Packit 6c4009
	  /* We need to restore gp for _dl_call_pltexit. */
Packit 6c4009
	  mov gp = loc11
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmb
Packit 6c4009
	  stf.spill [r2] = f14
Packit 6c4009
	  stf.spill [r3] = f15
Packit 6c4009
	  br.call.sptk.many b0 = _dl_call_pltexit
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  /* Load all the non-floating and floating return values. Skip
Packit 6c4009
	     the 16byte scratch area.  */
Packit 6c4009
	  adds r2 = 16, r12
Packit 6c4009
	  adds r3 = 24, r12
Packit 6c4009
	  nop.i 0x0
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ld8 r8 = [r2], 16
Packit 6c4009
	  ld8 r9 = [r3], 16
Packit 6c4009
	  nop.i 0x0
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ld8 r10 = [r2], 16
Packit 6c4009
	  ld8 r11 = [r3], 24
Packit 6c4009
	  nop.i 0x0
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ldf.fill f8 = [r2], 32
Packit 6c4009
	  ldf.fill f9 = [r3], 32
Packit 6c4009
	  mov ar.lc = loc6
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ldf.fill f10 = [r2], 32
Packit 6c4009
	  ldf.fill f11 = [r3], 32
Packit 6c4009
	  mov ar.pfs = loc0
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ldf.fill f12 = [r2], 32
Packit 6c4009
	  ldf.fill f13 = [r3], 32
Packit 6c4009
	  mov b0 = loc1
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	{ .mmi
Packit 6c4009
	  ldf.fill f14 = [r2]
Packit 6c4009
	  ldf.fill f15 = [r3]
Packit 6c4009
	  /* We know that the previous stack pointer, loc10, isn't 0.
Packit 6c4009
	     We use it to reload p7.  */
Packit 6c4009
	  cmp.ne p7, p0 = 0, loc10
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
.Lresolved:
Packit 6c4009
	{ .mmb
Packit 6c4009
	  .restore sp
Packit 6c4009
	  mov r12 = loc10
Packit 6c4009
(p7)	  br.ret.sptk.many b0
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
	/* An alloc is needed for the break system call to work. We
Packit 6c4009
	   don't care about the old value of the pfs register. After
Packit 6c4009
	   this alloc, we can't use any rotating registers. Otherwise
Packit 6c4009
	   assembler won't be happy. This has to be at the end.  */
Packit 6c4009
	{ .mmb
Packit 6c4009
	  .prologue
Packit 6c4009
	  .body
Packit 6c4009
	  alloc r2 = ar.pfs, 0, 0, 8, 0
Packit 6c4009
	  br.sptk.many b6
Packit 6c4009
	  ;;
Packit 6c4009
	}
Packit 6c4009
END(_dl_runtime_profile)
Packit 6c4009
#endif