aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/ia64/crtbegin.asm
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/ia64/crtbegin.asm')
-rw-r--r--gcc/config/ia64/crtbegin.asm128
1 files changed, 121 insertions, 7 deletions
diff --git a/gcc/config/ia64/crtbegin.asm b/gcc/config/ia64/crtbegin.asm
index b77ad98..d44df5b 100644
--- a/gcc/config/ia64/crtbegin.asm
+++ b/gcc/config/ia64/crtbegin.asm
@@ -26,12 +26,17 @@ __CTOR_LIST__:
__DTOR_LIST__:
data8 -1
+.section .IA_64.unwind
+__EH_FRAME_BEGIN__:
+
.section .sdata
+5: data8 @segrel(6f)
.type dtor_ptr#,@object
.size dtor_ptr#,8
dtor_ptr:
data8 __DTOR_LIST__# + 8
+/* A handle for __cxa_finalize to manage c++ local destructors. */
.global __dso_handle#
.type __dso_handle#,@object
.size __dso_handle#,8
@@ -45,6 +50,16 @@ __dso_handle:
data8 0
#endif
+/* The frame object. */
+/* ??? How can we rationally keep this size correct? */
+
+.section .bss
+ .type frame_object#,@object
+ .size frame_object#,56
+ .align 8
+frame_object:
+ .zero 56
+
/*
* Fragment of the ELF _fini routine that invokes our dtor cleanup.
*
@@ -65,38 +80,55 @@ __dso_handle:
;;
}
-.text
+/*
+ * Fragment of the ELF _init routine that sets up the frame info.
+ */
+
+.section .init,"ax","progbits"
+ { .mfb
+ st8 [r12] = gp, -16
+ br.call.sptk.many b0 = __do_frame_setup#
+ ;;
+ }
+ { .mmi
+ adds r12 = 16, r12
+ ;;
+ ld8 gp = [r12]
+ ;;
+ }
+.section .text
.align 16
.proc __do_global_dtors_aux#
-
__do_global_dtors_aux:
#ifndef SHARED
{ .mii
- alloc loc2 = ar.pfs, 0, 3, 0, 0
+ alloc loc3 = ar.pfs, 0, 4, 1, 0
addl loc0 = @gprel(dtor_ptr#), gp
mov loc1 = b0
}
+ mov loc2 = gp
#else
/*
if (__cxa_finalize)
__cxa_finalize(__dso_handle)
*/
{ .mii
- alloc loc2 = ar.pfs, 1, 3, 0, 0
+ alloc loc3 = ar.pfs, 0, 4, 1, 0
addl loc0 = @gprel(dtor_ptr#), gp
addl r16 = @ltoff(@fptr(__cxa_finalize#)), gp
;;
}
+ mov loc2 = gp
{ .mmi
ld8 r16 = [r16]
;;
- addl r32 = @ltoff(__dso_handle#), gp
+ addl out0 = @ltoff(__dso_handle#), gp
cmp.ne p7, p0 = r0, r16
;;
}
{ .mmi
- ld8 r32 = [r32]
+ ld8 out0 = [out0]
(p7) ld8 r18 = [r16], 8
mov loc1 = b0
;;
@@ -139,9 +171,36 @@ __do_global_dtors_aux:
cmp.ne p6, p0 = r0, r16
(p6) br.cond.sptk.few 0b
}
+ mov gp = loc2
+ ;;
+ /*
+ if (__deregister_frame_info)
+ __deregister_frame_info(__EH_FRAME_BEGIN__)
+ */
+ { .mii
+ addl r16 = @ltoff(@fptr(__deregister_frame_info#)), gp
+ addl out0 = @ltoff(__EH_FRAME_BEGIN__#), gp
+ ;;
+ }
+ { .mmi
+ ld8 r16 = [r16]
+ ld8 out0 = [out0]
+ ;;
+ }
+ { .mmi
+ cmp.ne p7, p0 = r0, r16
+ ;;
+(p7) ld8 r18 = [r16], 8
+ ;;
+ }
+ { .mib
+(p7) ld8 gp = [r16]
+(p7) mov b6 = r18
+(p7) br.call.sptk.many b0 = b6
+ }
{ .mii
mov b0 = loc1
- mov ar.pfs = loc2
+ mov ar.pfs = loc3
}
{ .bbb
br.ret.sptk.many b0
@@ -149,6 +208,61 @@ __do_global_dtors_aux:
}
.endp __do_global_dtors_aux#
+ .proc __do_frame_setup#
+__do_frame_setup:
+ /*
+ if (__register_frame_info)
+ __register_frame_info(__EH_FRAME_BEGIN__)
+ */
+ { .mii
+ alloc loc3 = ar.pfs, 0, 4, 2, 0
+ addl r16 = @ltoff(@fptr(__register_frame_info#)), gp
+ addl out0 = @ltoff(__EH_FRAME_BEGIN__#), gp
+ ;;
+ }
+ addl out1 = @ltoff(frame_object#), gp
+ ;;
+ /* frame_object.pc_base = segment_base_offset;
+ pc_base is at offset 0 within frame_object. */
+6:
+ mov loc0 = ip
+ addl loc1 = @gprel(5b), gp
+ ;;
+ ld8 loc1 = [loc1]
+ ld8 out1 = [out1]
+ ;;
+ sub loc2 = loc0, loc1
+ ;;
+ st8 [out1] = loc2
+ { .mmi
+ ld8 r16 = [r16]
+ ld8 out0 = [out0]
+ mov loc0 = b0
+ ;;
+ }
+ { .mmi
+ cmp.ne p7, p0 = r0, r16
+ ;;
+(p7) ld8 r18 = [r16], 8
+ ;;
+ }
+ { .mib
+(p7) ld8 gp = [r16]
+(p7) mov b6 = r18
+(p7) br.call.sptk.many b0 = b6
+ }
+ { .mii
+ mov b0 = loc0
+ mov ar.pfs = loc3
+ }
+ { .bbb
+ br.ret.sptk.many b0
+ ;;
+ }
+ .endp __do_frame_setup#
+
#ifdef SHARED
.weak __cxa_finalize#
#endif
+.weak __deregister_frame_info#
+.weak __register_frame_info#