Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_V8Code.s
CommitLineData
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
101run_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
135v9_to_v8plus_pc_npc_s_i_va_mem:
136v9_to_v8plus_pc_npc_s_i_va_tt:
137 st %o5,[%sp + 100] ! tt - store on the stack
138
139v9_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
143v9_to_v8plus_pc_npc_s_i_tt:
144 st %o4,[%sp + 92] ! lower part of 64bit (va) or
145 ! 32bit argument (tt)
146v9_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
165trap_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
176inst_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
187data_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
198data_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
209invalid_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
219inst_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