Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: SS_V8Code.s | |
5 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
7 | * | |
8 | * The above named program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public | |
10 | * License version 2 as published by the Free Software Foundation. | |
11 | * | |
12 | * The above named program is distributed in the hope that it will be | |
13 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public | |
18 | * License along with this work; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
20 | * | |
21 | * ========== Copyright Header End ============================================ | |
22 | */ | |
23 | #if !defined(ARCH_X64) | |
24 | ||
25 | !============================================================================ | |
26 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
27 | !============================================================================ | |
28 | ! tHIS COMMENT SECTION IS A MUST READ fOR THOSE THAT ARE GOING TO CHANGE THIS | |
29 | ! CODE. iF YOU DON'T READ IT OR DO NOT KNOW WHAT YOU ARE DOING THEN KEEP OFF. | |
30 | !============================================================================ | |
31 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
32 | !============================================================================ | |
33 | ! In v9 mode all the functions relevant in the code below use between 4 and 6 | |
34 | ! arguments. This means that all there functions pass their arguments in | |
35 | ! registers only as v9 has %0 to %05 available for the first 6 64bit arguments. | |
36 | ! | |
37 | ! | |
38 | ! The v8(plus) standard stack frame looks like: | |
39 | ! | |
40 | ! %fp 0| 16-word window save area | (%fp == %i6) | |
41 | ! +--------------------------------+ | |
42 | ! | unspecified | | |
43 | ! | .... | | |
44 | ! | variable size | | |
45 | ! +--------------------------------+ | |
46 | ! +92 | (if needed) outgoing arg 6 ... | | |
47 | ! +--------------------------------+ | |
48 | ! | six words into which callee | | |
49 | ! +68 | may write outgoing arg 0 to 5 | | |
50 | ! +--------------------------------+ | |
51 | ! +64 | struct/union return pointer | | |
52 | ! +--------------------------------+ | |
53 | ! %sp 0 | 16-word window save area | (%sp == %o6) | |
54 | ! +--------------------------------+ | |
55 | ! | |
56 | ! The picture was taken from the documents found on http://www.sparc.com/standards | |
57 | ! | |
58 | ! On function calls registers %o0 to %o5 are arguments 0 to 5. Argument number | |
59 | ! 6 is placed on the stack at offset %sp + 92. The 7th argument is placed at | |
60 | ! offset %sp + 96, etc. In v8(plus) mode the arguments are 32bits in size. | |
61 | ! | |
62 | ! The v8plus "standard" documents says that the kernel preserves the upper | |
63 | ! 32bits of the global and the out registers on trap or interrupt. This suits | |
64 | ! us well as all our assembly code does not use save and restore, so without | |
65 | ! looking we can say these routines are safe for use in v8plus mode. Note we | |
66 | ! know our assembly only tail calls - it doesn't make "nested calls. Nested | |
67 | ! calls can chop the out registers to 32bits !!!! so v9 assembly code that does | |
68 | ! that wouldn't be safe to use in v8plus mode. | |
69 | ! | |
70 | ! There is one problem that we need to fix however. The stack frame and argument | |
71 | ! passing in v8plus is 32bits, and 64bits in v9 mode. So we need calling | |
72 | ! convention converters around the assembly code. | |
73 | ! | |
74 | ! A 64bit value in v8plus is stored in two 32bit memory locations. Following | |
75 | ! the ldd/std instructions the word(32bits) at addr contains bits 31 to 0 and | |
76 | ! the word at addr + 4 contain bits 63 to 32. For argument passing bits 31 | |
77 | ! to 0 is kept argument N and bits 63 to 32 in argumewnt N+1. | |
78 | !============================================================================ | |
79 | ||
80 | #include "SS_Assembly.h" | |
81 | ||
82 | .register %g2,#scratch | |
83 | .register %g3,#scratch | |
84 | .section ".text" | |
85 | ||
86 | !============================================================================ | |
87 | ! run_exe_v8plus_to_v9 - this is the entry point for all the assembly coded | |
88 | ! routines in the run_exe table. From v8plus we call into v9 code. The run_exe | |
89 | ! routine's type signature is | |
90 | ! SS_Vaddr (*execute)( SS_Vaddr, SS_Vaddr, SS_Strand*,SS_Instr* ); | |
91 | ! which fits in 6 registers: %o0 to %o5. However, some of the assembly | |
92 | ! routines need to call routines with more arguments: data_mmu for example. | |
93 | ! Hence this routines created space on the stack for these extra routines, | |
94 | ! it takes the worst case apporach, which is 3 more 4byte arguments is 12 | |
95 | ! bytes. The v8(plus) ABI says that we need to move %sp by 92 + 12 = 104. | |
96 | !============================================================================ | |
97 | ||
98 | .align 8 | |
99 | .global run_exe_v8plus_to_v9 | |
100 | .type run_exe_v8plus_to_v9, #function | |
101 | run_exe_v8plus_to_v9: | |
102 | save %sp,-104,%sp ! reserve 12 bytes of stack space | |
103 | ||
104 | ldsh [%i5 + I_EXE_TBL_IDX],%g2 ! Get exe table index | |
105 | ||
106 | sllx %i0,32,R_PC ! pc = (%i0 << 32) | %i1 | |
107 | srl %i1,0x0,%g1 | |
108 | or R_PC,%g1,R_PC | |
109 | ||
110 | ld [%i4 + S_V8_EXE_TABLE],%g3 ! Get real exe table pointer | |
111 | ||
112 | sllx %i2,32,R_NPC ! npc = (%i2 << 32) | %i3 | |
113 | srl %i3,0x0,%g1 | |
114 | or R_NPC,%g1,R_NPC | |
115 | ||
116 | sll %g2,2,%g2 | |
117 | ld [%g3 + %g2],%g4 ! Get exe routine function | |
118 | ||
119 | mov %i4,S_PTR ! %o2 - s | |
120 | ||
121 | jmpl %g4,%o7 ! call asm exe routine | |
122 | mov %i5,I_PTR ! and it returns pc in v8plus style. | |
123 | ||
124 | mov %o0,%i0 ! return pc, in v8plus mode that's | |
125 | ret | |
126 | restore %o1,0,%o1 | |
127 | ||
128 | ||
129 | !============================================================================ | |
130 | ! v9_to_v8plus - these are the exit points from the assembly routine (v9) to | |
131 | ! the c coded land (v8plus). The code has multiple entry points as the argu- | |
132 | ! ments are pretty much the same. | |
133 | !============================================================================ | |
134 | ||
135 | v9_to_v8plus_pc_npc_s_i_va_mem: | |
136 | v9_to_v8plus_pc_npc_s_i_va_tt: | |
137 | st %o5,[%sp + 100] ! tt - store on the stack | |
138 | ||
139 | v9_to_v8plus_pc_npc_s_i_va: | |
140 | st %o4,[%sp + 96] ! store upper part of 64bit | |
141 | srlx %o4,32,%o4 ! va - store on the stack | |
142 | ||
143 | v9_to_v8plus_pc_npc_s_i_tt: | |
144 | st %o4,[%sp + 92] ! lower part of 64bit (va) or | |
145 | ! 32bit argument (tt) | |
146 | v9_to_v8plus_pc_npc_s_i: | |
147 | sra I_PTR,0,%o5 ! i is %o5 | |
148 | sra S_PTR,0,%o4 ! s is %o4 | |
149 | ||
150 | srl %o1,0,%o3 ! npc is %o2, %o3 | |
151 | srlx %o1,32,%o2 | |
152 | ||
153 | srl %o0,0,%o1 ! pc is %o0, %o1 | |
154 | jmpl %g4,%g0 ! return (%g4)(pc,npc,s,i,...); | |
155 | srlx %o0,32,%o0 | |
156 | ||
157 | ||
158 | !============================================================================ | |
159 | ! SS_Vaddr (*trap)( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, | |
160 | ! SS_Trap::Type tt ); | |
161 | !============================================================================ | |
162 | ||
163 | .global trap_v9_to_v8plus | |
164 | .type trap_v9_to_v8plus, #function | |
165 | trap_v9_to_v8plus: | |
166 | ba %xcc,v9_to_v8plus_pc_npc_s_i_tt | |
167 | ld [S_PTR + S_TRAP],%g4 | |
168 | ||
169 | !============================================================================ | |
170 | ! SS_Vaddr (*inst_trap)( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, | |
171 | ! SS_Vaddr va, SS_Trap::Type tt ); | |
172 | !============================================================================ | |
173 | ||
174 | .global inst_trap_v9_to_v8plus | |
175 | .type inst_trap_v9_to_v8plus, #function | |
176 | inst_trap_v9_to_v8plus: | |
177 | ba %xcc,v9_to_v8plus_pc_npc_s_i_va_tt | |
178 | ld [S_PTR + S_INST_TRAP],%g4 | |
179 | ||
180 | !============================================================================ | |
181 | ! SS_Vaddr (*data_trap)( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, | |
182 | ! SS_Vaddr va, SS_Trap::Type tt ); | |
183 | !============================================================================ | |
184 | ||
185 | .global data_trap_v9_to_v8plus | |
186 | .type data_trap_v9_to_v8plus, #function | |
187 | data_trap_v9_to_v8plus: | |
188 | ba %xcc,v9_to_v8plus_pc_npc_s_i_va_tt | |
189 | ld [S_PTR + S_DATA_TRAP],%g4 | |
190 | ||
191 | !============================================================================ | |
192 | ! SS_Vaddr (*data_mmu)( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, | |
193 | ! SS_Vaddr va, uint_t mem ); | |
194 | !============================================================================ | |
195 | ||
196 | .global data_mmu_v9_to_v8plus | |
197 | .type data_mmu_v9_to_v8plus, #function | |
198 | data_mmu_v9_to_v8plus: | |
199 | ba %xcc,v9_to_v8plus_pc_npc_s_i_va_mem | |
200 | ld [S_PTR + S_DATA_MMU],%g4 | |
201 | ||
202 | !============================================================================ | |
203 | ! SS_Vaddr (*invalid_asi)( SS_Vaddr pc, SS_Vaddr npc, SS_Strand*, SS_Instr*, | |
204 | ! SS_Vaddr ); | |
205 | !============================================================================ | |
206 | ||
207 | .global invalid_asi_v9_to_v8plus | |
208 | .type invalid_asi_v9_to_v8plus, #function | |
209 | invalid_asi_v9_to_v8plus: | |
210 | ba %xcc,v9_to_v8plus_pc_npc_s_i_va | |
211 | ld [S_PTR + S_INVALID_ASI],%g4 | |
212 | ||
213 | !============================================================================ | |
214 | ! SS_Vaddr (*inst_dev)( SS_Vaddr, SS_Vaddr, SS_Strand*,SS_Instr* ); | |
215 | !============================================================================ | |
216 | ||
217 | .global inst_dec_v9_to_v8plus | |
218 | .type inst_dec_v9_to_v8plus, #function | |
219 | inst_dec_v9_to_v8plus: | |
220 | ba %xcc,v9_to_v8plus_pc_npc_s_i | |
221 | ld [S_PTR + S_INST_DEC],%g4 | |
222 | ||
223 | #endif |