1/* Copyright (C) 2000-2015 Free Software Foundation, Inc. 2 Contributed by Jes Sorensen, <Jes.Sorensen@cern.ch> 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GCC is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 Under Section 7 of GPL version 3, you are granted additional 17 permissions described in the GCC Runtime Library Exception, version 18 3.1, as published by the Free Software Foundation. 19 20 You should have received a copy of the GNU General Public License and 21 a copy of the GCC Runtime Library Exception along with this program; 22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 <http://www.gnu.org/licenses/>. */ 24 25#include "auto-host.h" 26 27.section .ctors,"aw","progbits" 28 .align 8 29__CTOR_LIST__: 30 data8 -1 31 32.section .dtors,"aw","progbits" 33 .align 8 34__DTOR_LIST__: 35 data8 -1 36 37.section .jcr,"aw","progbits" 38 .align 8 39__JCR_LIST__: 40 41.section .sdata 42 .type dtor_ptr,@object 43 .size dtor_ptr,8 44dtor_ptr: 45 data8 @gprel(__DTOR_LIST__ + 8) 46 47 /* A handle for __cxa_finalize to manage c++ local destructors. */ 48 .global __dso_handle 49 .type __dso_handle,@object 50 .size __dso_handle,8 51#ifdef SHARED 52 .section .data 53__dso_handle: 54 data8 __dso_handle 55#else 56 .section .bss 57 .align 8 58__dso_handle: 59 .skip 8 60#endif 61 .hidden __dso_handle 62 63 64#ifdef HAVE_INITFINI_ARRAY_SUPPORT 65 66.section .fini_array, "a" 67 data8 @fptr(__do_global_dtors_aux) 68 69.section .init_array, "a" 70 data8 @fptr(__do_jv_register_classes) 71 data8 @fptr(__do_global_ctors_aux) 72 73#else /* !HAVE_INITFINI_ARRAY_SUPPORT */ 74/* 75 * Fragment of the ELF _fini routine that invokes our dtor cleanup. 76 * 77 * We make the call by indirection, because in large programs the 78 * .fini and .init sections are not in range of the destination, and 79 * we cannot allow the linker to insert a stub at the end of this 80 * fragment of the _fini function. Further, Itanium does not implement 81 * the long branch instructions, and we do not wish every program to 82 * trap to the kernel for emulation. 83 * 84 * Note that we require __do_global_dtors_aux to preserve the GP, 85 * so that the next fragment in .fini gets the right value. 86 */ 87.section .fini,"ax","progbits" 88 { .mlx 89 movl r2 = @pcrel(__do_global_dtors_aux - 16) 90 } 91 { .mii 92 mov r3 = ip 93 ;; 94 add r2 = r2, r3 95 ;; 96 } 97 { .mib 98 nop 0 99 mov b6 = r2 100 br.call.sptk.many b0 = b6 101 } 102 103/* Likewise for _init. */ 104 105.section .init,"ax","progbits" 106 { .mlx 107 movl r2 = @pcrel(__do_jv_register_classes - 16) 108 } 109 { .mii 110 mov r3 = ip 111 ;; 112 add r2 = r2, r3 113 ;; 114 } 115 { .mib 116 nop 0 117 mov b6 = r2 118 br.call.sptk.many b0 = b6 119 } 120#endif /* !HAVE_INITFINI_ARRAY_SUPPORT */ 121 122.section .text 123 .align 32 124 .proc __do_global_dtors_aux 125__do_global_dtors_aux: 126 .prologue 127#ifndef SHARED 128 .save ar.pfs, r35 129 alloc loc3 = ar.pfs, 0, 4, 1, 0 130 addl loc0 = @gprel(dtor_ptr), gp 131 .save rp, loc1 132 mov loc1 = rp 133 .body 134 135 mov loc2 = gp 136 nop 0 137 br.sptk.many .entry 138#else 139 /* 140 if (__cxa_finalize) 141 __cxa_finalize(__dso_handle) 142 */ 143 .save ar.pfs, r35 144 alloc loc3 = ar.pfs, 0, 4, 1, 0 145 addl loc0 = @gprel(dtor_ptr), gp 146 addl r16 = @ltoff(@fptr(__cxa_finalize)), gp 147 ;; 148 149 ld8 r16 = [r16] 150 ;; 151 addl out0 = @ltoff(__dso_handle), gp 152 cmp.ne p7, p0 = r0, r16 153 ;; 154 155 ld8 out0 = [out0] 156(p7) ld8 r18 = [r16], 8 157 .save rp, loc1 158 mov loc1 = rp 159 .body 160 ;; 161 162 mov loc2 = gp 163(p7) ld8 gp = [r16] 164(p7) mov b6 = r18 165 166 nop 0 167 nop 0 168(p7) br.call.sptk.many rp = b6 169 ;; 170 171 nop 0 172 nop 0 173 br.sptk.many .entry 174#endif 175 /* 176 do { 177 dtor_ptr++; 178 (*(dtor_ptr-1)) (); 179 } while (dtor_ptr); 180 */ 181.loop: 182 st8 [loc0] = r15 // update dtor_ptr (in memory) 183 ld8 r17 = [r16], 8 // r17 <- dtor's entry-point 184 nop 0 185 ;; 186 187 ld8 gp = [r16] // gp <- dtor's gp 188 mov b6 = r17 189 br.call.sptk.many rp = b6 190 191.entry: ld8 r15 = [loc0] // r15 <- dtor_ptr (gp-relative) 192 ;; 193 add r16 = r15, loc2 // r16 <- dtor_ptr (absolute) 194 adds r15 = 8, r15 195 ;; 196 197 ld8 r16 = [r16] // r16 <- pointer to dtor's fdesc 198 mov rp = loc1 199 mov ar.pfs = loc3 200 ;; 201 202 cmp.ne p6, p0 = r0, r16 203(p6) br.cond.sptk.few .loop 204 br.ret.sptk.many rp 205 .endp __do_global_dtors_aux 206 207 .align 32 208 .proc __do_jv_register_classes 209__do_jv_register_classes: 210 .prologue 211 .save ar.pfs, r33 212 alloc loc1 = ar.pfs, 0, 3, 1, 0 213 movl out0 = @gprel(__JCR_LIST__) 214 ;; 215 216 addl r14 = @ltoff(@fptr(_Jv_RegisterClasses)), gp 217 add out0 = out0, gp 218 .save rp, loc0 219 mov loc0 = rp 220 .body 221 ;; 222 223 ld8 r14 = [r14] 224 ld8 r15 = [out0] 225 cmp.ne p6, p0 = r0, r0 226 ;; 227 228 cmp.eq.or p6, p0 = r0, r14 229 cmp.eq.or p6, p0 = r0, r15 230(p6) br.ret.sptk.many rp 231 232 ld8 r15 = [r14], 8 233 ;; 234 nop 0 235 mov b6 = r15 236 237 mov loc2 = gp 238 ld8 gp = [r14] 239 br.call.sptk.many rp = b6 240 ;; 241 242 mov gp = loc2 243 mov rp = loc0 244 mov ar.pfs = loc1 245 246 nop 0 247 nop 0 248 br.ret.sptk.many rp 249 .endp __do_jv_register_classes 250 251#ifdef SHARED 252.weak __cxa_finalize 253#endif 254.weak _Jv_RegisterClasses 255