Home | History | Annotate | Line # | Download | only in fpsp
do_func.sa revision 1.2
      1 *	$NetBSD: do_func.sa,v 1.2 1994/10/26 07:49:02 cgd Exp $
      2 
      3 *	MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
      4 *	M68000 Hi-Performance Microprocessor Division
      5 *	M68040 Software Package 
      6 *
      7 *	M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
      8 *	All rights reserved.
      9 *
     10 *	THE SOFTWARE is provided on an "AS IS" basis and without warranty.
     11 *	To the maximum extent permitted by applicable law,
     12 *	MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
     13 *	INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
     14 *	PARTICULAR PURPOSE and any warranty against infringement with
     15 *	regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
     16 *	and any accompanying written materials. 
     17 *
     18 *	To the maximum extent permitted by applicable law,
     19 *	IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
     20 *	(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
     21 *	PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
     22 *	OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
     23 *	SOFTWARE.  Motorola assumes no responsibility for the maintenance
     24 *	and support of the SOFTWARE.  
     25 *
     26 *	You are hereby granted a copyright license to use, modify, and
     27 *	distribute the SOFTWARE so long as this entire notice is retained
     28 *	without alteration in any modified and/or redistributed versions,
     29 *	and that such modified versions are clearly identified as such.
     30 *	No licenses are granted by implication, estoppel or otherwise
     31 *	under any patents or trademarks of Motorola, Inc.
     32 
     33 *
     34 *	do_func.sa 3.4 2/18/91
     35 *
     36 * Do_func performs the unimplemented operation.  The operation
     37 * to be performed is determined from the lower 7 bits of the
     38 * extension word (except in the case of fmovecr and fsincos).
     39 * The opcode and tag bits form an index into a jump table in 
     40 * tbldo.sa.  Cases of zero, infinity and NaN are handled in 
     41 * do_func by forcing the default result.  Normalized and
     42 * denormalized (there are no unnormalized numbers at this
     43 * point) are passed onto the emulation code.  
     44 *
     45 * CMDREG1B and STAG are extracted from the fsave frame
     46 * and combined to form the table index.  The function called
     47 * will start with a0 pointing to the ETEMP operand.  Dyadic
     48 * functions can find FPTEMP at -12(a0).
     49 *
     50 * Called functions return their result in fp0.  Sincos returns
     51 * sin(x) in fp0 and cos(x) in fp1.
     52 *
     53 
     54 DO_FUNC	IDNT    2,1 Motorola 040 Floating Point Software Package
     55 
     56 	section	8
     57 
     58 	include	fpsp.h
     59 
     60 	xref	t_dz2
     61 	xref	t_operr
     62 	xref	t_inx2
     63 	xref 	t_resdnrm
     64 	xref	dst_nan
     65 	xref	src_nan
     66 	xref	nrm_set
     67 	xref	sto_cos
     68 
     69 	xref	tblpre
     70 	xref	slognp1,slogn,slog10,slog2
     71 	xref	slognd,slog10d,slog2d
     72 	xref	smod,srem
     73 	xref	sscale
     74 	xref	smovcr
     75 
     76 PONE	dc.l	$3fff0000,$80000000,$00000000	;+1
     77 MONE	dc.l	$bfff0000,$80000000,$00000000	;-1
     78 PZERO	dc.l	$00000000,$00000000,$00000000	;+0
     79 MZERO	dc.l	$80000000,$00000000,$00000000	;-0
     80 PINF	dc.l	$7fff0000,$00000000,$00000000	;+inf
     81 MINF	dc.l	$ffff0000,$00000000,$00000000	;-inf
     82 QNAN	dc.l	$7fff0000,$ffffffff,$ffffffff	;non-signaling nan
     83 PPIBY2  dc.l	$3FFF0000,$C90FDAA2,$2168C235	;+PI/2
     84 MPIBY2  dc.l	$bFFF0000,$C90FDAA2,$2168C235	;-PI/2
     85 
     86 	xdef	do_func
     87 do_func:
     88 	clr.b	CU_ONLY(a6)
     89 *
     90 * Check for fmovecr.  It does not follow the format of fp gen
     91 * unimplemented instructions.  The test is on the upper 6 bits;
     92 * if they are $17, the inst is fmovecr.  Call entry smovcr
     93 * directly.
     94 *
     95 	bfextu	CMDREG1B(a6){0:6},d0 ;get opclass and src fields
     96 	cmpi.l	#$17,d0		;if op class and size fields are $17, 
     97 *				;it is FMOVECR; if not, continue
     98 	bne.b	not_fmovecr
     99 	jmp	smovcr		;fmovecr; jmp directly to emulation
    100 
    101 not_fmovecr:
    102 	move.w	CMDREG1B(a6),d0
    103 	and.l	#$7F,d0
    104 	cmpi.l	#$38,d0		;if the extension is >= $38, 
    105 	bge.b	serror		;it is illegal
    106 	bfextu	STAG(a6){0:3},d1
    107 	lsl.l	#3,d0		;make room for STAG
    108 	add.l	d1,d0		;combine for final index into table
    109 	lea.l	tblpre,a1	;start of monster jump table
    110 	move.l	(a1,d0.w*4),a1	;real target address
    111 	lea.l	ETEMP(a6),a0	;a0 is pointer to src op
    112 	move.l	USER_FPCR(a6),d1
    113 	and.l	#$FF,d1		; discard all but rounding mode/prec
    114 	fmove.l	#0,fpcr
    115 	jmp	(a1)
    116 *
    117 *	ERROR
    118 *
    119 	xdef	serror
    120 serror:
    121 	st.b	STORE_FLG(a6)
    122 	rts
    123 *
    124 * These routines load forced values into fp0.  They are called
    125 * by index into tbldo.
    126 *
    127 * Load a signed zero to fp0 and set inex2/ainex
    128 *
    129 	xdef	snzrinx
    130 snzrinx:
    131 	btst.b	#sign_bit,LOCAL_EX(a0)	;get sign of source operand
    132 	bne.b	ld_mzinx	;if negative, branch
    133 	bsr	ld_pzero	;bsr so we can return and set inx
    134 	bra	t_inx2		;now, set the inx for the next inst
    135 ld_mzinx:
    136 	bsr	ld_mzero	;if neg, load neg zero, return here
    137 	bra	t_inx2		;now, set the inx for the next inst
    138 *
    139 * Load a signed zero to fp0; do not set inex2/ainex 
    140 *
    141 	xdef	szero
    142 szero:
    143 	btst.b	#sign_bit,LOCAL_EX(a0) ;get sign of source operand
    144 	bne	ld_mzero	;if neg, load neg zero
    145 	bra	ld_pzero	;load positive zero
    146 *
    147 * Load a signed infinity to fp0; do not set inex2/ainex 
    148 *
    149 	xdef	sinf
    150 sinf:
    151 	btst.b	#sign_bit,LOCAL_EX(a0)	;get sign of source operand
    152 	bne	ld_minf			;if negative branch
    153 	bra	ld_pinf
    154 *
    155 * Load a signed one to fp0; do not set inex2/ainex 
    156 *
    157 	xdef	sone
    158 sone:
    159 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    160 	bne	ld_mone
    161 	bra	ld_pone
    162 *
    163 * Load a signed pi/2 to fp0; do not set inex2/ainex 
    164 *
    165 	xdef	spi_2
    166 spi_2:
    167 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    168 	bne	ld_mpi2
    169 	bra	ld_ppi2
    170 *
    171 * Load either a +0 or +inf for plus/minus operand
    172 *
    173 	xdef	szr_inf
    174 szr_inf:
    175 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    176 	bne	ld_pzero
    177 	bra	ld_pinf
    178 *
    179 * Result is either an operr or +inf for plus/minus operand
    180 * [Used by slogn, slognp1, slog10, and slog2]
    181 *
    182 	xdef	sopr_inf
    183 sopr_inf:
    184 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    185 	bne	t_operr
    186 	bra	ld_pinf
    187 *
    188 *	FLOGNP1 
    189 *
    190 	xdef	sslognp1
    191 sslognp1:
    192 	fmovem.x (a0),fp0
    193 	fcmp.b	#-1,fp0
    194 	fbgt	slognp1		
    195 	fbeq	t_dz2		;if = -1, divide by zero exception
    196 	fmove.l	#0,FPSR		;clr N flag
    197 	bra	t_operr		;take care of operands < -1
    198 *
    199 *	FETOXM1
    200 *
    201 	xdef	setoxm1i
    202 setoxm1i:
    203 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    204 	bne	ld_mone
    205 	bra	ld_pinf
    206 *
    207 *	FLOGN
    208 *
    209 * Test for 1.0 as an input argument, returning +zero.  Also check
    210 * the sign and return operr if negative.
    211 *
    212 	xdef	sslogn
    213 sslogn:
    214 	btst.b	#sign_bit,LOCAL_EX(a0) 
    215 	bne	t_operr		;take care of operands < 0
    216 	cmpi.w	#$3fff,LOCAL_EX(a0) ;test for 1.0 input
    217 	bne	slogn
    218 	cmpi.l	#$80000000,LOCAL_HI(a0)
    219 	bne	slogn
    220 	tst.l	LOCAL_LO(a0)
    221 	bne	slogn
    222 	fmove.x	PZERO,fp0
    223 	rts
    224 
    225 	xdef	sslognd
    226 sslognd:
    227 	btst.b	#sign_bit,LOCAL_EX(a0) 
    228 	beq	slognd
    229 	bra	t_operr		;take care of operands < 0
    230 
    231 *
    232 *	FLOG10
    233 *
    234 	xdef	sslog10
    235 sslog10:
    236 	btst.b	#sign_bit,LOCAL_EX(a0)
    237 	bne	t_operr		;take care of operands < 0
    238 	cmpi.w	#$3fff,LOCAL_EX(a0) ;test for 1.0 input
    239 	bne	slog10
    240 	cmpi.l	#$80000000,LOCAL_HI(a0)
    241 	bne	slog10
    242 	tst.l	LOCAL_LO(a0)
    243 	bne	slog10
    244 	fmove.x	PZERO,fp0
    245 	rts
    246 
    247 	xdef	sslog10d
    248 sslog10d:
    249 	btst.b	#sign_bit,LOCAL_EX(a0) 
    250 	beq	slog10d
    251 	bra	t_operr		;take care of operands < 0
    252 
    253 *
    254 *	FLOG2
    255 *
    256 	xdef	sslog2
    257 sslog2:
    258 	btst.b	#sign_bit,LOCAL_EX(a0)
    259 	bne	t_operr		;take care of operands < 0
    260 	cmpi.w	#$3fff,LOCAL_EX(a0) ;test for 1.0 input
    261 	bne	slog2
    262 	cmpi.l	#$80000000,LOCAL_HI(a0)
    263 	bne	slog2
    264 	tst.l	LOCAL_LO(a0)
    265 	bne	slog2
    266 	fmove.x	PZERO,fp0
    267 	rts
    268 
    269 	xdef	sslog2d
    270 sslog2d:
    271 	btst.b	#sign_bit,LOCAL_EX(a0) 
    272 	beq	slog2d
    273 	bra	t_operr		;take care of operands < 0
    274 
    275 *
    276 *	FMOD
    277 *
    278 pmodt:
    279 *				;$21 fmod
    280 *				;dtag,stag
    281 	dc.l	smod		;  00,00  norm,norm = normal
    282 	dc.l	smod_oper	;  00,01  norm,zero = nan with operr
    283 	dc.l	smod_fpn	;  00,10  norm,inf  = fpn
    284 	dc.l	smod_snan	;  00,11  norm,nan  = nan
    285 	dc.l	smod_zro	;  01,00  zero,norm = +-zero
    286 	dc.l	smod_oper	;  01,01  zero,zero = nan with operr
    287 	dc.l	smod_zro	;  01,10  zero,inf  = +-zero
    288 	dc.l	smod_snan	;  01,11  zero,nan  = nan
    289 	dc.l	smod_oper	;  10,00  inf,norm  = nan with operr
    290 	dc.l	smod_oper	;  10,01  inf,zero  = nan with operr
    291 	dc.l	smod_oper	;  10,10  inf,inf   = nan with operr
    292 	dc.l	smod_snan	;  10,11  inf,nan   = nan
    293 	dc.l	smod_dnan	;  11,00  nan,norm  = nan
    294 	dc.l	smod_dnan	;  11,01  nan,zero  = nan
    295 	dc.l	smod_dnan	;  11,10  nan,inf   = nan
    296 	dc.l	smod_dnan	;  11,11  nan,nan   = nan
    297 
    298 	xdef	pmod
    299 pmod:
    300 	clr.b	FPSR_QBYTE(a6) ; clear quotient field
    301 	bfextu	STAG(a6){0:3},d0 ;stag = d0
    302 	bfextu	DTAG(a6){0:3},d1 ;dtag = d1
    303 
    304 *
    305 * Alias extended denorms to norms for the jump table.
    306 *
    307 	bclr.l	#2,d0
    308 	bclr.l	#2,d1
    309 
    310 	lsl.b	#2,d1
    311 	or.b	d0,d1		;d1{3:2} = dtag, d1{1:0} = stag
    312 *				;Tag values:
    313 *				;00 = norm or denorm
    314 *				;01 = zero
    315 *				;10 = inf
    316 *				;11 = nan
    317 	lea	pmodt,a1
    318 	move.l	(a1,d1.w*4),a1
    319 	jmp	(a1)
    320 
    321 smod_snan:
    322 	bra	src_nan
    323 smod_dnan:
    324 	bra	dst_nan
    325 smod_oper:
    326 	bra	t_operr
    327 smod_zro:
    328 	move.b	ETEMP(a6),d1	;get sign of src op
    329 	move.b	FPTEMP(a6),d0	;get sign of dst op
    330 	eor.b	d0,d1		;get exor of sign bits
    331 	btst.l	#7,d1		;test for sign
    332 	beq.b	smod_zsn	;if clr, do not set sign big
    333 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    334 smod_zsn:
    335 	btst.l	#7,d0		;test if + or -
    336 	beq	ld_pzero	;if pos then load +0
    337 	bra	ld_mzero	;else neg load -0
    338 	
    339 smod_fpn:
    340 	move.b	ETEMP(a6),d1	;get sign of src op
    341 	move.b	FPTEMP(a6),d0	;get sign of dst op
    342 	eor.b	d0,d1		;get exor of sign bits
    343 	btst.l	#7,d1		;test for sign
    344 	beq.b	smod_fsn	;if clr, do not set sign big
    345 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    346 smod_fsn:
    347 	tst.b	DTAG(a6)	;filter out denormal destination case
    348 	bpl.b	smod_nrm	;
    349 	lea.l	FPTEMP(a6),a0	;a0<- addr(FPTEMP)
    350 	bra	t_resdnrm	;force UNFL(but exact) result
    351 smod_nrm:
    352 	fmove.l USER_FPCR(a6),fpcr ;use user's rmode and precision
    353 	fmove.x FPTEMP(a6),fp0	;return dest to fp0
    354 	rts
    355 		
    356 *
    357 *	FREM
    358 *
    359 premt:
    360 *				;$25 frem
    361 *				;dtag,stag
    362 	dc.l	srem		;  00,00  norm,norm = normal
    363 	dc.l	srem_oper	;  00,01  norm,zero = nan with operr
    364 	dc.l	srem_fpn	;  00,10  norm,inf  = fpn
    365 	dc.l	srem_snan	;  00,11  norm,nan  = nan
    366 	dc.l	srem_zro	;  01,00  zero,norm = +-zero
    367 	dc.l	srem_oper	;  01,01  zero,zero = nan with operr
    368 	dc.l	srem_zro	;  01,10  zero,inf  = +-zero
    369 	dc.l	srem_snan	;  01,11  zero,nan  = nan
    370 	dc.l	srem_oper	;  10,00  inf,norm  = nan with operr
    371 	dc.l	srem_oper	;  10,01  inf,zero  = nan with operr
    372 	dc.l	srem_oper	;  10,10  inf,inf   = nan with operr
    373 	dc.l	srem_snan	;  10,11  inf,nan   = nan
    374 	dc.l	srem_dnan	;  11,00  nan,norm  = nan
    375 	dc.l	srem_dnan	;  11,01  nan,zero  = nan
    376 	dc.l	srem_dnan	;  11,10  nan,inf   = nan
    377 	dc.l	srem_dnan	;  11,11  nan,nan   = nan
    378 
    379 	xdef	prem
    380 prem:
    381 	clr.b	FPSR_QBYTE(a6)   ;clear quotient field
    382 	bfextu	STAG(a6){0:3},d0 ;stag = d0
    383 	bfextu	DTAG(a6){0:3},d1 ;dtag = d1
    384 *
    385 * Alias extended denorms to norms for the jump table.
    386 *
    387 	bclr	#2,d0
    388 	bclr	#2,d1
    389 
    390 	lsl.b	#2,d1
    391 	or.b	d0,d1		;d1{3:2} = dtag, d1{1:0} = stag
    392 *				;Tag values:
    393 *				;00 = norm or denorm
    394 *				;01 = zero
    395 *				;10 = inf
    396 *				;11 = nan
    397 	lea	premt,a1
    398 	move.l	(a1,d1.w*4),a1
    399 	jmp	(a1)
    400 	
    401 srem_snan:
    402 	bra	src_nan
    403 srem_dnan:
    404 	bra	dst_nan
    405 srem_oper:
    406 	bra	t_operr
    407 srem_zro:
    408 	move.b	ETEMP(a6),d1	;get sign of src op
    409 	move.b	FPTEMP(a6),d0	;get sign of dst op
    410 	eor.b	d0,d1		;get exor of sign bits
    411 	btst.l	#7,d1		;test for sign
    412 	beq.b	srem_zsn	;if clr, do not set sign big
    413 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    414 srem_zsn:
    415 	btst.l	#7,d0		;test if + or -
    416 	beq	ld_pzero	;if pos then load +0
    417 	bra	ld_mzero	;else neg load -0
    418 	
    419 srem_fpn:
    420 	move.b	ETEMP(a6),d1	;get sign of src op
    421 	move.b	FPTEMP(a6),d0	;get sign of dst op
    422 	eor.b	d0,d1		;get exor of sign bits
    423 	btst.l	#7,d1		;test for sign
    424 	beq.b	srem_fsn	;if clr, do not set sign big
    425 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    426 srem_fsn:
    427 	tst.b	DTAG(a6)	;filter out denormal destination case
    428 	bpl.b	srem_nrm	;
    429 	lea.l	FPTEMP(a6),a0	;a0<- addr(FPTEMP)
    430 	bra	t_resdnrm	;force UNFL(but exact) result
    431 srem_nrm:
    432 	fmove.l USER_FPCR(a6),fpcr ;use user's rmode and precision
    433 	fmove.x FPTEMP(a6),fp0	;return dest to fp0
    434 	rts
    435 *
    436 *	FSCALE
    437 *
    438 pscalet:
    439 *				;$26 fscale
    440 *				;dtag,stag
    441 	dc.l	sscale		;  00,00  norm,norm = result
    442 	dc.l	sscale		;  00,01  norm,zero = fpn
    443 	dc.l	scl_opr		;  00,10  norm,inf  = nan with operr
    444 	dc.l	scl_snan	;  00,11  norm,nan  = nan
    445 	dc.l	scl_zro		;  01,00  zero,norm = +-zero
    446 	dc.l	scl_zro		;  01,01  zero,zero = +-zero
    447 	dc.l	scl_opr		;  01,10  zero,inf  = nan with operr
    448 	dc.l	scl_snan	;  01,11  zero,nan  = nan
    449 	dc.l	scl_inf		;  10,00  inf,norm  = +-inf
    450 	dc.l	scl_inf		;  10,01  inf,zero  = +-inf
    451 	dc.l	scl_opr		;  10,10  inf,inf   = nan with operr
    452  	dc.l	scl_snan	;  10,11  inf,nan   = nan
    453  	dc.l	scl_dnan	;  11,00  nan,norm  = nan
    454  	dc.l	scl_dnan	;  11,01  nan,zero  = nan
    455  	dc.l	scl_dnan	;  11,10  nan,inf   = nan
    456 	dc.l	scl_dnan	;  11,11  nan,nan   = nan
    457 
    458 	xdef	pscale
    459 pscale:
    460 	bfextu	STAG(a6){0:3},d0 ;stag in d0
    461 	bfextu	DTAG(a6){0:3},d1 ;dtag in d1
    462 	bclr.l	#2,d0		;alias  denorm into norm
    463 	bclr.l	#2,d1		;alias  denorm into norm
    464 	lsl.b	#2,d1
    465 	or.b	d0,d1		;d1{4:2} = dtag, d1{1:0} = stag
    466 *				;dtag values     stag values:
    467 *				;000 = norm      00 = norm
    468 *				;001 = zero	 01 = zero
    469 *				;010 = inf	 10 = inf
    470 *				;011 = nan	 11 = nan
    471 *				;100 = dnrm
    472 *
    473 *
    474 	lea.l	pscalet,a1	;load start of jump table
    475 	move.l	(a1,d1.w*4),a1	;load a1 with label depending on tag
    476 	jmp	(a1)		;go to the routine
    477 
    478 scl_opr:
    479 	bra	t_operr
    480 
    481 scl_dnan:
    482 	bra	dst_nan
    483 
    484 scl_zro:
    485 	btst.b	#sign_bit,FPTEMP_EX(a6)	;test if + or -
    486 	beq	ld_pzero		;if pos then load +0
    487 	bra	ld_mzero		;if neg then load -0
    488 scl_inf:
    489 	btst.b	#sign_bit,FPTEMP_EX(a6)	;test if + or -
    490 	beq	ld_pinf			;if pos then load +inf
    491 	bra	ld_minf			;else neg load -inf
    492 scl_snan:
    493 	bra	src_nan
    494 *
    495 *	FSINCOS
    496 *
    497 	xdef	ssincosz
    498 ssincosz:
    499 	btst.b	#sign_bit,ETEMP(a6)	;get sign
    500 	beq.b	sincosp
    501 	fmove.x	MZERO,fp0
    502 	bra.b	sincoscom
    503 sincosp:
    504 	fmove.x PZERO,fp0
    505 sincoscom:
    506   	fmovem.x PONE,fp1	;do not allow FPSR to be affected
    507 	bra	sto_cos		;store cosine result
    508 
    509 	xdef	ssincosi
    510 ssincosi:
    511 	fmove.x QNAN,fp1	;load NAN
    512 	bsr	sto_cos		;store cosine result
    513 	fmove.x QNAN,fp0	;load NAN
    514 	bra	t_operr
    515 
    516 	xdef	ssincosnan
    517 ssincosnan:
    518 	move.l	ETEMP_EX(a6),FP_SCR1(a6)
    519 	move.l	ETEMP_HI(a6),FP_SCR1+4(a6)
    520 	move.l	ETEMP_LO(a6),FP_SCR1+8(a6)
    521 	bset.b	#signan_bit,FP_SCR1+4(a6)
    522 	fmovem.x FP_SCR1(a6),fp1
    523 	bsr	sto_cos
    524 	bra	src_nan
    525 *
    526 * This code forces default values for the zero, inf, and nan cases 
    527 * in the transcendentals code.  The CC bits must be set in the
    528 * stacked FPSR to be correctly reported.
    529 *
    530 ***Returns +PI/2
    531 	xdef	ld_ppi2
    532 ld_ppi2:
    533 	fmove.x PPIBY2,fp0		;load +pi/2
    534 	bra	t_inx2			;set inex2 exc
    535 
    536 ***Returns -PI/2
    537 	xdef	ld_mpi2
    538 ld_mpi2:
    539 	fmove.x MPIBY2,fp0		;load -pi/2
    540 	or.l	#neg_mask,USER_FPSR(a6)	;set N bit
    541 	bra	t_inx2			;set inex2 exc
    542 
    543 ***Returns +inf
    544 	xdef	ld_pinf
    545 ld_pinf:
    546 	fmove.x PINF,fp0		;load +inf
    547 	or.l	#inf_mask,USER_FPSR(a6)	;set I bit
    548 	rts
    549 
    550 ***Returns -inf
    551 	xdef	ld_minf
    552 ld_minf:
    553 	fmove.x MINF,fp0		;load -inf
    554 	or.l	#neg_mask+inf_mask,USER_FPSR(a6)	;set N and I bits
    555 	rts
    556 
    557 ***Returns +1
    558 	xdef	ld_pone
    559 ld_pone:
    560 	fmove.x PONE,fp0		;load +1
    561 	rts
    562 
    563 ***Returns -1
    564 	xdef	ld_mone
    565 ld_mone:
    566 	fmove.x MONE,fp0		;load -1
    567 	or.l	#neg_mask,USER_FPSR(a6)	;set N bit
    568 	rts
    569 
    570 ***Returns +0
    571 	xdef	ld_pzero
    572 ld_pzero:
    573 	fmove.x PZERO,fp0		;load +0
    574 	or.l	#z_mask,USER_FPSR(a6)	;set Z bit
    575 	rts
    576 
    577 ***Returns -0
    578 	xdef	ld_mzero
    579 ld_mzero:
    580 	fmove.x MZERO,fp0		;load -0
    581 	or.l	#neg_mask+z_mask,USER_FPSR(a6)	;set N and Z bits
    582 	rts
    583 
    584 	end
    585