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