Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/sparc/linux-unwind.h @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 77e2b8dfacca |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* DWARF2 EH unwinding support for SPARC Linux. | |
2 Copyright 2004, 2005, 2009 Free Software Foundation, Inc. | |
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 | |
26 /* Do code reading to identify a signal frame, and set the frame | |
27 state data appropriately. See unwind-dw2.c for the structs. */ | |
28 | |
29 /* Handle multilib correctly. */ | |
30 #if defined(__arch64__) | |
31 | |
32 /* 64-bit SPARC version */ | |
33 #define MD_FALLBACK_FRAME_STATE_FOR sparc64_fallback_frame_state | |
34 | |
35 static _Unwind_Reason_Code | |
36 sparc64_fallback_frame_state (struct _Unwind_Context *context, | |
37 _Unwind_FrameState *fs) | |
38 { | |
39 unsigned int *pc = context->ra; | |
40 long new_cfa, i; | |
41 long regs_off, fpu_save_off; | |
42 long this_cfa, fpu_save; | |
43 | |
44 if (pc[0] != 0x82102065 /* mov NR_rt_sigreturn, %g1 */ | |
45 || pc[1] != 0x91d0206d) /* ta 0x6d */ | |
46 return _URC_END_OF_STACK; | |
47 regs_off = 192 + 128; | |
48 fpu_save_off = regs_off + (16 * 8) + (3 * 8) + (2 * 4); | |
49 this_cfa = (long) context->cfa; | |
50 new_cfa = *(long *)((context->cfa) + (regs_off + (14 * 8))); | |
51 new_cfa += 2047; /* Stack bias */ | |
52 fpu_save = *(long *)((this_cfa) + (fpu_save_off)); | |
53 fs->regs.cfa_how = CFA_REG_OFFSET; | |
54 fs->regs.cfa_reg = 14; | |
55 fs->regs.cfa_offset = new_cfa - (long) context->cfa; | |
56 for (i = 1; i < 16; ++i) | |
57 { | |
58 fs->regs.reg[i].how = REG_SAVED_OFFSET; | |
59 fs->regs.reg[i].loc.offset = | |
60 this_cfa + (regs_off + (i * 8)) - new_cfa; | |
61 } | |
62 for (i = 0; i < 16; ++i) | |
63 { | |
64 fs->regs.reg[i + 16].how = REG_SAVED_OFFSET; | |
65 fs->regs.reg[i + 16].loc.offset = | |
66 this_cfa + (i * 8) - new_cfa; | |
67 } | |
68 if (fpu_save) | |
69 { | |
70 for (i = 0; i < 64; ++i) | |
71 { | |
72 if (i > 32 && (i & 0x1)) | |
73 continue; | |
74 fs->regs.reg[i + 32].how = REG_SAVED_OFFSET; | |
75 fs->regs.reg[i + 32].loc.offset = | |
76 (fpu_save + (i * 4)) - new_cfa; | |
77 } | |
78 } | |
79 /* Stick return address into %g0, same trick Alpha uses. */ | |
80 fs->regs.reg[0].how = REG_SAVED_OFFSET; | |
81 fs->regs.reg[0].loc.offset = | |
82 this_cfa + (regs_off + (16 * 8) + 8) - new_cfa; | |
83 fs->retaddr_column = 0; | |
84 return _URC_NO_REASON; | |
85 } | |
86 | |
87 #else | |
88 | |
89 /* 32-bit SPARC version */ | |
90 #define MD_FALLBACK_FRAME_STATE_FOR sparc_fallback_frame_state | |
91 | |
92 static _Unwind_Reason_Code | |
93 sparc_fallback_frame_state (struct _Unwind_Context *context, | |
94 _Unwind_FrameState *fs) | |
95 { | |
96 unsigned int *pc = context->ra; | |
97 int new_cfa, i, oldstyle; | |
98 int regs_off, fpu_save_off; | |
99 int fpu_save, this_cfa; | |
100 | |
101 if (pc[1] != 0x91d02010) /* ta 0x10 */ | |
102 return _URC_END_OF_STACK; | |
103 if (pc[0] == 0x821020d8) /* mov NR_sigreturn, %g1 */ | |
104 oldstyle = 1; | |
105 else if (pc[0] == 0x82102065) /* mov NR_rt_sigreturn, %g1 */ | |
106 oldstyle = 0; | |
107 else | |
108 return _URC_END_OF_STACK; | |
109 if (oldstyle) | |
110 { | |
111 regs_off = 96; | |
112 fpu_save_off = regs_off + (4 * 4) + (16 * 4); | |
113 } | |
114 else | |
115 { | |
116 regs_off = 96 + 128; | |
117 fpu_save_off = regs_off + (4 * 4) + (16 * 4) + (2 * 4); | |
118 } | |
119 this_cfa = (int) context->cfa; | |
120 new_cfa = *(int *)((context->cfa) + (regs_off+(4*4)+(14 * 4))); | |
121 fpu_save = *(int *)((this_cfa) + (fpu_save_off)); | |
122 fs->regs.cfa_how = CFA_REG_OFFSET; | |
123 fs->regs.cfa_reg = 14; | |
124 fs->regs.cfa_offset = new_cfa - (int) context->cfa; | |
125 for (i = 1; i < 16; ++i) | |
126 { | |
127 if (i == 14) | |
128 continue; | |
129 fs->regs.reg[i].how = REG_SAVED_OFFSET; | |
130 fs->regs.reg[i].loc.offset = | |
131 this_cfa + (regs_off+(4 * 4)+(i * 4)) - new_cfa; | |
132 } | |
133 for (i = 0; i < 16; ++i) | |
134 { | |
135 fs->regs.reg[i + 16].how = REG_SAVED_OFFSET; | |
136 fs->regs.reg[i + 16].loc.offset = | |
137 this_cfa + (i * 4) - new_cfa; | |
138 } | |
139 if (fpu_save) | |
140 { | |
141 for (i = 0; i < 32; ++i) | |
142 { | |
143 fs->regs.reg[i + 32].how = REG_SAVED_OFFSET; | |
144 fs->regs.reg[i + 32].loc.offset = | |
145 (fpu_save + (i * 4)) - new_cfa; | |
146 } | |
147 } | |
148 /* Stick return address into %g0, same trick Alpha uses. */ | |
149 fs->regs.reg[0].how = REG_SAVED_OFFSET; | |
150 fs->regs.reg[0].loc.offset = this_cfa+(regs_off+4)-new_cfa; | |
151 fs->retaddr_column = 0; | |
152 return _URC_NO_REASON; | |
153 } | |
154 | |
155 #endif |