Home | History | Annotate | Download | only in fptest
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28 
     29 /*
     30  * Usage of %ncc
     31  *
     32  * When the branch instructions were modified from Bicc to BPcc format,
     33  * the pseudo-op %ncc was used. This will be converted by the assembler
     34  * to %icc or %xcc depending on whether the compilation is being done
     35  * for 32-bit or 64-bit platforms.
     36  */
     37 
     38 
     39 #include<sys/asm_linkage.h>
     40 
     41 /*
     42  * ------------------------------------------------------------------------
     43  *  Name:        datap_add()
     44  * Function:	This routine test the data path of the adder for single
     45  * 		precision.
     46  * Calling:	i0 = value
     47  * Returns:
     48  * Convention:
     49  * --------------------------------------------------------------------------
     50  *
     51  *		f0 = value
     52  *		f1 = 0
     53  *	add =   f2 = value
     54  */
     55 
     56 #ifdef __lint
     57 
     58 /*ARGSUSED*/
     59 unsigned long
     60 datap_add(unsigned long arg1)
     61 {
     62 	return (0);
     63 }
     64 
     65 #else
     66 
     67 .section        ".data"
     68 .align  4
     69 
     70 .Ldadd:
     71         .skip   4
     72 .Ldadd1:
     73         .skip   4
     74 
     75 ENTRY_NP(datap_add)
     76 	save    %sp, -SA(MINFRAME), %sp	! save the stack frame
     77 	setn	.Ldadd,%l6,%l0	! get a memory address
     78 	setn    .Ldadd1,%l6,%l1 ! .. one for the result
     79 	mov     %g0,%l3         ! .. get a zero
     80 	st      %l3, [%l1]      ! .... and store it in memory
     81 	st	%i0, [%l0]	! .... store the value passed
     82 	ld	[%l0], %f0	! .... put the passed value into f0
     83 	ld	[%l1], %f1	! .... put value 0 into reg f1
     84 	fadds   %f0, %f1, %f2   ! ...... add zero and value into f2
     85 	fcmps	%fcc0, %f0, %f2	! .... check the value passed and added value
     86 	fbe,a	%fcc0, datap_ok	! .. if they are equal
     87 	nop			! .... delay
     88 
     89 	st	%f2, [%l1]	! return the result on error
     90 
     91 datap_ok:
     92 	ld	[%l1], %i0	! then return a zero
     93 	ret			! .... delay
     94 	restore
     95 SET_SIZE(datap_add)
     96 
     97 #endif
     98 
     99 /*
    100  * ------------------------------------------------------------------------
    101  * Name:
    102  * Function:
    103  * Calling:
    104  * Returns:
    105  * Convention:
    106  * --------------------------------------------------------------------------
    107  *
    108  * This routine test the data path of multiplier for single precision
    109  *             f0 = value
    110  *             f1 = 1
    111  *     mult =  f2 = f0 * f1
    112  */
    113 
    114 #ifdef __lint
    115 
    116 /*ARGSUSED*/
    117 unsigned long
    118 datap_mult(unsigned long arg1)
    119 {
    120 	return (0);
    121 }
    122 
    123 #else
    124 
    125 .section        ".data"
    126 .align  4
    127 
    128 .Ldtmlt:
    129         .skip   4
    130 .Ldtmlt1:
    131         .skip   4
    132 
    133 ENTRY_NP(datap_mult)
    134 	save    %sp, -SA(MINFRAME), %sp
    135         setn    .Ldtmlt,%l6,%l0
    136         setn    .Ldtmlt1,%l6,%l1
    137         setn    0x3F800000,%l6,%l3      ! put value 1 into memory
    138 	st      %l3, [%l1]
    139         st      %i0, [%l0]      ! store the value passed into memory location
    140         ld      [%l0], %f0      ! put the passed value into f0
    141         ld      [%l1], %f1      ! put value 1 into reg f1
    142         fmuls   %f0, %f1, %f2	! multiply value with 1 , it has to be same
    143 	fcmps   %fcc0, %f0, %f2
    144 
    145 	fbne,a	%fcc0, datap_mult_done
    146 	st	%f2, [%l1]	! executed only when the conditional
    147 				! branch is taken as annul bit is set.
    148 				! This branch will be taken under
    149 				! an error condition (%f0 != %f2).
    150 				! Then we need to return the result.
    151 
    152 	mov	%g0,%l3
    153 	st	%l3, [%l1]
    154 
    155 datap_mult_done :
    156 	ld	[%l1], %i0
    157 	ret
    158 	restore
    159 SET_SIZE(datap_mult)
    160 
    161 #endif
    162 
    163 /*
    164  * ------------------------------------------------------------------------
    165  * Name:
    166  * Function:
    167  * Calling:
    168  * Returns:
    169  * Convention:
    170  * --------------------------------------------------------------------------
    171  *
    172  *	This routine tests the data path of the weitek multiplier for
    173  *	double precision. Single-precision load and store are being
    174  *      used as the input double-precision value is taken as two SP
    175  *      arguments
    176  *
    177  *              f0 = msw value
    178  *		f1 = lsw value
    179  *
    180  *		f2 = 0
    181  *		f3 = 0
    182  *	add =   f4 = f0 + f2
    183  */
    184 
    185 #ifdef __lint
    186 
    187 /*ARGSUSED*/
    188 unsigned long
    189 datap_add_dp(unsigned long arg1, unsigned long arg2)
    190 {
    191 	return (0);
    192 }
    193 
    194 #else
    195 
    196 .section        ".data"
    197 .align  8
    198 
    199 .Ldtadddp:
    200         .skip   8
    201 .Ldtadddp1:
    202         .skip   8
    203 .Ldtadddp2:
    204         .skip   8
    205 .Lamsw:
    206         .skip   8
    207 .Lalsw:
    208         .skip   8
    209 
    210 ENTRY_NP(datap_add_dp)
    211 	save    %sp, -SA(MINFRAME), %sp
    212         setn    .Ldtadddp,%l6,%l0
    213         setn    .Ldtadddp1,%l6,%l1
    214 	setn	.Ldtadddp2,%l6,%l2
    215 	setn	.Lamsw,%l6,%l4
    216 	setn	.Lalsw,%l6,%l5
    217 	mov	%g0,%l3	! put value 0 into memory
    218         st      %l3, [%l1]
    219 	st	%i0, [%l0]	! msw of value
    220         st	%i1, [%l2]	! lsw of value
    221 	ld	[%l0], %f0	! put the msw into f0
    222 	ld	[%l2], %f1	! put the lsw into f1
    223 	ld	[%l1], %f2	! put 0 into f2
    224 	ld	[%l1], %f3	! put 0 into f3
    225 	faddd   %f0, %f2, %f4	! add value + 0 into f4
    226 	fcmpd   %fcc0, %f0, %f4	! now compare the result
    227 
    228 	fbe,a	%fcc0, datap_add_dp_ok	! good
    229 	nop
    230 
    231 	mov	0x1,%l3
    232 	st	%l3, [%l1]
    233 
    234 datap_add_dp_ok :
    235 	ld	[%l1], %i0
    236 	ret
    237 	restore
    238 
    239 SET_SIZE(datap_add_dp)
    240 
    241 #endif
    242 
    243 /*
    244  * ------------------------------------------------------------------------
    245  * Name:
    246  * Function:
    247  * Calling:
    248  * Returns:
    249  * Convention:
    250  *
    251  * This routine tests the data path of the weitek multiplier for
    252  * double precision. Single-precision load and store are being
    253  * used as the input double-precision value is taken as two SP
    254  * arguments.
    255  *
    256  *             f0 = msw value
    257  *             f1 = lsw value
    258  *             f2 = 0
    259  *             f3 = 0
    260  *	mult = f4 = f0 * f2
    261  * ------------------------------------------------------------------------
    262  */
    263 
    264 #ifdef __lint
    265 
    266 /*ARGSUSED*/
    267 unsigned long
    268 datap_mult_dp(unsigned long arg1, unsigned long arg2)
    269 {
    270 	return (0);
    271 }
    272 
    273 #else
    274 
    275 .section        ".data"
    276 .align  8
    277 
    278 .Ldtmdp:
    279         .skip   8
    280 .Ldtmdp1:
    281         .skip   8
    282 .Ldtmdp2:
    283         .skip   8
    284 .Lmmsw:
    285         .skip   8
    286 .Lmlsw:
    287         .skip   8
    288 
    289 ENTRY_NP(datap_mult_dp)
    290 	save    %sp, -SA(MINFRAME), %sp
    291         setn    .Ldtmdp,%l6,%l0
    292         setn    .Ldtmdp1,%l6,%l1
    293         setn    .Ldtmdp2,%l6,%l2
    294         setn    .Lmmsw,%l6,%l4
    295 	setn	.Lmlsw,%l6,%l5
    296         setn    0x3FF00000,%l6,%l3 ! put msw value  of DP 1  into memory
    297         st      %l3, [%l1]
    298         st      %i0, [%l0]      ! msw of value
    299         st      %i1, [%l2]      ! lsw of value
    300         ld      [%l0], %f0      ! put the msw into f0
    301         ld      [%l2], %f1      ! put the lsw into f1
    302         ld      [%l1], %f2      ! put msw of DP 1 into f2
    303 	mov	%g0,%l3
    304 	st	%l3, [%l1]
    305         ld      [%l1], %f3	! put 0 into f3, i.e f2|f3 = 0x3ff0000000000000 (dp 1)
    306 	fmuld	%f0, %f2, %f4   ! mult value * 1 into f4
    307 	fcmpd   %fcc0, %f0, %f4	! now compare the result
    308 
    309         fbe,a     %fcc0, datap_mult_dp_ok        ! good
    310 	nop
    311 
    312         mov     0x1,%l3
    313         st      %l3, [%l1]
    314 
    315 datap_mult_dp_ok :
    316 	ld	[%l1], %i0
    317 	ret
    318 	restore
    319 
    320 SET_SIZE(datap_mult_dp)
    321 
    322 #endif
    323 
    324 /*
    325  * -------------------------------------------------------------------------
    326  * for add routine all the f registers from 0 - 19 will be filled with numbers
    327  * and the result should be 10.
    328  * -------------------------------------------------------------------------
    329  */
    330 
    331 #ifdef __lint
    332 
    333 unsigned long
    334 timing_add_sp()
    335 {
    336 	return (0);
    337 }
    338 
    339 #else
    340 
    341 .section        ".data"
    342 .align  4
    343 
    344 .Ltmasp:
    345         .skip   4
    346 .Ltmasp1:
    347         .skip   4
    348 .Ltmasp2:
    349         .skip   4
    350 
    351 ENTRY_NP(timing_add_sp)
    352 	save    %sp, -SA(MINFRAME), %sp		! save the registers, stacck
    353         setn    .Ltmasp,%l6,%l0
    354 	setn	.Ltmasp1,%l6,%l1
    355 	setn	.Ltmasp2,%l6,%l2
    356 	mov	%g0,%l3
    357 	setn    0x3f800000,%l6,%l4 	! put value 1
    358 	setn	0x41200000,%l6,%l5		! put value 10 into local 5
    359 	st	%l5, [%l0]
    360 	st	%l4, [%l1]
    361 	st	%l3, [%l2]
    362 	ld	[%l0], %f31		! register 31 has 10
    363 	ld	[%l1], %f30		! register 30 has 1
    364 
    365 	ld	[%l2], %f0		! reg 0 has 0
    366 	fmovs   %f31, %f1		! reg1 has 10
    367 	fsubs   %f31, %f30, %f18	! reg 18 has 9
    368 	fmovs   %f18, %f3		! reg 3 has 9
    369 	fmovs   %f30, %f2		! reg 2 has 1
    370 	fmovs   %f30, %f19		! reg 19 has 1
    371 	fsubs   %f18, %f19, %f16	! reg 16 has 8
    372 	fmovs   %f16, %f5		! reg 5 has 8
    373 	fsubs   %f31, %f16, %f17	! reg 17 has 2
    374 	fmovs	%f17, %f4		! reg 4 has 2
    375 	fsubs   %f16, %f30, %f14	! reg 14 has 7
    376 	fmovs   %f14, %f7		! reg 7 has 7
    377 	fsubs   %f31, %f14, %f15	! reg 15 has 3
    378 	fmovs	%f15, %f6		! reg 6 has 3
    379 	fsubs   %f14, %f30, %f12	! reg 12 has 6
    380 	fmovs	%f12, %f9		! reg 9 has 6
    381 	fsubs   %f31, %f12, %f13	! reg 13 has 4
    382 	fmovs	%f13, %f8		! reg 8 has 4
    383 	fsubs   %f12, %f30, %f10	! reg 10 has 5
    384 	fmovs	%f10, %f11		! reg 11 has 5
    385 
    386 	fadds	%f0, %f1, %f20		! reg 0 + reg 1 = reg 20 = 10
    387 	fadds   %f2, %f3, %f21		! reg 2 + reg 3 = reg 21 = 10
    388 	fadds   %f4, %f5, %f22		! reg 4 + reg 5 = reg 22 = 10
    389 	fadds   %f6, %f7, %f23		! reg 6 + reg 7 = reg 23 = 10
    390 	fadds   %f8, %f9, %f24		! reg 8 + reg 9 = reg 24 = 10
    391 	fadds   %f10, %f11, %f25	! reg 10 + reg 11 = reg 25 = 10
    392 	fadds   %f12, %f13, %f26	! reg 12 + reg 13 = reg 26 = 10
    393 	fadds   %f14, %f15, %f27	! reg 14 + reg 15 = reg 27 = 10
    394 	fadds   %f16, %f17, %f28	! reg 16 + reg 17 = reg 28 = 10
    395 	fadds   %f18, %f19, %f29	! reg 18 + reg 19 = reg 29 = 10
    396 
    397 	!  Now additions are done check it out
    398 	fcmps	%fcc0, %f31, %f20
    399 	fbne,a,pn	%fcc0, done_t_add_sp	! If not equal, go to the end.
    400 	st	%f20, [%l2] 	! Executed only when the conditional
    401 				! branch is taken as annul bit is set.
    402 				! This branch will be taken under
    403 				! an error condition.
    404 
    405 	! No errors. Move on to the next register
    406 
    407 	fcmps	%fcc0, %f31, %f21
    408 	fbne,a,pn	%fcc0, done_t_add_sp
    409 	st	%f21, [%l2]
    410 
    411 
    412 	fcmps   %fcc0, %f31, %f22
    413 	fbne,a,pn	%fcc0, done_t_add_sp
    414 	st	%f22, [%l2]
    415 
    416 
    417 	fcmps	%fcc0, %f31, %f23
    418 	fbne,a,pn	%fcc0, done_t_add_sp
    419         st      %f23, [%l2]
    420 
    421 
    422         fcmps   %fcc0, %f31, %f24
    423         fbne,a,pn	%fcc0, done_t_add_sp
    424         st      %f24, [%l2]
    425 
    426 
    427         fcmps   %fcc0, %f31, %f25
    428         fbne,a,pn	%fcc0, done_t_add_sp
    429         st      %f25, [%l2]
    430 
    431 
    432         fcmps   %fcc0, %f31, %f26
    433         fbne,a,pn	%fcc0, done_t_add_sp
    434         st      %f26, [%l2]
    435 
    436 
    437         fcmps   %fcc0, %f31, %f27
    438         fbne,a,pn	%fcc0, done_t_add_sp
    439         st      %f27, [%l2]
    440 
    441 
    442         fcmps   %fcc0, %f31, %f28
    443         fbne,a,pn	%fcc0, done_t_add_sp
    444         st      %f28, [%l2]
    445 
    446 
    447 	! Though this is the last set of compare instructions
    448 	! we cannot fall through as the store needs to be done
    449 	! only when the registers are not equal. That is why
    450 	! we need the unconditional branch with the annul bit set.
    451         fcmps   %fcc0, %f31, %f29
    452         fbne,a,pn	%fcc0, done_t_add_sp
    453 	st	%f29, [%l2]
    454 
    455 done_t_add_sp:
    456 	ld	[%l2], %i0
    457 	ret
    458         restore
    459 SET_SIZE(timing_add_sp)
    460 
    461 #endif
    462 
    463 /*
    464  * ----------------------------------------------------------------------
    465  *	for mult routine all the f registers from 0 - 19 will be filled
    466  *	with numbers and the result should be the number.
    467  * ----------------------------------------------------------------------
    468  */
    469 
    470 
    471 #ifdef __lint
    472 
    473 unsigned long
    474 timing_mult_sp()
    475 {
    476 	return (0);
    477 }
    478 
    479 #else
    480 
    481 .section        ".data"
    482 .align  4
    483 
    484 .Ltmmsp:
    485         .skip   4
    486 .Ltmmsp1:
    487         .skip   4
    488 .Ltmmsp2:
    489         .skip   4
    490 
    491 ENTRY_NP(timing_mult_sp)
    492 	save    %sp, -SA(MINFRAME), %sp           ! save the registers, stacck
    493         setn    .Ltmmsp,%l6, %l0
    494         setn    .Ltmmsp1,%l6, %l1
    495         setn    .Ltmmsp2,%l6, %l2
    496         mov     %g0, %l3
    497 	setn	0x3f800000,%l6, %l4         ! put value 1
    498         setn    0x41200000,%l6, %l5         ! put value 10 into local 5
    499         st      %l5, [%l0]
    500         st      %l4, [%l1]
    501         st      %l3, [%l2]
    502         ld      [%l0], %f31             ! register 31 has 10
    503         ld      [%l1], %f1              ! register 1 has 1
    504 	fmovs   %f1, %f3
    505 	fmovs   %f1, %f5
    506 	fmovs   %f1, %f7
    507 	fmovs   %f1, %f9
    508 	fmovs   %f1, %f11	! register 1, 3, 5, 7, 9, 11, 13, 15, 17, 19
    509 	fmovs   %f1, %f13	! has a value of 1
    510 	fmovs   %f1, %f15
    511 	fmovs   %f1, %f17
    512 	fmovs   %f1, %f19	!
    513 	fmovs	%f1, %f0
    514 	fmovs   %f31, %f18	! reg 18 has 10
    515 	fsubs	%f31, %f0, %f16		! reg 16  has 9
    516 	fsubs   %f16, %f0, %f14		! reg 14 has 8
    517 	fsubs   %f14, %f0, %f12		! reg 12 has 7
    518 	fsubs   %f12, %f0, %f10		! reg 10 has 6
    519 	fsubs   %f10, %f0, %f8		! reg 8 has 5
    520 	fsubs   %f8, %f0, %f6		! reg 6 has 4
    521 	fsubs   %f6, %f0, %f4		! reg 4 has 3
    522 	fsubs   %f4, %f0, %f2		! reg 2 has 2
    523 
    524 	fmuls   %f0, %f1, %f20          ! reg 0 * reg 1 = reg 20 = 1
    525         fmuls   %f2, %f3, %f21          ! reg 2 * reg 3 = reg 21 = 2
    526         fmuls   %f4, %f5, %f22          ! reg 4 * reg 5 = reg 22 = 3
    527         fmuls   %f6, %f7, %f23          ! reg 6 * reg 7 = reg 23 = 4
    528         fmuls   %f8, %f9, %f24          ! reg 8 * reg 9 = reg 24 = 5
    529         fmuls   %f10, %f11, %f25        ! reg 10 * reg 11 = reg 25 = 6
    530         fmuls   %f12, %f13, %f26        ! reg 12 * reg 13 = reg 26 = 7
    531         fmuls   %f14, %f15, %f27        ! reg 14 * reg 15 = reg 27 = 8
    532         fmuls   %f16, %f17, %f28        ! reg 16 * reg 17 = reg 28 = 9
    533         fmuls   %f18, %f19, %f29        ! reg 18 * reg 19 = reg 29 = 10
    534 
    535 	fcmps	%fcc0, %f0, %f20
    536 	fbne,a,pn	%fcc0, done_t_mult_sp
    537 	st	%f20, [%l2] 	! Executed only when the conditional
    538 				! branch is taken as annul bit is set.
    539 				! This branch will be taken under
    540 				! an error condition.
    541 
    542 	! No errors. Move on to the next register
    543 
    544 	fcmps	%fcc0, %f2, %f21
    545 	fbne,a,pn	%fcc0, done_t_mult_sp
    546 	st	%f21, [%l2]
    547 
    548 
    549 	fcmps   %fcc0, %f4, %f22
    550 	fbne,a,pn 	%fcc0, done_t_mult_sp
    551 	st	%f22, [%l2]
    552 
    553 
    554 	fcmps	%fcc0, %f6, %f23
    555 	fbne,a,pn	%fcc0, done_t_mult_sp
    556         st      %f23, [%l2]
    557 
    558 
    559 	fcmps	%fcc0, %f8, %f24
    560 	fbne,a,pn	%fcc0, done_t_mult_sp
    561         st      %f24, [%l2]
    562 
    563 
    564 	fcmps	%fcc0, %f10, %f25
    565 	fbne,a,pn	%fcc0, done_t_mult_sp
    566         st      %f25, [%l2]
    567 
    568 
    569 	fcmps	%fcc0, %f12, %f26
    570 	fbne,a,pn	%fcc0, done_t_mult_sp
    571         st      %f26, [%l2]
    572 
    573 
    574 	fcmps	%fcc0, %f14, %f27
    575 	fbne,a,pn	%fcc0, done_t_mult_sp
    576         st      %f27, [%l2]
    577 
    578 
    579 	fcmps	%fcc0, %f16, %f28
    580 	fbne,a,pn	%fcc0, done_t_mult_sp
    581         st      %f28, [%l2]
    582 
    583 
    584 	! Though this is the last set of compare instructions
    585 	! we cannot fall through as the store needs to be done
    586 	! only when the registers are not equal. That is why
    587 	! we need the unconditional branch with the annul bit set.
    588 	fcmps	%fcc0, %f18, %f29
    589 	fbne,a,pn	%fcc0, done_t_mult_sp
    590 	st	%f29, [%l2]
    591 
    592 
    593 done_t_mult_sp:
    594 	ld	[%l2], %i0
    595 	ret
    596         restore
    597 SET_SIZE(timing_mult_sp)
    598 
    599 #endif
    600 
    601 /*
    602  * ----------------------------------------------------------------
    603  *	same thing for double precision
    604  * ----------------------------------------------------------------
    605  */
    606 
    607 #ifdef __lint
    608 
    609 uint64_t
    610 timing_add_dp()
    611 {
    612 	return (0);
    613 }
    614 
    615 #else
    616 
    617 .section        ".data"
    618 .align  8
    619 
    620 .Ltmadp:
    621         .skip   8
    622 .Ltmadp1:
    623         .skip   8
    624 .Ltmadp2:
    625         .skip   8
    626 
    627 ENTRY_NP(timing_add_dp)
    628 	save    %sp, -SA(MINFRAME), %sp           ! save the registers, stacck
    629         setn    .Ltmadp,%l6, %l0
    630         setn    .Ltmadp1,%l6, %l1
    631         setn    .Ltmadp2,%l6, %l2
    632         mov     %g0, %l3
    633 	setn	0x3ff0000000000000,%l6, %l4         ! put value 1
    634         setn    0x4024000000000000,%l6, %l5         ! put value 10 into local 5
    635         stx     %l5, [%l0]
    636         stx     %l4, [%l1]
    637         stx     %l3, [%l2]
    638 	ldd	[%l0], %f30             ! register 30 has 10
    639 	fmovd   %f30, %f2		! reg 2 has 10
    640 	ldd	[%l2], %f0		! reg 0 has 0
    641 	ldd	[%l1], %f4		! reg 4 has 1
    642 	fsubd	%f30, %f4, %f6		! reg 6 has 9
    643 	fsubd	%f6, %f4, %f10		! reg 10 has 8
    644 	fsubd   %f30, %f10, %f8		! reg 8 has 2
    645 	fsubd	%f10, %f4, %f14		! reg 14 has 7
    646 	fsubd   %f30, %f14, %f12	! reg 12 has 3
    647 	fsubd	%f14, %f4, %f18		! reg 18 has 6
    648 	fsubd	%f30, %f18, %f16	! reg 16 has 4
    649 !
    650 	faddd	%f0, %f2, %f20		! reg 20 has 10
    651 	faddd   %f4, %f6, %f22		! reg 22 has 10
    652 	faddd   %f8, %f10, %f24		! reg 24 has 10
    653 	faddd   %f12, %f14, %f26	! reg 26 has 10
    654 	faddd   %f16, %f18, %f28	! reg 28 has 10
    655 !
    656 	fcmpd	%fcc0, %f30, %f20
    657 	fbne,a,pn	%fcc0, done_t_add_dp
    658 	std	%f20, [%l2]
    659 
    660 	fcmpd	%fcc0, %f30, %f22
    661 	fbne,a,pn	%fcc0, done_t_add_dp
    662 	std	%f22, [%l2]
    663 
    664 	fcmpd   %fcc0, %f30, %f24
    665         fbne,a,pn     %fcc0, done_t_add_dp
    666         std      %f24, [%l2]
    667 
    668         fcmpd   %fcc0, %f30, %f26
    669         fbne,a,pn     %fcc0, done_t_add_dp
    670         std      %f26, [%l2]
    671 
    672 	! Though this is the last set of compare instructions
    673 	! we cannot fall through as the store needs to be done
    674 	! only when the registers are not equal. That is why
    675 	! we need the unconditional branch with the annul bit set.
    676 	fcmpd	%fcc0, %f30, %f28
    677 	fbne,a	%fcc0, done_t_add_dp
    678 	std	%f28, [%l2]
    679 
    680 done_t_add_dp:
    681 	ldx	[%l2], %i0
    682 
    683 	ret
    684 	restore
    685 SET_SIZE(timing_add_dp)
    686 
    687 #endif
    688 
    689 /*
    690  * -------------------------------------------------------------------
    691  *	Now for mult
    692  * -------------------------------------------------------------------
    693  */
    694 
    695 #ifdef __lint
    696 
    697 uint64_t
    698 timing_mult_dp()
    699 {
    700 	return (0);
    701 }
    702 
    703 #else
    704 
    705 .section        ".data"
    706 .align  8
    707 
    708 .Ltmmdp:
    709         .skip   8
    710 .Ltmmdp1:
    711         .skip   8
    712 .Ltmmdp2:
    713         .skip   8
    714 
    715 ENTRY_NP(timing_mult_dp)
    716 	save    %sp, -SA(MINFRAME), %sp           ! save the registers, stacck
    717         setn    .Ltmmdp,%l6, %l0
    718         setn    .Ltmmdp1,%l6, %l1
    719         setn    .Ltmmdp2,%l6, %l2
    720         mov     %g0, %l3
    721         setn    0x3ff0000000000000,%l6, %l4         ! put value 1
    722         setn    0x4034000000000000,%l6, %l5         ! put value 20 into local 5
    723         stx      %l5, [%l0]
    724         stx      %l4, [%l1]
    725         stx      %l3, [%l2]
    726 	ldd      [%l0], %f30             ! register 30 has 20
    727 	ldd	[%l1], %f2		! register  2 has 1
    728 	fmovd   %f30, %f0		! register  0 has 20
    729 	faddd	%f2, %f2, %f10		! register 10 has 2
    730 	fmovd   %f10, %f16		! register 16 has 2
    731 	faddd	%f10, %f16, %f4		! register 4 has 4
    732 	faddd   %f4, %f2, %f6		! register 6 has 5
    733 	fmovd	%f6, %f12		! reg. 12 has 5
    734 	fmovd	%f4, %f14		! reg 14 has 4
    735 	faddd	%f12, %f6, %f18		! reg 18 has 10
    736 	fmovd	%f18, %f8		! reg 8 has 10
    737 !
    738 ! 	now everything is set
    739 !
    740 	fmuld   %f0, %f2, %f20          ! reg 20 has 20
    741 	fmuld	%f4, %f6, %f22          ! reg 22 has 20
    742 	fmuld	%f8, %f10, %f24         ! reg 24 has 20
    743 	fmuld	%f12, %f14, %f26        ! reg 26 has 20
    744 	fmuld	%f16, %f18, %f28        ! reg 28 has 20
    745 !
    746 	fcmpd   %fcc0, %f30, %f20
    747 	fbne,a,pn	%fcc0, done_t_mult_dp
    748         std      %f20, [%l2]
    749 
    750 	fcmpd   %fcc0, %f30, %f22
    751         fbne,a,pn     %fcc0, done_t_mult_dp
    752         std      %f22, [%l2]
    753 
    754 	fcmpd   %fcc0, %f30, %f24
    755         fbne,a,pn     %fcc0, done_t_mult_dp
    756         std      %f24, [%l2]
    757 
    758         fcmpd   %fcc0, %f30, %f26
    759         fbne,a,pn     %fcc0, done_t_mult_dp
    760         std      %f26, [%l2]
    761 
    762 	! Though this is the last set of compare instructions
    763 	! we cannot fall through as the store needs to be done
    764 	! only when the registers are not equal. That is why
    765 	! we need the unconditional branch with the annul bit set.
    766         fcmpd   %fcc0, %f30, %f28
    767         fbne,a     %fcc0, done_t_mult_dp
    768         std      %f28, [%l2]
    769 
    770 done_t_mult_dp:
    771 	ldx	[%l2], %i0
    772 
    773 	ret
    774 	restore
    775 SET_SIZE(timing_mult_dp)
    776 
    777 #endif
    778 
    779 /*
    780  * --------------------------------------------------------------------------
    781  * The following routines are for testing the IEEE754 exception fields
    782  * of the FSR (cexc, aexc)
    783  *	The input is : i0 = amsw
    784  *		       i1 = bmsw or alsw (for double precision)
    785  *	  	       i2 = bmsw (for dp)
    786  *		       i3 = blsw (for dp)
    787  *
    788  *	The output is  i0 = value of FSR register
    789  * -------------------------------------------------------------------------
    790  */
    791 
    792 #ifdef __lint
    793 
    794 /*ARGSUSED*/
    795 uint64_t
    796 wadd_sp(unsigned long arg1, unsigned long arg2)
    797 {
    798 	return (0);
    799 }
    800 
    801 #else
    802 
    803 .section        ".data"
    804 .align  8
    805 
    806 .Lwadds:
    807         .word   0
    808 .Lwadds1:
    809         .word   0
    810 .Lwadds2:
    811         .xword  0    ! For the FSR contents
    812 
    813 ENTRY_NP(wadd_sp)
    814 	save    %sp, -SA(MINFRAME), %sp
    815         setn    .Lwadds,%l6, %l0
    816         setn    .Lwadds1,%l6, %l1
    817 	setn	.Lwadds2,%l6, %l2
    818 
    819 	st	%i0, [%l0]		! get the first value
    820 	st	%i1, [%l1]		! get the second value
    821 	ld	[%l0], %f0		! f0 has the first value
    822 	ld 	[%l1], %f2		! f2 has the second value
    823 
    824 	fadds   %f0, %f2, %f3		! now do the instruction
    825 	stx	%fsr, [%l2]		! get the fsr value
    826 
    827 	ldx     [%l2], %i0
    828 	ret
    829 	restore
    830 SET_SIZE(wadd_sp)
    831 
    832 #endif
    833 
    834 /*
    835  * -------------------------------------------------------------
    836  *	same thing for add double precision
    837  * -------------------------------------------------------------
    838  */
    839 
    840 #ifdef __lint
    841 
    842 /*ARGSUSED*/
    843 uint64_t
    844 wadd_dp(unsigned long arg1, unsigned long arg2,
    845 	    unsigned long arg3, unsigned long arg4)
    846 {
    847 	return (0);
    848 }
    849 
    850 #else
    851 
    852 .section        ".data"
    853 .align  8
    854 
    855 .Ladddp:
    856         .word   0
    857 .Ladddp1:
    858         .word   0
    859 .Ladddp2:
    860         .xword  0    ! For the FSR contents
    861 
    862 ENTRY_NP(wadd_dp)
    863 	save    %sp, -SA(MINFRAME), %sp
    864         setn    .Ladddp,%l6, %l0
    865         setn    .Ladddp1,%l6, %l1
    866         setn    .Ladddp2,%l6, %l2
    867 
    868 	st	%i0, [%l0]              ! get the first value
    869         st      %i1, [%l1]              ! get the lsw of first value
    870 	ld	[%l0], %f0
    871 	ld	[%l1], %f1
    872 	st      %i2, [%l0]              ! get the second value
    873 	st      %i3, [%l1]              ! get the lsw of second value
    874 	ld	[%l0], %f2
    875 	ld	[%l1], %f3
    876 
    877 	faddd	%f0, %f2, %f4		! now do the instruction
    878         stx      %fsr, [%l2]             ! get the fsr value
    879 
    880 	ldx     [%l2], %i0
    881 	ret
    882 	restore
    883 
    884 SET_SIZE(wadd_dp)
    885 
    886 #endif
    887 
    888 /*
    889  * --------------------------------------------------------------
    890  *	for divide single precision
    891  * --------------------------------------------------------------
    892  */
    893 
    894 #ifdef __lint
    895 
    896 /*ARGSUSED*/
    897 uint64_t wdiv_sp(unsigned long arg1, unsigned long arg2)
    898 {
    899 	return (0);
    900 }
    901 
    902 #else
    903 
    904 .section        ".data"
    905 .align  8
    906 
    907 .Ldvsp:
    908         .word   0
    909 .Ldvsp1:
    910         .word   0
    911 .Ldvsp2:
    912         .xword  0    ! For the FSR contents
    913 
    914 ENTRY_NP(wdiv_sp)
    915 	save    %sp, -SA(MINFRAME), %sp
    916         setn    .Ldvsp,%l6, %l0
    917         setn    .Ldvsp1,%l6, %l1
    918         setn    .Ldvsp2,%l6, %l2
    919 
    920         st      %i0, [%l0]              ! get the first value
    921         st      %i1, [%l1]              ! get the second value
    922         ld      [%l0], %f0              ! f0 has the first value
    923         ld      [%l1], %f2              ! f2 has the second value
    924 
    925         fdivs	%f0, %f2, %f3           ! now do the instruction
    926         stx      %fsr, [%l2]             ! get the fsr value
    927 
    928 	ldx     [%l2], %i0
    929 	ret
    930 	restore
    931 
    932 SET_SIZE(wdiv_sp)
    933 
    934 #endif
    935 
    936 /*
    937  * ----------------------------------------------------------------
    938  *	for divide double precision
    939  * ----------------------------------------------------------------
    940  */
    941 
    942 #ifdef __lint
    943 
    944 /*ARGSUSED*/
    945 uint64_t
    946 wdiv_dp(unsigned long arg1, unsigned long arg2,
    947 	    unsigned long arg3, unsigned long arg4)
    948 {
    949 	return (0);
    950 }
    951 
    952 #else
    953 
    954  .section        ".data"
    955  .align  8
    956 
    957 .Ldvdp:
    958         .word   0
    959 .Ldvdp1:
    960         .word   0
    961 .Ldvdp2:
    962         .xword  0    ! For the FSR contents
    963 
    964 ENTRY_NP(wdiv_dp)
    965 	save    %sp, -SA(MINFRAME), %sp
    966         setn    .Ldvdp,%l6, %l0
    967         setn    .Ldvdp1,%l6, %l1
    968         setn    .Ldvdp2,%l6, %l2
    969 
    970         st      %i0, [%l0]              ! get the first value
    971         st      %i1, [%l1]              ! get the lsw of first value
    972         ld      [%l0], %f0
    973         ld      [%l1], %f1
    974         st      %i2, [%l0]              ! get the second value
    975         st      %i3, [%l1]              ! get the lsw of second value
    976         ld      [%l0], %f2
    977         ld      [%l1], %f3
    978 
    979         fdivd	%f0, %f2, %f4           ! now do the instruction
    980         stx      %fsr, [%l2]             ! get the fsr value
    981 
    982 	ldx     [%l2], %i0
    983 	ret
    984 	restore
    985 
    986 SET_SIZE(wdiv_dp)
    987 
    988 #endif
    989 
    990 /*
    991  * ------------------------------------------------------------------------
    992  *      for multiply single precision
    993  * ------------------------------------------------------------------------
    994  */
    995 
    996 #ifdef __lint
    997 
    998 /*ARGSUSED*/
    999 uint64_t
   1000 wmult_sp(unsigned long arg1, unsigned long arg2)
   1001 {
   1002 	return (0);
   1003 }
   1004 
   1005 #else
   1006 
   1007 .section        ".data"
   1008 .align  8
   1009 
   1010 .Lmltsp:
   1011         .word   0
   1012 .Lmltsp1:
   1013         .word   0
   1014 .Lmltsp2:
   1015         .xword  0    ! For the FSR contents
   1016 
   1017 ENTRY_NP(wmult_sp)
   1018 	save    %sp, -SA(MINFRAME), %sp
   1019         setn    .Lmltsp,%l6, %l0
   1020         setn    .Lmltsp1,%l6, %l1
   1021         setn    .Lmltsp2,%l6, %l2
   1022 
   1023         st      %i0, [%l0]              ! get the first value
   1024         st      %i1, [%l1]              ! get the second value
   1025         ld      [%l0], %f0              ! f0 has the first value
   1026         ld      [%l1], %f2              ! f2 has the second value
   1027 
   1028         fmuls   %f0, %f2, %f3           ! now do the instruction
   1029         stx      %fsr, [%l2]             ! get the fsr value
   1030 
   1031 	ldx     [%l2], %i0
   1032 	ret
   1033 	restore
   1034 
   1035 SET_SIZE(wmult_sp)
   1036 
   1037 #endif
   1038 
   1039 /*
   1040  * ---------------------------------------------------------------------
   1041  *      for multiply double precision
   1042  * ---------------------------------------------------------------------
   1043  */
   1044 
   1045 #ifdef __lint
   1046 
   1047 /*ARGSUSED*/
   1048 uint64_t
   1049 wmult_dp(unsigned long arg1, unsigned long arg2,
   1050 	    unsigned long arg3, unsigned long arg4)
   1051 {
   1052 	return (0);
   1053 }
   1054 
   1055 #else
   1056 
   1057 .section        ".data"
   1058 .align  8
   1059 
   1060 .Lmltdp:
   1061         .word   0
   1062 .Lmltdp1:
   1063         .word   0
   1064 .Lmltdp2:
   1065         .xword  0    ! For the FSR contents
   1066 
   1067 ENTRY_NP(wmult_dp)
   1068         save    %sp, -SA(MINFRAME), %sp
   1069         setn    .Lmltdp,%l6, %l0
   1070         setn    .Lmltdp1,%l6, %l1
   1071         setn    .Lmltdp2,%l6, %l2
   1072 
   1073         st      %i0, [%l0]		! get the first value
   1074         st      %i1, [%l1]		! get the lsw of first value
   1075         ld      [%l0], %f0
   1076         ld      [%l1], %f1
   1077         st      %i2, [%l0]		! get the second value
   1078         st      %i3, [%l1]		! get the lsw of second value
   1079         ld      [%l0], %f2
   1080         ld      [%l1], %f3
   1081 
   1082         fmuld	 %f0, %f2, %f4		! now do the instruction
   1083         stx      %fsr, [%l2]		! get the fsr value
   1084 
   1085 	ldx     [%l2], %i0
   1086 	ret
   1087 	restore
   1088 
   1089 SET_SIZE(wmult_dp)
   1090 
   1091 #endif
   1092 
   1093 /*
   1094  * -----------------------------------------------------------------
   1095  *      for square-root single precision
   1096  * -----------------------------------------------------------------
   1097  */
   1098 
   1099 #ifdef __lint
   1100 
   1101 /*ARGSUSED*/
   1102 uint64_t
   1103 wsqrt_sp(unsigned long arg1)
   1104 {
   1105 	return (0);
   1106 }
   1107 
   1108 #else
   1109 
   1110 .section        ".data"
   1111 .align  4
   1112 .Lsqsp_opr:
   1113                 .word   0
   1114 
   1115         .align  8
   1116 .Lsqsp_fsr:
   1117                 .xword  0       ! For the FSR contents
   1118 
   1119 ENTRY_NP(wsqrt_sp)
   1120 	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
   1121 	setn	.Lsqsp_opr,%l6,%l0	! .. get the address of temp2
   1122 	setn	.Lsqsp_fsr,%l6,%l2	! .. and temp
   1123 
   1124 	st	%i0, [%l0]	! .. get the callers value
   1125 	ld	[%l0], %f0	! .. into the float register
   1126 
   1127 	fsqrts  %f0, %f2	! .... have the fpu perform the operation
   1128         stx     %fsr, [%l2]		! get the fsr value
   1129 
   1130 	ldx     [%l2], %i0
   1131 	ret
   1132 	restore
   1133 
   1134 SET_SIZE(wsqrt_sp)
   1135 
   1136 #endif
   1137 
   1138 /*
   1139  * ---------------------------------------------------------------------
   1140  *       for square-root double precision
   1141  * ---------------------------------------------------------------------
   1142  */
   1143 
   1144 #ifdef __lint
   1145 
   1146 /*ARGSUSED*/
   1147 uint64_t
   1148 wsqrt_dp(uint64_t arg1)
   1149 {
   1150 	return (0);
   1151 }
   1152 
   1153 #else
   1154 
   1155 .section        ".data"
   1156 .align  8
   1157 .Lsqdp_opr:
   1158                 .xword  0
   1159 .Lsqdp_fsr:
   1160                 .xword  0       ! For the FSR contents
   1161 
   1162 ENTRY_NP(wsqrt_dp)
   1163 	save	%sp, -SA(MINFRAME), %sp	! save the registers, stack
   1164 	setn	.Lsqdp_opr,%l6,%l0 	! .. get the address of temp2
   1165 	setn	.Lsqdp_fsr,%l6,%l2 	! .. and temp
   1166 
   1167 	stx	%i0, [%l0] 	! .. get the callers value
   1168 	ldd	[%l0], %f0 	! .. into a float register
   1169 
   1170 	fsqrtd  %f0, %f2	! .... have the fpu perform the operation
   1171         stx     %fsr, [%l2]	! get the fsr value
   1172 
   1173 	ldx     [%l2], %i0
   1174 	ret
   1175 	restore
   1176 
   1177 SET_SIZE(wsqrt_dp)
   1178 
   1179 #endif
   1180 
   1181 /*
   1182  * ---------------------------------------------------------------------
   1183  *	Chaining test.
   1184  * ---------------------------------------------------------------------
   1185  */
   1186 
   1187 #ifdef __lint
   1188 
   1189 /*ARGSUSED*/
   1190 unsigned long
   1191 chain_sp(int arg1)
   1192 {
   1193 	return (0);
   1194 }
   1195 
   1196 #else
   1197 
   1198 .section        ".data"
   1199 .align  8
   1200 
   1201 .Lchsp:
   1202         .word   0
   1203 .Lchsp1:
   1204         .word   0
   1205 
   1206 ENTRY_NP(chain_sp)
   1207 	save    %sp, -SA(MINFRAME), %sp
   1208         setn    .Lchsp,%l6, %l0
   1209         setn    .Lchsp1,%l6, %l1
   1210 	st	%i0, [%l0]	! store the value
   1211 	ld	[%l0], %f0
   1212 	fitos   %f0, %f2	! convert integer into single
   1213 	fmovs   %f2, %f0	! f0 has the same value  x
   1214 	fadds	%f0, %f2, %f4   ! f4 will have 2x
   1215 	fsubs   %f4, %f0, %f6   ! f6 will have x
   1216 	fmuls   %f6, %f4, %f8   ! f8 will have (2x * x)
   1217 	fdivs   %f8, %f4, %f10  ! f10 will have (2x * x) / 2x = x
   1218 	fstoi	%f10, %f12
   1219 
   1220 	st	%f12, [%l1]
   1221 	ld	[%l1], %i0
   1222 
   1223 	ret
   1224         restore
   1225 SET_SIZE(chain_sp)
   1226 
   1227 #endif
   1228 
   1229 #ifdef __lint
   1230 
   1231 /*ARGSUSED*/
   1232 unsigned long
   1233 chain_dp(int arg1)
   1234 {
   1235 	return (0);
   1236 }
   1237 
   1238 #else
   1239 
   1240 .section        ".data"
   1241 .align  8
   1242 
   1243 .Lchdp:
   1244         .word   0
   1245 .Lchdp1:
   1246         .word   0
   1247 
   1248 ENTRY_NP(chain_dp)
   1249 	save    %sp, -SA(MINFRAME), %sp
   1250         setn    .Lchdp,%l6, %l0
   1251         setn    .Lchdp1,%l6, %l1
   1252         st      %i0, [%l0]      ! store the value
   1253         ld      [%l0], %f0
   1254         fitod   %f0, %f2        ! convert integer into double
   1255 	fmovs   %f2, %f0        ! f0 has the same value  x
   1256         faddd   %f0, %f2, %f4   ! f4 will have 2x
   1257         fsubd   %f4, %f0, %f6   ! f6 will have x
   1258         fmuld   %f6, %f4, %f8   ! f8 will have (2x * x)
   1259         fdivd   %f8, %f4, %f10  ! f10 will have (2x * x) / 2x = x
   1260         fdtoi   %f10, %f12
   1261 
   1262 	st	%f12, [%l1]
   1263 	ld	[%l1], %i0
   1264 
   1265 	ret
   1266         restore
   1267 SET_SIZE(chain_dp)
   1268 
   1269 #endif
   1270 
   1271 /*
   1272  * --------------------------------------------------------------------------
   1273  * Name:	Initialize all SP Registers
   1274  * Function:	Loads the callers value into all SP floating point registers.
   1275  * Calling:	in0 = Value
   1276  * Returns:	All float register = Value
   1277  * Convention:	init_regs(val);
   1278  * Method:	Copys the user value into each fp reg in sequence.
   1279  * --------------------------------------------------------------------------
   1280  */
   1281 
   1282 #ifdef __lint
   1283 
   1284 /*ARGSUSED*/
   1285 void
   1286 init_regs(uint32_t arg1)
   1287 {
   1288 }
   1289 
   1290 #else
   1291 
   1292 .section        ".data"
   1293 .align  8
   1294 
   1295 .Lclrg:
   1296         .skip   8
   1297 
   1298 ENTRY_NP(init_regs)
   1299 	save    %sp, -SA(MINFRAME), %sp	! save the registers, stack
   1300         setn    .Lclrg,%l6,%l0	! load the address of temp2 in local0
   1301 	st	%i0, [%l0]	! load the value in temp2 via local0
   1302 	ld	[%l0], %f0	! .. load the value
   1303 	ld	[%l0], %f1	! .. load the value
   1304         ld      [%l0], %f2	! .. load the value
   1305         ld      [%l0], %f3	! .. load the value
   1306         ld      [%l0], %f4	! .. load the value
   1307 	ld	[%l0], %f5	! .. load the value
   1308         ld      [%l0], %f6 	! .. load the value
   1309         ld      [%l0], %f7 	! .. load the value
   1310         ld      [%l0], %f8 	! .. load the value
   1311         ld      [%l0], %f9 	! .. load the value
   1312         ld      [%l0], %f10 	! .. load the value
   1313         ld      [%l0], %f11 	! .. load the value
   1314         ld      [%l0], %f12 	! .. load the value
   1315         ld      [%l0], %f13 	! .. load the value
   1316         ld      [%l0], %f14 	! .. load the value
   1317         ld      [%l0], %f15 	! .. load the value
   1318         ld      [%l0], %f16 	! .. load the value
   1319         ld      [%l0], %f17 	! .. load the value
   1320         ld      [%l0], %f18 	! .. load the value
   1321         ld      [%l0], %f19 	! .. load the value
   1322         ld      [%l0], %f20 	! .. load the value
   1323         ld      [%l0], %f21 	! .. load the value
   1324         ld      [%l0], %f22 	! .. load the value
   1325         ld      [%l0], %f23 	! .. load the value
   1326         ld      [%l0], %f24 	! .. load the value
   1327         ld      [%l0], %f25 	! .. load the value
   1328         ld      [%l0], %f26 	! .. load the value
   1329         ld      [%l0], %f27 	! .. load the value
   1330         ld      [%l0], %f28 	! .. load the value
   1331         ld      [%l0], %f29 	! .. load the value
   1332         ld      [%l0], %f30 	! .. load the value
   1333         ld      [%l0], %f31	! .. load the value
   1334 	ret
   1335         restore
   1336 SET_SIZE(init_regs)
   1337 
   1338 #endif
   1339 
   1340 /*
   1341  * Name:	Initialize all double precision Registers
   1342  * Function:	Loads the callers value into all floating point registers.
   1343  * Calling:	in0 = Value
   1344  * Returns:	All float register = Value
   1345  * Convention:	init_regs_dp(val);
   1346  * Method:	Copys the user value into each fp reg in sequence.
   1347  * --------------------------------------------------------------------------
   1348  */
   1349 
   1350 #ifdef __lint
   1351 
   1352 /*ARGSUSED*/
   1353 void
   1354 init_regs_dp(uint64_t arg1)
   1355 {
   1356 }
   1357 
   1358 #else
   1359 
   1360 .section        ".data"
   1361 .align  8
   1362 
   1363 .Lclrg_dp:
   1364         .skip   16
   1365 
   1366 ENTRY_NP(init_regs_dp)
   1367 	save    %sp, -SA(MINFRAME), %sp
   1368 								! save the registers, stack
   1369         setx    .Lclrg_dp,%l6,%l0	! load the address of temp2 in local0
   1370 	stx	%i0, [%l0]		! load the value in temp2 via local0
   1371 	ldd	[%l0], %f0		! .. load the value
   1372 	ldd	[%l0], %f2		! .. load the value
   1373         ldd     [%l0], %f4		! .. load the value
   1374         ldd     [%l0], %f6		! .. load the value
   1375         ldd     [%l0], %f8		! .. load the value
   1376 	ldd	[%l0], %f10		! .. load the value
   1377         ldd     [%l0], %f12		! .. load the value
   1378         ldd     [%l0], %f14		! .. load the value
   1379         ldd     [%l0], %f16		! .. load the value
   1380         ldd     [%l0], %f18		! .. load the value
   1381         ldd     [%l0], %f20 	! .. load the value
   1382         ldd     [%l0], %f22 	! .. load the value
   1383         ldd     [%l0], %f24 	! .. load the value
   1384         ldd     [%l0], %f26 	! .. load the value
   1385         ldd     [%l0], %f28 	! .. load the value
   1386         ldd     [%l0], %f30 	! .. load the value
   1387         ldd     [%l0], %f32 	! .. load the value
   1388         ldd     [%l0], %f34 	! .. load the value
   1389         ldd     [%l0], %f36 	! .. load the value
   1390         ldd     [%l0], %f38 	! .. load the value
   1391         ldd     [%l0], %f40 	! .. load the value
   1392         ldd     [%l0], %f42 	! .. load the value
   1393         ldd     [%l0], %f44 	! .. load the value
   1394         ldd     [%l0], %f46 	! .. load the value
   1395         ldd     [%l0], %f48 	! .. load the value
   1396         ldd     [%l0], %f50 	! .. load the value
   1397         ldd     [%l0], %f52 	! .. load the value
   1398         ldd     [%l0], %f54 	! .. load the value
   1399         ldd     [%l0], %f56 	! .. load the value
   1400         ldd     [%l0], %f58 	! .. load the value
   1401         ldd     [%l0], %f60 	! .. load the value
   1402         ldd     [%l0], %f62		! .. load the value
   1403 	ret
   1404         restore
   1405 SET_SIZE(init_regs_dp)
   1406 
   1407 #endif
   1408 
   1409 /*
   1410  * Name:
   1411  * Function:
   1412  * Calling:
   1413  * Returns:
   1414  * Convention:
   1415  * --------------------------------------------------------------------------
   1416  */
   1417 
   1418 #ifdef __lint
   1419 
   1420 /*ARGSUSED*/
   1421 uint32_t
   1422 register_test(int arg1, uint32_t arg2)
   1423 {
   1424 	return (0);
   1425 }
   1426 
   1427 #else
   1428 
   1429 .section        ".data"
   1430 .align  4
   1431 
   1432 .Lrgtst1:
   1433         .skip   4
   1434 .Lrgtst2:
   1435         .skip   4
   1436 
   1437 ENTRY_NP(register_test)
   1438 	save    %sp, -SA(MINFRAME), %sp
   1439 
   1440 	setn	.Lrgtst1,%l6,%l1
   1441 	setn	.Lrgtst2,%l6,%l2
   1442 
   1443 
   1444 	setn	regTable, %l6, %o0
   1445 	mulx	%i0, 12, %o1		! Table entries are 12 bytes each.
   1446 
   1447 	! Jump to the appropriate set of instructions
   1448 	jmp	%o0+%o1
   1449 	st	%i1,  [%l1]		! save the pattern to be written
   1450 
   1451 
   1452 ! If the number of instructions in this macro are changed,
   1453 ! please ensure that the second operand for the mulx above
   1454 ! is also updated. We can calculate this during run-time but
   1455 ! that will mean extra instructions and time.
   1456 #define	TEST_REG(reg_num)		\
   1457 	ld	[%l1], %f/**/reg_num;	\
   1458 	ba	%ncc, reg_done;		\
   1459 	st	%f/**/reg_num, [%l2]
   1460 
   1461 regTable :
   1462 
   1463 	TEST_REG(0)
   1464 	TEST_REG(1)
   1465 	TEST_REG(2)
   1466 	TEST_REG(3)
   1467 	TEST_REG(4)
   1468 	TEST_REG(5)
   1469 	TEST_REG(6)
   1470 	TEST_REG(7)
   1471 	TEST_REG(8)
   1472 	TEST_REG(9)
   1473 	TEST_REG(10)
   1474 	TEST_REG(11)
   1475 	TEST_REG(12)
   1476 	TEST_REG(13)
   1477 	TEST_REG(14)
   1478 	TEST_REG(15)
   1479 	TEST_REG(16)
   1480 	TEST_REG(17)
   1481 	TEST_REG(18)
   1482 	TEST_REG(19)
   1483 	TEST_REG(20)
   1484 	TEST_REG(21)
   1485 	TEST_REG(22)
   1486 	TEST_REG(23)
   1487 	TEST_REG(24)
   1488 	TEST_REG(25)
   1489 	TEST_REG(26)
   1490 	TEST_REG(27)
   1491 	TEST_REG(28)
   1492 	TEST_REG(29)
   1493 	TEST_REG(30)
   1494 
   1495 	! No need for a branch here as this the last entry in
   1496 	! the table and the label is will be reached by falling
   1497 	! through.
   1498 	ld	[%l1], %f31
   1499 	st	%f31, [%l2]
   1500 
   1501 reg_done:
   1502 	ld	[%l2], %i0
   1503 
   1504 	ret
   1505 	restore
   1506 SET_SIZE(register_test)
   1507 
   1508 #endif
   1509 
   1510 /*
   1511  * Name:
   1512  * Function:
   1513  * Calling:
   1514  * Returns:
   1515  * Convention:
   1516  * --------------------------------------------------------------------------
   1517  */
   1518 
   1519 #ifdef __lint
   1520 
   1521 /*ARGSUSED*/
   1522 uint64_t
   1523 register_test_dp(int arg1, uint64_t arg2)
   1524 {
   1525 	return (0);
   1526 }
   1527 
   1528 #else
   1529 
   1530 .section        ".data"
   1531 .align  8
   1532 
   1533 .Lrgtst1_dp:
   1534         .skip   8
   1535 .Lrgtst2_dp:
   1536         .skip   8
   1537 
   1538 ENTRY_NP(register_test_dp)
   1539 	save    %sp, -SA(MINFRAME), %sp
   1540 
   1541 	setx	.Lrgtst1_dp,%l6,%l1
   1542 	setx	.Lrgtst2_dp,%l6,%l2
   1543 
   1544 	setn	regTable_dp, %l6, %o0
   1545 	mulx	%i0, 6, %o1	! Registers are 64-bit and hence the
   1546 				! register numbers given will be even.
   1547 				! Each table entry is 12 bytes.
   1548 				! Multiplying the even register number
   1549 				! by 6 will give the correct offset.
   1550 
   1551 
   1552 	! Jump to the appropriate set of instructions
   1553 	jmp	%o0+%o1
   1554 	stx	%i1,  [%l1]		!save the pattern to be written
   1555 
   1556 ! If the number of instructions in this macro are changed,
   1557 ! please ensure that the second operand for the mulx above
   1558 ! is also updated. We can calculate this during run-time but
   1559 ! that will mean extra instructions and time.
   1560 #define TEST_REG_DP(reg_num)		\
   1561 	ldd	[%l1], %f/**/reg_num;	\
   1562 	ba	%ncc, reg_done_dp;	\
   1563 	std	%f/**/reg_num, [%l2]
   1564 
   1565 regTable_dp :
   1566 
   1567 	TEST_REG_DP(0)
   1568 	TEST_REG_DP(2)
   1569 	TEST_REG_DP(4)
   1570 	TEST_REG_DP(6)
   1571 	TEST_REG_DP(8)
   1572 	TEST_REG_DP(10)
   1573 	TEST_REG_DP(12)
   1574 	TEST_REG_DP(14)
   1575 	TEST_REG_DP(16)
   1576 	TEST_REG_DP(18)
   1577 	TEST_REG_DP(20)
   1578 	TEST_REG_DP(22)
   1579 	TEST_REG_DP(24)
   1580 	TEST_REG_DP(26)
   1581 	TEST_REG_DP(28)
   1582 	TEST_REG_DP(30)
   1583 	TEST_REG_DP(32)
   1584 	TEST_REG_DP(34)
   1585 	TEST_REG_DP(36)
   1586 	TEST_REG_DP(38)
   1587 	TEST_REG_DP(40)
   1588 	TEST_REG_DP(42)
   1589 	TEST_REG_DP(44)
   1590 	TEST_REG_DP(46)
   1591 	TEST_REG_DP(48)
   1592 	TEST_REG_DP(50)
   1593 	TEST_REG_DP(52)
   1594 	TEST_REG_DP(54)
   1595 	TEST_REG_DP(56)
   1596 	TEST_REG_DP(58)
   1597 	TEST_REG_DP(60)
   1598 
   1599 	! No need for a branch here as this the last entry in
   1600 	! the table and the label is will be reached by falling
   1601 	! through.
   1602 	ldd	[%l1], %f62
   1603 	std	%f62, [%l2]
   1604 
   1605 reg_done_dp:
   1606 	ldx	[%l2], %i0
   1607 
   1608 	ret
   1609 	restore
   1610 SET_SIZE(register_test_dp)
   1611 
   1612 #endif
   1613 
   1614 /*
   1615  * ------------------------------------------------------------------------
   1616  * Name:	Move Registers
   1617  * Function:	Move a value thru the float registers
   1618  * Calling:	in0 = value
   1619  * Returns:	in0 = result
   1620  * Convention:	if (result != move_regs(value))
   1621  *                  error(result-value);
   1622  * --------------------------------------------------------------------------
   1623  */
   1624 
   1625 #ifdef __lint
   1626 
   1627 /*ARGSUSED*/
   1628 unsigned long
   1629 move_regs(unsigned long arg1)
   1630 {
   1631 	return (0);
   1632 }
   1633 
   1634 #else
   1635 
   1636 .section        ".data"
   1637 .align  4
   1638 
   1639 .Lmvrg:
   1640         .skip   4
   1641 .Lmvrg1:
   1642         .skip   4
   1643 
   1644 ENTRY_NP(move_regs)
   1645 	save    %sp, -SA(MINFRAME), %sp	! save the registers, stack
   1646         setn    .Lmvrg1,%l6,%l0	! get the address to temp2
   1647         setn    .Lmvrg,%l6,%l1	! .. and temp
   1648         st      %i0, [%l0]	! get the callers value
   1649         ld      [%l0], %f0	! .. into a float register
   1650 	fmovs   %f0, %f1	! copy from 1 register to the next
   1651 	fmovs   %f1, %f2	! .. to the next
   1652 	fmovs   %f2, %f3	! .. to the next
   1653 	fmovs   %f3, %f4	! .. to the next
   1654 	fmovs   %f4, %f5	! .. to the next
   1655 	fmovs   %f5, %f6	! .. to the next
   1656 	fmovs   %f6, %f7	! .. to the next
   1657 	fmovs   %f7, %f8	! .. to the next
   1658 	fmovs   %f8, %f9	! .. to the next
   1659 	fmovs   %f9, %f10	! .. to the next
   1660 	fmovs   %f10, %f11	! .. to the next
   1661 	fmovs   %f11, %f12	! .. to the next
   1662 	fmovs   %f12, %f13	! .. to the next
   1663 	fmovs   %f13, %f14	! .. to the next
   1664 	fmovs   %f14, %f15	! .. to the next
   1665 	fmovs   %f15, %f16	! .. to the next
   1666 	fmovs   %f16, %f17	! .. to the next
   1667 	fmovs   %f17, %f18	! .. to the next
   1668 	fmovs   %f18, %f19	! .. to the next
   1669 	fmovs   %f19, %f20	! .. to the next
   1670 	fmovs   %f20, %f21	! .. to the next
   1671 	fmovs   %f21, %f22	! .. to the next
   1672 	fmovs   %f22, %f23	! .. to the next
   1673 	fmovs   %f23, %f24	! .. to the next
   1674 	fmovs   %f24, %f25	! .. to the next
   1675 	fmovs   %f25, %f26	! .. to the next
   1676 	fmovs   %f26, %f27	! .. to the next
   1677 	fmovs   %f27, %f28	! .. to the next
   1678 	fmovs   %f28, %f29	! .. to the next
   1679 	fmovs   %f29, %f30	! .. to the next
   1680 	fmovs   %f30, %f31	! .. to the next
   1681 	st	%f31, [%l1]	! .... save the result
   1682 	ld	[%l1], %i0	! .. and return it to the caller
   1683 	ret
   1684         restore
   1685 SET_SIZE(move_regs)
   1686 
   1687 #endif
   1688 
   1689 /*
   1690  * ------------------------------------------------------------------------
   1691  * Name:
   1692  * Function:
   1693  * Calling:
   1694  * Returns:
   1695  * Convention:
   1696  * --------------------------------------------------------------------------
   1697  *
   1698  *	The following routine checks the branching is done accordingly
   1699  *	to the ficc bits.
   1700  * 	input	%i0 = 0 = branch unordered
   1701  *		      1 = branch greater
   1702  *		      2 = branch unordered or greater
   1703  *		      3 = branch less
   1704  *		      4 = branch unordered or less
   1705  *		      5 = branch less or greater
   1706  *		      6 = branch not equal
   1707  *		      7 = branch equal
   1708  *		      8 = branch unordered or equal
   1709  *		    . 9 = branch greater or equal
   1710  * 		     10 = branch branch unordered or greater or equal
   1711  *		     11 = branch less or equal
   1712  *		     12 = branch unordered or or less or equal
   1713  *		     13 = branch ordered
   1714  *		     14 = branch always
   1715  *		     15 = branch never
   1716  *
   1717  *	ouput : %i0 = 0 = good
   1718  *		    = 1 = error
   1719  */
   1720 
   1721 #ifdef __lint
   1722 
   1723 /*ARGSUSED*/
   1724 unsigned long
   1725 branches(unsigned long arg1, unsigned long arg2, unsigned long arg3)
   1726 {
   1727 	return (0);
   1728 }
   1729 
   1730 #else
   1731 
   1732 .section        ".data"
   1733 .align  8
   1734 
   1735 .Lbr:
   1736         .skip   8
   1737 .Lbr1:
   1738         .skip   8
   1739 
   1740 ENTRY_NP(branches)
   1741 	save    %sp, -SA(MINFRAME), %sp           ! save the registers, stacck
   1742         setn    .Lbr1,%l6,%l1
   1743         setn    .Lbr,%l6,%l2
   1744         st      %i1, [%l1]
   1745 	st	%i2, [%l2]
   1746 	ld      [%l1], %f0
   1747         ld      [%l2], %f2
   1748 
   1749 	setn	brn_0, %l6, %o0
   1750 	mulx	%i0, 12, %o1
   1751 
   1752 
   1753 	jmp	%o0+%o1
   1754 	fcmps	%fcc0, %f0, %f2		! compare the values  to get ficc
   1755 !
   1756 !				branch unordered
   1757 brn_0:
   1758 	fbu,a	%fcc0, br_good
   1759 	nop
   1760 	ba,a	%ncc, br_error
   1761 
   1762 !				branch greater
   1763 brn_1:
   1764 	fbg,a	%fcc0, br_good
   1765 	nop
   1766 	ba,a	%ncc, br_error
   1767 
   1768 !				branch unordered or greater
   1769 brn_2:
   1770 	fbug,a	%fcc0, br_good
   1771 	nop
   1772 	ba,a	%ncc, br_error
   1773 
   1774 !				branch less
   1775 brn_3:
   1776 	fbl,a	%fcc0, br_good
   1777 	nop
   1778 	ba,a	%ncc, br_error
   1779 
   1780 !				branch unorderd or less
   1781 brn_4:
   1782 	fbul,a	%fcc0, br_good
   1783 	nop
   1784 	ba,a	%ncc, br_error
   1785 
   1786 !				branch less or greater
   1787 brn_5:
   1788 	fblg,a	%fcc0, br_good
   1789 	nop
   1790 	ba,a	%ncc, br_error
   1791 
   1792 !				branch not equal
   1793 brn_6:
   1794 	fbne,a	%fcc0, br_good
   1795 	nop
   1796 	ba,a	%ncc, br_error
   1797 
   1798 !                               branch equal
   1799 brn_7:
   1800 	fbe,a	%fcc0, br_good
   1801         nop
   1802 	ba,a	%ncc, br_error
   1803 
   1804 !                               branch unordered or equal
   1805 brn_8:
   1806 	fbue,a	%fcc0, br_good
   1807         nop
   1808 	ba,a	%ncc, br_error
   1809 
   1810 !                               branch greater or equal
   1811 brn_9:
   1812 	fbge,a	%fcc0, br_good
   1813         nop
   1814 	ba,a	%ncc, br_error
   1815 
   1816 !                               branch unordered or greater or equal
   1817 brn_10:
   1818 	fbuge,a	%fcc0, br_good
   1819         nop
   1820 	ba,a	%ncc, br_error
   1821 
   1822 !                               branch less or equal
   1823 brn_11:
   1824 	fble,a	%fcc0, br_good
   1825         nop
   1826 	ba,a	%ncc, br_error
   1827 
   1828 !                               branch unordered or less or equal
   1829 brn_12:
   1830 	fbule,a	%fcc0, br_good
   1831         nop
   1832 	ba,a	%ncc, br_error
   1833 
   1834 !                               branch ordered
   1835 brn_13:
   1836 	fbo,a	%fcc0, br_good
   1837 	nop
   1838 	ba,a	%ncc, br_error
   1839 
   1840 !				branch always
   1841 brn_14:
   1842 	fba,a	%fcc0, br_good
   1843 	nop
   1844 	ba,a	%ncc, br_error
   1845 
   1846 !				branch never
   1847 brn_15:
   1848 	fbn,a	%fcc0, br_error
   1849 	nop
   1850 
   1851 br_good:
   1852 	mov	%g0, %i0	! Branch worked as expected
   1853 
   1854 	ret
   1855 	restore
   1856 
   1857 br_error:
   1858 	mov	0xff, %i0	! set the flag that it is error
   1859 
   1860         ret
   1861         restore
   1862 SET_SIZE(branches)
   1863 
   1864 #endif
   1865 
   1866 /*
   1867  * void read_fpreg(pf, n)
   1868  *      FPU_REGS_TYPE   *pf;    Old freg value.
   1869  *      unsigned        n;      Want to read register n.
   1870  *
   1871  * {
   1872  *      *pf = %f[n];
   1873  * }
   1874  */
   1875 
   1876 
   1877 #ifdef __lint
   1878 
   1879 /*ARGSUSED*/
   1880 void
   1881 read_fpreg(unsigned int *arg1, int arg2)
   1882 {
   1883 }
   1884 
   1885 #else
   1886 
   1887 ENTRY_NP(read_fpreg)
   1888 	save    %sp, -SA(MINFRAME), %sp
   1889         mulx    %i1, 12, %i1            ! Table entries are 12 bytes each.
   1890         setn    stable, %l1, %g1        ! g1 gets base of table.
   1891         jmp     %g1 + %i1               ! Jump into table
   1892         nop                             ! Can't follow CTI by CTI.
   1893 
   1894 #define STOREFP(n) st %f/**/n, [%i0]; ret; restore
   1895 
   1896 stable:
   1897 	STOREFP(0)
   1898 	STOREFP(1)
   1899 	STOREFP(2)
   1900 	STOREFP(3)
   1901 	STOREFP(4)
   1902 	STOREFP(5)
   1903 	STOREFP(6)
   1904 	STOREFP(7)
   1905 	STOREFP(8)
   1906 	STOREFP(9)
   1907 	STOREFP(10)
   1908 	STOREFP(11)
   1909 	STOREFP(12)
   1910 	STOREFP(13)
   1911 	STOREFP(14)
   1912 	STOREFP(15)
   1913 	STOREFP(16)
   1914 	STOREFP(17)
   1915 	STOREFP(18)
   1916 	STOREFP(19)
   1917 	STOREFP(20)
   1918 	STOREFP(21)
   1919 	STOREFP(22)
   1920 	STOREFP(23)
   1921 	STOREFP(24)
   1922 	STOREFP(25)
   1923 	STOREFP(26)
   1924 	STOREFP(27)
   1925 	STOREFP(28)
   1926 	STOREFP(29)
   1927 	STOREFP(30)
   1928 	STOREFP(31)
   1929 SET_SIZE(read_fpreg)
   1930 
   1931 #endif
   1932 
   1933 #ifdef __lint
   1934 
   1935 /*ARGSUSED*/
   1936 void
   1937 read_fpreg_dp(unsigned long *arg1, int arg2)
   1938 {
   1939 	return;
   1940 }
   1941 
   1942 #else
   1943 
   1944 ENTRY_NP(read_fpreg_dp)
   1945 	save    %sp, -SA(MINFRAME), %sp
   1946         mulx    %i1, 6, %i1             ! Table entries are 12 bytes each.
   1947 										! But o1 will have even numbered
   1948 										! index
   1949         setn    stable_dp, %l0, %g1			! g1 gets base of table.
   1950         jmp     %g1 + %i1               ! Jump into table
   1951         nop                             ! Can't follow CTI by CTI.
   1952 
   1953 #define STOREFP_DP(n) std %f/**/n, [%i0]; ret; restore
   1954 
   1955 stable_dp:
   1956 	STOREFP_DP(0)
   1957 	STOREFP_DP(2)
   1958 	STOREFP_DP(4)
   1959 	STOREFP_DP(6)
   1960 	STOREFP_DP(8)
   1961 	STOREFP_DP(10)
   1962 	STOREFP_DP(12)
   1963 	STOREFP_DP(14)
   1964 	STOREFP_DP(16)
   1965 	STOREFP_DP(18)
   1966 	STOREFP_DP(20)
   1967 	STOREFP_DP(22)
   1968 	STOREFP_DP(24)
   1969 	STOREFP_DP(26)
   1970 	STOREFP_DP(28)
   1971 	STOREFP_DP(30)
   1972 	STOREFP_DP(32)
   1973 	STOREFP_DP(34)
   1974 	STOREFP_DP(36)
   1975 	STOREFP_DP(38)
   1976 	STOREFP_DP(40)
   1977 	STOREFP_DP(42)
   1978 	STOREFP_DP(44)
   1979 	STOREFP_DP(46)
   1980 	STOREFP_DP(48)
   1981 	STOREFP_DP(50)
   1982 	STOREFP_DP(52)
   1983 	STOREFP_DP(54)
   1984 	STOREFP_DP(56)
   1985 	STOREFP_DP(58)
   1986 	STOREFP_DP(60)
   1987 	STOREFP_DP(62)
   1988 
   1989 SET_SIZE(read_fpreg_dp)
   1990 
   1991 #endif
   1992 
   1993 /*
   1994  * void
   1995  * write_fpreg(pf, n)
   1996  *      FPU_REGS_TYPE   *pf;    New freg value.
   1997  *      unsigned        n;      Want to read register n.
   1998  *
   1999  * {
   2000  *      %f[n] = *pf;
   2001  * }
   2002  */
   2003 
   2004 #ifdef __lint
   2005 
   2006 #else
   2007 
   2008 ENTRY_NP(write_fpreg)
   2009         sll     %o1, 3, %o1             ! Table entries are 8 bytes each.
   2010         setn     ltable, %l0,  %g1       ! g1 gets base of table.
   2011         jmp     %g1 + %o1               ! Jump into table
   2012         nop                             ! Can't follow CTI by CTI.
   2013 
   2014 
   2015 #define LOADFP(n) jmp %o7+8 ; ld [%o0],%f/**/n
   2016 
   2017 ltable:
   2018 	LOADFP(0)
   2019 	LOADFP(1)
   2020 	LOADFP(2)
   2021 	LOADFP(3)
   2022 	LOADFP(4)
   2023 	LOADFP(5)
   2024 	LOADFP(6)
   2025 	LOADFP(7)
   2026 	LOADFP(8)
   2027 	LOADFP(9)
   2028 	LOADFP(10)
   2029 	LOADFP(11)
   2030 	LOADFP(12)
   2031 	LOADFP(13)
   2032 	LOADFP(14)
   2033 	LOADFP(15)
   2034 	LOADFP(16)
   2035 	LOADFP(17)
   2036 	LOADFP(18)
   2037 	LOADFP(19)
   2038 	LOADFP(20)
   2039 	LOADFP(21)
   2040 	LOADFP(22)
   2041 	LOADFP(23)
   2042 	LOADFP(24)
   2043 	LOADFP(25)
   2044 	LOADFP(26)
   2045 	LOADFP(27)
   2046 	LOADFP(28)
   2047 	LOADFP(29)
   2048 	LOADFP(30)
   2049 	LOADFP(31)
   2050 SET_SIZE(write_fpreg)
   2051 
   2052 #endif
   2053