Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / legion / src / procs / sunsparc / common / fpsim_support.s
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: fpsim_support.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/*==========================================================================*
24 *
25 * fpsim_support.s : assembly language routines used by FPSIM libraries.
26 *
27 * Author: Robert Rethemeyer
28 *
29 * (c) Copyright 2006 Sun Microsystems, Inc.
30 *
31 * Design:
32 * This is a collection of functions that explicitly invoke the various
33 * SPARC floating-point instructions, using a supplied rounding mode,
34 * and returning the exception bits extracted from %fsr.cexc.
35 * Each routine is essentially a wrapper around the FP instruction.
36 *
37 * Why do this in assembly and not C? One or more of the following reasons:
38 * 1. No way to do it except using library calls (e.g. fiddling with %fsr)
39 * 2. C does not provide an easy way to do it (e.g. add & get carry)
40 * 3. The compiler may substitute its own code to satisfy the C standard
41 * 4. The compiler does not generate the intended code (e.g. for "D=S*S",
42 * it will generate FMULS followed by FSTOD, instead of FSMULD.
43 *
44 * These are all leaf subroutines that may use/trash registers:
45 * %o0-%o5, %f0-%f3, %g1
46 * Exception bits are returned in %o0
47 * FP result is returned by Store using result pointer parameter.
48 *
49 * $Id: fpsim_support.s,v 1.5 2006/12/07 20:52:05 bobsmail Exp $
50 *
51 *==========================================================================*/
52
53/*********************************************************************
54 * ATTENTION: This code is part of a library shared by multiple
55 * projects. DO NOT MAKE CHANGES TO THIS CODE WITHIN YOUR PROJECT.
56 * Instead, contact the owner/maintainer of the library, currently:
57 * Robert.Rethemeyer@Sun.COM +1-408-616-5717 (x45717)
58 * Systems Group: TVT: FrontEnd Technologies
59 * The CVS source code repository for the library is at:
60 * /import/ftap-blimp1/cvs/fpsim
61 * DO NOT COMMIT CHANGES TO THAT REPOSITORY: contact the maintainer.
62 ********************************************************************/
63
64#define FUNCTION(FNAME) .global FNAME; .type FNAME,#function; FNAME:
65#define ENDFUNC(FNAME) .size FNAME,.-FNAME
66
67/* SET_ROUNDING:
68 1. save current FSR in caller-provided temp area (2 words)
69 2. mask off TEM, NS, CEXC bits
70 3. insert caller's rounding mode bits
71 4. load new FSR
72 5. save current GSR in g1
73 6. clear GSR
74*/
75#define SET_ROUNDING(ROUND,TEMPFSR) \
76 st %fsr, [TEMPFSR+0]; \
77 lduw [TEMPFSR+0], %o5; \
78 set 0x303FFFE0, %g1; \
79 and %o5, %g1, %o5; \
80 sllx ROUND, 30, %g1; \
81 or %o5, %g1, %o5; \
82 rd %gsr, %g1; \
83 stw %o5, [TEMPFSR+4]; \
84 ld [TEMPFSR+4], %fsr; \
85 wr %g0, %g0, %gsr;
86
87/* RESTORE_FSR:
88 1. save updated FSR
89 2. restore previous FSR
90 3. load updated FSR in %o0
91 4. restore previous GSR
92*/
93#define RESTORE_FSR(TEMPFSR) \
94 st %fsr, [TEMPFSR+4]; \
95 lduw [TEMPFSR+4], %o0; \
96 ld [TEMPFSR+0], %fsr; \
97 wr %g1, %g0, %gsr;
98
99
100 .section ".text"
101
102/*==========================================================================*/
103
104! int asm_faddd( double* op1, double* op2, double* rslt, int rnd, int* tmp );
105! %o0 %o0 %o1 %o2 %o3 %o4
106
107FUNCTION(asm_faddd)
108
109 SET_ROUNDING(%o3,%o4)
110 ldd [%o0], %f0
111 ldd [%o1], %f2
112 faddd %f0, %f2, %f4
113 std %f4, [%o2]
114 RESTORE_FSR(%o4)
115 retl
116 and %o0, 0x1F, %o0;
117
118ENDFUNC(asm_faddd)
119
120
121
122/*==========================================================================*/
123
124! int asm_fsubd( double* op1, double* op2, double* rslt, int rnd, int* tmp );
125! %o0 %o0 %o1 %o2 %o3 %o4
126
127FUNCTION(asm_fsubd)
128
129 SET_ROUNDING(%o3,%o4)
130 ldd [%o0], %f0
131 ldd [%o1], %f2
132 fsubd %f0, %f2, %f4
133 std %f4, [%o2]
134 RESTORE_FSR(%o4)
135 retl
136 and %o0, 0x1F, %o0;
137
138ENDFUNC(asm_fsubd)
139
140
141
142/*==========================================================================*/
143
144! int asm_fmuld( double* op1, double* op2, double* rslt, int rnd, int* tmp );
145! %o0 %o0 %o1 %o2 %o3 %o4
146
147FUNCTION(asm_fmuld)
148
149 SET_ROUNDING(%o3,%o4)
150 ldd [%o0], %f0
151 ldd [%o1], %f2
152 fmuld %f0, %f2, %f4
153 std %f4, [%o2]
154 RESTORE_FSR(%o4)
155 retl
156 and %o0, 0x1F, %o0;
157
158ENDFUNC(asm_fmuld)
159
160
161
162/*==========================================================================*/
163
164! int asm_fdivd( double* op1, double* op2, double* rslt, int rnd, int* tmp );
165! %o0 %o0 %o1 %o2 %o3 %o4
166
167FUNCTION(asm_fdivd)
168
169 SET_ROUNDING(%o3,%o4)
170 ldd [%o0], %f0
171 ldd [%o1], %f2
172 fdivd %f0, %f2, %f4
173 std %f4, [%o2]
174 RESTORE_FSR(%o4)
175 retl
176 and %o0, 0x1F, %o0;
177
178ENDFUNC(asm_fdivd)
179
180
181
182/*==========================================================================*/
183
184! int asm_fsqrtd( double* op2, double* rslt, int rnd, int* tmp );
185! %o0 %o0 %o1 %o2 %o3
186
187FUNCTION(asm_fsqrtd)
188
189 SET_ROUNDING(%o2,%o3)
190 ldd [%o0], %f0
191 fsqrtd %f0, %f2
192 std %f2, [%o1]
193 RESTORE_FSR(%o3)
194 retl
195 and %o0, 0x1F, %o0;
196
197ENDFUNC(asm_fsqrtd)
198
199
200
201/*==========================================================================*/
202
203! int asm_fadds( float* op1, float* op2, float* rslt, int rnd, int* tmp );
204! %o0 %o0 %o1 %o2 %o3 %o4
205
206FUNCTION(asm_fadds)
207
208 SET_ROUNDING(%o3,%o4)
209 ld [%o0], %f0
210 ld [%o1], %f1
211 fadds %f0, %f1, %f2
212 st %f2, [%o2]
213 RESTORE_FSR(%o4)
214 retl
215 and %o0, 0x1F, %o0;
216
217ENDFUNC(asm_fadds)
218
219
220
221/*==========================================================================*/
222
223! int asm_fsubs( float* op1, float* op2, float* rslt, int rnd, int* tmp );
224! %o0 %o0 %o1 %o2 %o3 %o4
225
226FUNCTION(asm_fsubs)
227
228 SET_ROUNDING(%o3,%o4)
229 ld [%o0], %f0
230 ld [%o1], %f1
231 fsubs %f0, %f1, %f2
232 st %f2, [%o2]
233 RESTORE_FSR(%o4)
234 retl
235 and %o0, 0x1F, %o0;
236
237ENDFUNC(asm_fsubs)
238
239
240
241/*==========================================================================*/
242
243! int asm_fmuls( float* op1, float* op2, float* rslt, int rnd, int* tmp );
244! %o0 %o0 %o1 %o2 %o3 %o4
245
246FUNCTION(asm_fmuls)
247
248 SET_ROUNDING(%o3,%o4)
249 ld [%o0], %f0
250 ld [%o1], %f1
251 fmuls %f0, %f1, %f2
252 st %f2, [%o2]
253 RESTORE_FSR(%o4)
254 retl
255 and %o0, 0x1F, %o0;
256
257ENDFUNC(asm_fmuls)
258
259
260
261/*==========================================================================*/
262
263! int asm_fdivs( float* op1, float* op2, float* rslt, int rnd, int* tmp )
264! %o0 %o0 %o1 %o2 %o3 %o4
265
266FUNCTION(asm_fdivs)
267
268 SET_ROUNDING(%o3,%o4)
269 ld [%o0], %f0
270 ld [%o1], %f1
271 fdivs %f0, %f1, %f2
272 st %f2, [%o2]
273 RESTORE_FSR(%o4)
274 retl
275 and %o0, 0x1F, %o0;
276
277ENDFUNC(asm_fdivs)
278
279
280
281/*==========================================================================*/
282
283! int asm_fsqrts( float* op2, float* rslt, int rnd, int* tmp );
284! %o0 %o0 %o1 %o2 %o3
285
286FUNCTION(asm_fsqrts)
287
288 SET_ROUNDING(%o2,%o3)
289 ld [%o0], %f0
290 fsqrts %f0, %f1
291 st %f1, [%o1]
292 RESTORE_FSR(%o3)
293 retl
294 and %o0, 0x1F, %o0;
295
296ENDFUNC(asm_fsqrts)
297
298
299
300/*==========================================================================*/
301
302! int asm_fsmuld( float* op1, float* op2, double* rslt, int* tmp );
303! %o0 %o0 %o1 %o2 %o3
304
305FUNCTION(asm_fsmuld)
306
307 SET_ROUNDING(%g0,%o3)
308 ld [%o0], %f0
309 ld [%o1], %f1
310 fsmuld %f0, %f1, %f2
311 std %f2, [%o2]
312 RESTORE_FSR(%o3)
313 retl
314 and %o0, 0x1F, %o0;
315
316ENDFUNC(asm_fsmuld)
317
318
319
320/*==========================================================================*/
321
322! int asm_fstod( float* op2, double* rslt, int rnd, int* tmp );
323! %o0 %o0 %o1 %o2 %o3
324
325FUNCTION(asm_fstod)
326
327 SET_ROUNDING(%o2,%o3)
328 ld [%o0], %f0
329 fstod %f0, %f2
330 std %f2, [%o1]
331 RESTORE_FSR(%o3)
332 retl
333 and %o0, 0x1F, %o0;
334
335ENDFUNC(asm_fstod)
336
337
338
339/*==========================================================================*/
340
341! int asm_fdtos( double* op2, float* rslt, int rnd, int* tmp );
342! %o0 %o0 %o1 %o2 %o3
343
344FUNCTION(asm_fdtos)
345
346 SET_ROUNDING(%o2,%o3)
347 ldd [%o0], %f0
348 fdtos %f0, %f2
349 st %f2, [%o1]
350 RESTORE_FSR(%o3)
351 retl
352 and %o0, 0x1F, %o0;
353
354ENDFUNC(asm_fdtos)
355
356
357
358/*==========================================================================*/
359
360! int asm_fstox( float* op2, uint64* rslt, int rnd, int* tmp );
361! %o0 %o0 %o1 %o2 %o3
362
363FUNCTION(asm_fstox)
364
365 SET_ROUNDING(%o2,%o3)
366 ld [%o0], %f0
367 fstox %f0, %f2
368 std %f2, [%o1]
369 RESTORE_FSR(%o3)
370 retl
371 and %o0, 0x1F, %o0;
372
373ENDFUNC(asm_fstox)
374
375
376
377/*==========================================================================*/
378
379! int asm_fdtox( double* op2, uint64* rslt, int rnd, int* tmp );
380! %o0 %o0 %o1 %o2 %o3
381
382FUNCTION(asm_fdtox)
383
384 SET_ROUNDING(%o2,%o3)
385 ldd [%o0], %f0
386 fdtox %f0, %f2
387 std %f2, [%o1]
388 RESTORE_FSR(%o3)
389 retl
390 and %o0, 0x1F, %o0;
391
392ENDFUNC(asm_fdtox)
393
394
395
396/*==========================================================================*/
397
398! int asm_fstoi( float* op2, uint* rslt, int rnd, int* tmp );
399! %o0 %o0 %o1 %o2 %o3
400
401FUNCTION(asm_fstoi)
402
403 SET_ROUNDING(%o2,%o3)
404 ld [%o0], %f0
405 fstoi %f0, %f1
406 st %f1, [%o1]
407 RESTORE_FSR(%o3)
408 retl
409 and %o0, 0x1F, %o0;
410
411ENDFUNC(asm_fstoi)
412
413
414
415/*==========================================================================*/
416
417! int asm_fdtoi( double* op2, uint* rslt, int rnd, int* tmp );
418! %o0 %o0 %o1 %o2 %o3
419
420FUNCTION(asm_fdtoi)
421
422 SET_ROUNDING(%o2,%o3)
423 ldd [%o0], %f0
424 fdtoi %f0, %f2
425 st %f2, [%o1]
426 RESTORE_FSR(%o3)
427 retl
428 and %o0, 0x1F, %o0;
429
430ENDFUNC(asm_fdtoi)
431
432
433
434/*==========================================================================*/
435
436! int asm_fxtos( uint64* op2, float* rslt, int rnd, int* tmp );
437! %o0 %o0 %o1 %o2 %o3
438
439FUNCTION(asm_fxtos)
440
441 SET_ROUNDING(%o2,%o3)
442 ldd [%o0], %f0
443 fxtos %f0, %f2
444 st %f2, [%o1]
445 RESTORE_FSR(%o3)
446 retl
447 and %o0, 0x1F, %o0;
448
449ENDFUNC(asm_fxtos)
450
451
452
453/*==========================================================================*/
454
455! int asm_fxtod( uint64* op2, double* rslt, int rnd, int* tmp );
456! %o0 %o0 %o1 %o2 %o3
457
458FUNCTION(asm_fxtod)
459
460 SET_ROUNDING(%o2,%o3)
461 ldd [%o0], %f0
462 fxtod %f0, %f2
463 std %f2, [%o1]
464 RESTORE_FSR(%o3)
465 retl
466 and %o0, 0x1F, %o0;
467
468ENDFUNC(asm_fxtod)
469
470
471
472/*==========================================================================*/
473
474! int asm_fitos( uint* op2, float* rslt, int rnd, int* tmp );
475! %o0 %o0 %o1 %o2 %o3
476
477FUNCTION(asm_fitos)
478
479 SET_ROUNDING(%o2,%o3)
480 ld [%o0], %f0
481 fitos %f0, %f1
482 st %f1, [%o1]
483 RESTORE_FSR(%o3)
484 retl
485 and %o0, 0x1F, %o0;
486
487ENDFUNC(asm_fitos)
488
489
490
491/*==========================================================================*/
492
493! void asm_fitod( uint* op2, double* rslt );
494! %o0 %o1
495
496FUNCTION(asm_fitod)
497
498 ld [%o0], %f1
499 fitod %f1, %f2
500 retl
501 std %f2, [%o1]
502
503ENDFUNC(asm_fitod)
504
505
506
507/*==========================================================================*/
508
509! Add 2 integers and return carry-out:
510! int asm_addc( uint64 op1, uint64 op2, uint64* res );
511! %o0 %o0 %o1 %o2
512
513FUNCTION(asm_addc)
514
515 addcc %o0, %o1, %o3 ! add
516 clr %o0 ! carry = 0
517 stx %o3, [%o2]
518 retl
519 movcs %xcc, 1, %o0 ! get carry-out
520
521ENDFUNC(asm_addc)
522
523
524
525
526/*==========================================================================*/
527
528! Subtract 2 integers and return borrow-out:
529! int asm_subc( uint64 op1, uint64 op2, uint64* res );
530! %o0 %o0 %o1 %o2
531
532FUNCTION(asm_subc)
533
534 subcc %o0, %o1, %o3 ! sub
535 clr %o0 ! borrow = 0
536 stx %o3, [%o2]
537 retl
538 movcs %xcc, 1, %o0 ! get borrow-out
539
540ENDFUNC(asm_subc)
541