Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_Float.s
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: SS_Float.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.register %g2,#scratch
26.register %g3,#scratch
27.section ".text"
28
29! All functions that check for FPU enabled branch here when it's disabled
30! and have to throw a trap. I exect %o0=pc, %o1=npc, %o2=strand_ptr, %o3=instr_ptr
31! so all that's required is setting %o4 to the trap number. There's two entry
32! points here: one that restores the host fsr, and the other doesn't.
33
34.align 8
35.global fpop_disabled_trap_fsr
36.type fpop_disabled_trap_fsr, #function
37fpop_disabled_trap_fsr:
38 ldx [S_PTR + S_FSR_CPU],%fsr ! Load host's %fsr
39
40.global fpop_disabled_trap
41.type fpop_disabled_trap, #function
42fpop_disabled_trap:
43 ldptr [S_PTR + TRAP],%g1 ! In v8plus mode we need to convert
44 jmpl %g1,%g0 ! from v9 to v8plus first before we
45 mov T_FP_DISABLED,%o4 ! handle the trap
46
47
48#define FSR_CEXC_TO_AEXC_SFT 5
49#define FSR_CEXC 0x01f
50#define FSR_AEXC (FSR_CEXC << FSR_CEXC_TO_AEXC_SFT)
51#define FSR_AEXC_CEXC (FSR_CEXC+FSR_AEXC)
52#define FSR_FTT_SFT 14
53#define FSR_FTT_MSK (0x7 << FSR_FTT_SFT)
54#define FSR_IEEE_754_EXC (1 << FSR_FTT_SFT)
55
56/*
57 * fsr_cpu - the fsr of the host
58 * fsr_tmp - tmp for getting fsr after operation
59 * fsr_run - the fsr of the simulated cpu with:
60 * fsr_run.tem = 0 - this so we can catch ieee traps
61 * fsr_run.aexc = 0 -
62 * fsr_run.cexc = 0 - this so we can catch ieee traps
63 * fsr_tem - the fsr.tem field of the simulated cpu
64 * fsr_exc - the fsr.cexc and fsr.aexc fields of the simulated cpu
65 */
66
67.global fpop_retl
68.global fpop_retl_f
69.global fpop_retl_d
70.type fpop_retl , #function
71.type fpop_retl_f, #function
72.type fpop_retl_d, #function
73
74!============================================================================
75! fpop_retl_d is the tail code for floating point functions that have a double
76! precision result and update %fsr
77! %g3 - rd index
78! %g5 - cpu %gsr to be restored
79! %f8 (%f9) - fpop result
80!============================================================================
81
82.align 8
83
84fpop_retl_d:
85 wr %g5,%gsr ! Restore host %gsr
86
87 stx %fsr,[S_PTR + S_FSR_TMP] ! Grab host's %fsr ... and get instr result
88 ldx [S_PTR + S_FSR_TMP],%g1
89
90 ldx [S_PTR + S_FSR_TEM],%g4 ! Get simulated fsr tem
91 ldx [S_PTR + S_FSR_EXC],%g5 ! Get simulated fsr aexc and cexc
92
93 andn %g1,FSR_AEXC_CEXC,%g2 ! Clear aexc and cexc of fsr_run
94 andcc %g1,FSR_CEXC,%g1 ! Extract cexc, and check if any traps occured
95
96 be %xcc,fpop_fprs_d ! No traps then update fprs and FRF and return
97 ldx [S_PTR + S_FSR_CPU],%fsr ! Load host's %fsr
98
99 andcc %g1,%g4,%g0 ! (tem & cexc) == 0?
100 and %g5,FSR_AEXC,%g5 ! Get previous fsr aexc
101
102 bne %xcc,fpop_trap ! if (tem & cexc) goto fpop_raise_trap
103 or %g1,%g5,%g4 ! Combine previous aexc and new cexc
104
105 sllx %g1,FSR_CEXC_TO_AEXC_SFT,%g5 ! In case of no trap then cexc gets or'ed with aexc
106 or %g4,%g5,%g1
107 stx %g1,[S_PTR + S_FSR_EXC]
108 ba,a %xcc,fpop_fprs_dd
109
110fpop_fprs_d:
111 andn %g5,FSR_CEXC,%g1 ! clear fsr.cexc as no trap occured
112 stx %g1,[S_PTR + S_FSR_EXC] ! Save fsr_exc for next fpop
113
114fpop_fprs_dd:
115 mov R_NPC,R_PC ! pc = npc
116 add R_NPC,4,R_NPC ! npc = npc + 4
117 ldub [S_PTR + S_FPRS],%g5 ! set fprs.dl and/or fprs.du based on the
118 sub %g3,S_FRF - 32*4,%g4 ! index rd. Convert the rd index to 1 (%f)
119 stx %g2,[S_PTR + S_FSR_RUN] ! Save fsr_run for next fpop
120 srlx %g4,7,%g4 ! or 2 (%d) value and or it with the previous
121 stx R_NPC,[S_PTR + S_NPC]
122 or %g5,%g4,%g5 ! fprs value.
123 std %f8,[S_PTR + %g3] ! Update register file
124 V8_PC
125 retl
126 stb %g5,[S_PTR + S_FPRS] ! Update fprs.dl and fprs.du
127
128
129!============================================================================
130! fpop_retl_d is the tail code for floating point functions that have a single
131! precision result and update %fsr
132! %g3 - rd index
133! %g5 - cpu %gsr to be restored
134! %f8 (%f9) - fpop result
135!============================================================================
136
137.align 8
138
139fpop_retl_f:
140 wr %g5,%gsr ! Restore host %gsr
141
142 stx %fsr,[S_PTR + S_FSR_TMP] ! Grab host's %fsr ... and get instr result
143 ldx [S_PTR + S_FSR_TMP],%g1
144
145 ldx [S_PTR + S_FSR_TEM],%g4 ! Get simulated fsr tem
146 ldx [S_PTR + S_FSR_EXC],%g5 ! Get simulated fsr aexc and cexc
147
148 andn %g1,FSR_AEXC_CEXC,%g2 ! Clear aexc and cexc of fsr_run
149 andcc %g1,FSR_CEXC,%g1 ! Extract cexc, and check if any traps occured
150
151 be %xcc,fpop_fprs_f ! No traps then update fprs and FRF and return
152 ldx [S_PTR + S_FSR_CPU],%fsr ! Load host's %fsr
153
154 andcc %g1,%g4,%g0 ! (tem & cexc) == 0?
155 and %g5,FSR_AEXC,%g5 ! Get previous fsr aexc
156
157 bne %xcc,fpop_trap ! if (tem & cexc) goto fpop_raise_trap
158 or %g1,%g5,%g4 ! Combine previous aexc and new cexc
159
160 sllx %g1,FSR_CEXC_TO_AEXC_SFT,%g5 ! In case of no trap then cexc gets or'ed with aexc
161 or %g4,%g5,%g1
162 stx %g1,[S_PTR + S_FSR_EXC]
163 ba,a %xcc,fpop_fprs_ff
164
165fpop_fprs_f:
166 andn %g5,FSR_CEXC,%g1 ! clear fsr.cexc as no trap occured
167 stx %g1,[S_PTR + S_FSR_EXC] ! Save fsr_exc for next fpop
168
169fpop_fprs_ff:
170 mov R_NPC,R_PC ! pc = npc
171 add R_NPC,4,R_NPC ! npc = npc + 4
172 ldub [S_PTR + S_FPRS],%g5 ! set fprs.dl and/or fprs.du based on the
173 sub %g3,S_FRF - 32*4,%g4 ! index rd. Convert the rd index to 1 (%f)
174 stx %g2,[S_PTR + S_FSR_RUN] ! Save fsr_run for next fpop
175 srlx %g4,7,%g4 ! or 2 (%d) value and or it with the previous
176 stx R_NPC,[S_PTR + S_NPC]
177 or %g5,%g4,%g5 ! fprs value.
178 st %f8,[S_PTR + %g3] ! Update register file
179 V8_PC
180 retl
181 stb %g5,[S_PTR + S_FPRS] ! Update fprs.dl and fprs.du
182
183!============================================================================
184! fpop_retl is the tail code for floating point functions that do
185! not cause and results other then an update of %fsr
186! %g5 - cpu %gsr to be restored
187!============================================================================
188
189fpop_retl:
190 wr %g5,%gsr ! Restore host %gsr
191
192 stx %fsr,[S_PTR + S_FSR_TMP] ! Grab host's %fsr ... and get instr result
193 ldx [S_PTR + S_FSR_TMP],%g1
194
195 ldx [S_PTR + S_FSR_TEM],%g4 ! Get simulated fsr tem
196 ldx [S_PTR + S_FSR_EXC],%g5 ! Get simulated fsr aexc and cexc
197
198 andn %g1,FSR_AEXC_CEXC,%g2 ! Clear aexc and cexc of fsr_run
199 andcc %g1,FSR_CEXC,%g1 ! Extract cexc, and check if any traps occured
200
201 be %xcc,fpop_fprs ! No traps then update fprs and FRF and return
202 ldx [S_PTR + S_FSR_CPU],%fsr ! Load host's %fsr
203
204 andcc %g1,%g4,%g0 ! (tem & cexc) == 0?
205 and %g5,FSR_AEXC,%g5 ! Get previous fsr aexc
206
207 bne %xcc,fpop_trap ! if (tem & cexc) goto fpop_raise_trap
208 or %g1,%g5,%g4 ! Combine previous aexc and new cexc
209
210 sllx %g1,FSR_CEXC_TO_AEXC_SFT,%g5 ! In case of no trap then cexc gets or'ed with aexc
211 or %g4,%g5,%g1
212 stx %g1,[S_PTR + S_FSR_EXC]
213 ba,a %xcc,fpop_fprs_
214
215fpop_fprs:
216 andn %g5,FSR_CEXC,%g1 ! clear fsr.cexc as no trap occured
217 stx %g1,[S_PTR + S_FSR_EXC] ! Save fsr_exc for next fpop
218
219fpop_fprs_:
220 mov R_NPC,R_PC ! pc = npc
221 add R_NPC,4,R_NPC ! npc = npc + 4
222 stx R_NPC,[S_PTR + S_NPC]
223 V8_PC
224 retl
225 stx %g2,[S_PTR + S_FSR_RUN] ! Save fsr_run for next fpop
226
227!============================================================================
228! fpop_trap is the branched to from the fpop_retl functions above in case
229! and FP_EXCEPTION_IEEE_754 trap needs to be thrown.
230!============================================================================
231
232fpop_trap:
233 sethi %hi(FSR_FTT_MSK),%g4 ! Clear old ftt
234 ldptr [S_PTR + TRAP],%g5
235
236 andn %g2,%g4,%g2 ! Clear old ftt
237 sethi %hi(FSR_IEEE_754_EXC),%g4 ! Set ftt to IEEE exception
238 stx %g1,[S_PTR + S_FSR_EXC]
239
240 or %g2,%g4,%g2 ! Set ftt to IEEE exception
241 mov T_FP_EXCEPTION_IEEE_754,%o4
242
243 jmpl %g5,%g0 ! trap(pc,npc,s,i,T_FP_EXCEPTION_IEEE_754)
244 stx %g2,[S_PTR + S_FSR_RUN] ! Save simulated fsr
245
246
247!============================================================================
248! opf_fprs_gsr_d: store double result %f8 in drf[%g3], update fprs, pc and npc
249!============================================================================
250
251.global opf_fprs_gsr_d
252.type opf_fprs_gsr_d, #function
253
254opf_fprs_gsr_d:
255 rd %gsr,%g1
256 sub %g3,S_FRF - 32*4,%g4 ! index rd. Convert the rd index to 1 (%f)
257
258 wr %g5,%gsr ! Restore host %gsr
259 ldub [S_PTR + S_FPRS],%g5 ! set fprs.dl and/or fprs.du based on the
260
261 srlx %g4,7,%g4 ! or 2 (%d) value and or it with the previous
262 std %f8,[S_PTR + %g3] ! Update register file
263
264 mov R_NPC,R_PC ! pc = npc
265 add R_NPC,4,R_NPC ! npc = npc + 4
266
267 stx R_NPC,[S_PTR + S_NPC]
268
269 stx %g1,[S_PTR + S_GSR]
270 or %g5,%g4,%g5 ! fprs value.
271
272 V8_PC
273 retl
274 stb %g5,[S_PTR + S_FPRS] ! Update fprs.dl and fprs.du
275
276!============================================================================
277! opf_fprs_gsr_f: store float result %f8 in frf[%g3], update fprs, pc and npc
278!============================================================================
279
280.global opf_fprs_gsr_f
281.type opf_fprs_gsr_f, #function
282
283opf_fprs_gsr_f:
284 rd %gsr,%g1
285 sub %g3,S_FRF - 32*4,%g4 ! index rd. Convert the rd index to 1 (%f)
286
287 mov R_NPC,R_PC ! pc = npc
288 wr %g5,%gsr ! Restore host %gsr
289 ldub [S_PTR + S_FPRS],%g5 ! set fprs.dl and/or fprs.du based on the
290
291 add R_NPC,4,R_NPC ! npc = npc + 4
292 srlx %g4,7,%g4 ! or 2 (%d) value and or it with the previous
293 st %f8,[S_PTR + %g3] ! Update register file
294
295 stx R_NPC,[S_PTR + S_NPC]
296
297 stx %g1,[S_PTR + S_GSR]
298 or %g5,%g4,%g5 ! fprs value.
299
300 V8_PC
301 retl
302 stb %g5,[S_PTR + S_FPRS] ! Update fprs.dl and fprs.du
303
304!============================================================================
305! opf_fprs_d: store double result %f8 in drf[%g3], update fprs, pc and npc
306!============================================================================
307
308.global opf_fprs_d
309.type opf_fprs_d, #function
310
311opf_fprs_d:
312 mov R_NPC,R_PC ! pc = npc
313 sub %g3,S_FRF - 32*4,%g4 ! index rd. Convert the rd index to 1 (%f)
314 ldub [S_PTR + S_FPRS],%g5 ! set fprs.dl and/or fprs.du based on the
315
316 add R_NPC,4,R_NPC ! npc = npc + 4
317 srlx %g4,7,%g4 ! or 2 (%d) value and or it with the previous
318 std %f8,[S_PTR + %g3] ! Update register file
319
320 stx R_NPC,[S_PTR + S_NPC]
321 or %g5,%g4,%g5 ! fprs value.
322
323 V8_PC
324 retl
325 stb %g5,[S_PTR + S_FPRS] ! Update fprs.dl and fprs.du
326
327!============================================================================
328! opf_fprs_f: store double result %f8 in drf[%g3], update fprs, pc and npc
329!============================================================================
330
331.global opf_fprs_f
332.type opf_fprs_f, #function
333
334opf_fprs_f:
335 mov R_NPC,R_PC ! pc = npc
336 sub %g3,S_FRF - 32*4,%g4 ! index rd. Convert the rd index to 1 (%f)
337 ldub [S_PTR + S_FPRS],%g5 ! set fprs.dl and/or fprs.du based on the
338
339 add R_NPC,4,R_NPC ! npc = npc + 4
340 srlx %g4,7,%g4 ! or 2 (%d) value and or it with the previous
341 st %f8,[S_PTR + %g3] ! Update register file
342
343 stx R_NPC,[S_PTR + S_NPC]
344 or %g5,%g4,%g5 ! fprs value.
345
346 V8_PC
347 retl
348 stb %g5,[S_PTR + S_FPRS] ! Update fprs.dl and fprs.du
349
350#endif