Home | History | Annotate | Line # | Download | only in fpsp
      1 *	$NetBSD: do_func.sa,v 1.3 2001/12/09 01:43:13 briggs 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	short_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 short_serror:
    122 	st.b	STORE_FLG(a6)
    123 	rts
    124 *
    125 * These routines load forced values into fp0.  They are called
    126 * by index into tbldo.
    127 *
    128 * Load a signed zero to fp0 and set inex2/ainex
    129 *
    130 	xdef	snzrinx
    131 snzrinx:
    132 	btst.b	#sign_bit,LOCAL_EX(a0)	;get sign of source operand
    133 	bne.b	ld_mzinx	;if negative, branch
    134 	bsr	ld_pzero	;bsr so we can return and set inx
    135 	bra	t_inx2		;now, set the inx for the next inst
    136 ld_mzinx:
    137 	bsr	ld_mzero	;if neg, load neg zero, return here
    138 	bra	t_inx2		;now, set the inx for the next inst
    139 *
    140 * Load a signed zero to fp0; do not set inex2/ainex 
    141 *
    142 	xdef	szero
    143 szero:
    144 	btst.b	#sign_bit,LOCAL_EX(a0) ;get sign of source operand
    145 	bne	ld_mzero	;if neg, load neg zero
    146 	bra	ld_pzero	;load positive zero
    147 *
    148 * Load a signed infinity to fp0; do not set inex2/ainex 
    149 *
    150 	xdef	sinf
    151 sinf:
    152 	btst.b	#sign_bit,LOCAL_EX(a0)	;get sign of source operand
    153 	bne	ld_minf			;if negative branch
    154 	bra	ld_pinf
    155 *
    156 * Load a signed one to fp0; do not set inex2/ainex 
    157 *
    158 	xdef	sone
    159 sone:
    160 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    161 	bne	ld_mone
    162 	bra	ld_pone
    163 *
    164 * Load a signed pi/2 to fp0; do not set inex2/ainex 
    165 *
    166 	xdef	spi_2
    167 spi_2:
    168 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    169 	bne	ld_mpi2
    170 	bra	ld_ppi2
    171 *
    172 * Load either a +0 or +inf for plus/minus operand
    173 *
    174 	xdef	szr_inf
    175 szr_inf:
    176 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    177 	bne	ld_pzero
    178 	bra	ld_pinf
    179 *
    180 * Result is either an operr or +inf for plus/minus operand
    181 * [Used by slogn, slognp1, slog10, and slog2]
    182 *
    183 	xdef	sopr_inf
    184 sopr_inf:
    185 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    186 	bne	t_operr
    187 	bra	ld_pinf
    188 *
    189 *	FLOGNP1 
    190 *
    191 	xdef	sslognp1
    192 sslognp1:
    193 	fmovem.x (a0),fp0
    194 	fcmp.b	#-1,fp0
    195 	fbgt	slognp1		
    196 	fbeq	t_dz2		;if = -1, divide by zero exception
    197 	fmove.l	#0,FPSR		;clr N flag
    198 	bra	t_operr		;take care of operands < -1
    199 *
    200 *	FETOXM1
    201 *
    202 	xdef	setoxm1i
    203 setoxm1i:
    204 	btst.b	#sign_bit,LOCAL_EX(a0)	;check sign of source
    205 	bne	ld_mone
    206 	bra	ld_pinf
    207 *
    208 *	FLOGN
    209 *
    210 * Test for 1.0 as an input argument, returning +zero.  Also check
    211 * the sign and return operr if negative.
    212 *
    213 	xdef	sslogn
    214 sslogn:
    215 	btst.b	#sign_bit,LOCAL_EX(a0) 
    216 	bne	t_operr		;take care of operands < 0
    217 	cmpi.w	#$3fff,LOCAL_EX(a0) ;test for 1.0 input
    218 	bne	slogn
    219 	cmpi.l	#$80000000,LOCAL_HI(a0)
    220 	bne	slogn
    221 	tst.l	LOCAL_LO(a0)
    222 	bne	slogn
    223 	fmove.x	PZERO,fp0
    224 	rts
    225 
    226 	xdef	sslognd
    227 sslognd:
    228 	btst.b	#sign_bit,LOCAL_EX(a0) 
    229 	beq	slognd
    230 	bra	t_operr		;take care of operands < 0
    231 
    232 *
    233 *	FLOG10
    234 *
    235 	xdef	sslog10
    236 sslog10:
    237 	btst.b	#sign_bit,LOCAL_EX(a0)
    238 	bne	t_operr		;take care of operands < 0
    239 	cmpi.w	#$3fff,LOCAL_EX(a0) ;test for 1.0 input
    240 	bne	slog10
    241 	cmpi.l	#$80000000,LOCAL_HI(a0)
    242 	bne	slog10
    243 	tst.l	LOCAL_LO(a0)
    244 	bne	slog10
    245 	fmove.x	PZERO,fp0
    246 	rts
    247 
    248 	xdef	sslog10d
    249 sslog10d:
    250 	btst.b	#sign_bit,LOCAL_EX(a0) 
    251 	beq	slog10d
    252 	bra	t_operr		;take care of operands < 0
    253 
    254 *
    255 *	FLOG2
    256 *
    257 	xdef	sslog2
    258 sslog2:
    259 	btst.b	#sign_bit,LOCAL_EX(a0)
    260 	bne	t_operr		;take care of operands < 0
    261 	cmpi.w	#$3fff,LOCAL_EX(a0) ;test for 1.0 input
    262 	bne	slog2
    263 	cmpi.l	#$80000000,LOCAL_HI(a0)
    264 	bne	slog2
    265 	tst.l	LOCAL_LO(a0)
    266 	bne	slog2
    267 	fmove.x	PZERO,fp0
    268 	rts
    269 
    270 	xdef	sslog2d
    271 sslog2d:
    272 	btst.b	#sign_bit,LOCAL_EX(a0) 
    273 	beq	slog2d
    274 	bra	t_operr		;take care of operands < 0
    275 
    276 *
    277 *	FMOD
    278 *
    279 pmodt:
    280 *				;$21 fmod
    281 *				;dtag,stag
    282 	dc.l	smod		;  00,00  norm,norm = normal
    283 	dc.l	smod_oper	;  00,01  norm,zero = nan with operr
    284 	dc.l	smod_fpn	;  00,10  norm,inf  = fpn
    285 	dc.l	smod_snan	;  00,11  norm,nan  = nan
    286 	dc.l	smod_zro	;  01,00  zero,norm = +-zero
    287 	dc.l	smod_oper	;  01,01  zero,zero = nan with operr
    288 	dc.l	smod_zro	;  01,10  zero,inf  = +-zero
    289 	dc.l	smod_snan	;  01,11  zero,nan  = nan
    290 	dc.l	smod_oper	;  10,00  inf,norm  = nan with operr
    291 	dc.l	smod_oper	;  10,01  inf,zero  = nan with operr
    292 	dc.l	smod_oper	;  10,10  inf,inf   = nan with operr
    293 	dc.l	smod_snan	;  10,11  inf,nan   = nan
    294 	dc.l	smod_dnan	;  11,00  nan,norm  = nan
    295 	dc.l	smod_dnan	;  11,01  nan,zero  = nan
    296 	dc.l	smod_dnan	;  11,10  nan,inf   = nan
    297 	dc.l	smod_dnan	;  11,11  nan,nan   = nan
    298 
    299 	xdef	pmod
    300 pmod:
    301 	clr.b	FPSR_QBYTE(a6) ; clear quotient field
    302 	bfextu	STAG(a6){0:3},d0 ;stag = d0
    303 	bfextu	DTAG(a6){0:3},d1 ;dtag = d1
    304 
    305 *
    306 * Alias extended denorms to norms for the jump table.
    307 *
    308 	bclr.l	#2,d0
    309 	bclr.l	#2,d1
    310 
    311 	lsl.b	#2,d1
    312 	or.b	d0,d1		;d1{3:2} = dtag, d1{1:0} = stag
    313 *				;Tag values:
    314 *				;00 = norm or denorm
    315 *				;01 = zero
    316 *				;10 = inf
    317 *				;11 = nan
    318 	lea	pmodt,a1
    319 	move.l	(a1,d1.w*4),a1
    320 	jmp	(a1)
    321 
    322 smod_snan:
    323 	bra	src_nan
    324 smod_dnan:
    325 	bra	dst_nan
    326 smod_oper:
    327 	bra	t_operr
    328 smod_zro:
    329 	move.b	ETEMP(a6),d1	;get sign of src op
    330 	move.b	FPTEMP(a6),d0	;get sign of dst op
    331 	eor.b	d0,d1		;get exor of sign bits
    332 	btst.l	#7,d1		;test for sign
    333 	beq.b	smod_zsn	;if clr, do not set sign big
    334 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    335 smod_zsn:
    336 	btst.l	#7,d0		;test if + or -
    337 	beq	ld_pzero	;if pos then load +0
    338 	bra	ld_mzero	;else neg load -0
    339 	
    340 smod_fpn:
    341 	move.b	ETEMP(a6),d1	;get sign of src op
    342 	move.b	FPTEMP(a6),d0	;get sign of dst op
    343 	eor.b	d0,d1		;get exor of sign bits
    344 	btst.l	#7,d1		;test for sign
    345 	beq.b	smod_fsn	;if clr, do not set sign big
    346 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    347 smod_fsn:
    348 	tst.b	DTAG(a6)	;filter out denormal destination case
    349 	bpl.b	smod_nrm	;
    350 	lea.l	FPTEMP(a6),a0	;a0<- addr(FPTEMP)
    351 	bra	t_resdnrm	;force UNFL(but exact) result
    352 smod_nrm:
    353 	fmove.l USER_FPCR(a6),fpcr ;use user's rmode and precision
    354 	fmove.x FPTEMP(a6),fp0	;return dest to fp0
    355 	rts
    356 		
    357 *
    358 *	FREM
    359 *
    360 premt:
    361 *				;$25 frem
    362 *				;dtag,stag
    363 	dc.l	srem		;  00,00  norm,norm = normal
    364 	dc.l	srem_oper	;  00,01  norm,zero = nan with operr
    365 	dc.l	srem_fpn	;  00,10  norm,inf  = fpn
    366 	dc.l	srem_snan	;  00,11  norm,nan  = nan
    367 	dc.l	srem_zro	;  01,00  zero,norm = +-zero
    368 	dc.l	srem_oper	;  01,01  zero,zero = nan with operr
    369 	dc.l	srem_zro	;  01,10  zero,inf  = +-zero
    370 	dc.l	srem_snan	;  01,11  zero,nan  = nan
    371 	dc.l	srem_oper	;  10,00  inf,norm  = nan with operr
    372 	dc.l	srem_oper	;  10,01  inf,zero  = nan with operr
    373 	dc.l	srem_oper	;  10,10  inf,inf   = nan with operr
    374 	dc.l	srem_snan	;  10,11  inf,nan   = nan
    375 	dc.l	srem_dnan	;  11,00  nan,norm  = nan
    376 	dc.l	srem_dnan	;  11,01  nan,zero  = nan
    377 	dc.l	srem_dnan	;  11,10  nan,inf   = nan
    378 	dc.l	srem_dnan	;  11,11  nan,nan   = nan
    379 
    380 	xdef	prem
    381 prem:
    382 	clr.b	FPSR_QBYTE(a6)   ;clear quotient field
    383 	bfextu	STAG(a6){0:3},d0 ;stag = d0
    384 	bfextu	DTAG(a6){0:3},d1 ;dtag = d1
    385 *
    386 * Alias extended denorms to norms for the jump table.
    387 *
    388 	bclr	#2,d0
    389 	bclr	#2,d1
    390 
    391 	lsl.b	#2,d1
    392 	or.b	d0,d1		;d1{3:2} = dtag, d1{1:0} = stag
    393 *				;Tag values:
    394 *				;00 = norm or denorm
    395 *				;01 = zero
    396 *				;10 = inf
    397 *				;11 = nan
    398 	lea	premt,a1
    399 	move.l	(a1,d1.w*4),a1
    400 	jmp	(a1)
    401 	
    402 srem_snan:
    403 	bra	src_nan
    404 srem_dnan:
    405 	bra	dst_nan
    406 srem_oper:
    407 	bra	t_operr
    408 srem_zro:
    409 	move.b	ETEMP(a6),d1	;get sign of src op
    410 	move.b	FPTEMP(a6),d0	;get sign of dst op
    411 	eor.b	d0,d1		;get exor of sign bits
    412 	btst.l	#7,d1		;test for sign
    413 	beq.b	srem_zsn	;if clr, do not set sign big
    414 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    415 srem_zsn:
    416 	btst.l	#7,d0		;test if + or -
    417 	beq	ld_pzero	;if pos then load +0
    418 	bra	ld_mzero	;else neg load -0
    419 	
    420 srem_fpn:
    421 	move.b	ETEMP(a6),d1	;get sign of src op
    422 	move.b	FPTEMP(a6),d0	;get sign of dst op
    423 	eor.b	d0,d1		;get exor of sign bits
    424 	btst.l	#7,d1		;test for sign
    425 	beq.b	srem_fsn	;if clr, do not set sign big
    426 	bset.b	#q_sn_bit,FPSR_QBYTE(a6) ;set q-byte sign bit
    427 srem_fsn:
    428 	tst.b	DTAG(a6)	;filter out denormal destination case
    429 	bpl.b	srem_nrm	;
    430 	lea.l	FPTEMP(a6),a0	;a0<- addr(FPTEMP)
    431 	bra	t_resdnrm	;force UNFL(but exact) result
    432 srem_nrm:
    433 	fmove.l USER_FPCR(a6),fpcr ;use user's rmode and precision
    434 	fmove.x FPTEMP(a6),fp0	;return dest to fp0
    435 	rts
    436 *
    437 *	FSCALE
    438 *
    439 pscalet:
    440 *				;$26 fscale
    441 *				;dtag,stag
    442 	dc.l	sscale		;  00,00  norm,norm = result
    443 	dc.l	sscale		;  00,01  norm,zero = fpn
    444 	dc.l	scl_opr		;  00,10  norm,inf  = nan with operr
    445 	dc.l	scl_snan	;  00,11  norm,nan  = nan
    446 	dc.l	scl_zro		;  01,00  zero,norm = +-zero
    447 	dc.l	scl_zro		;  01,01  zero,zero = +-zero
    448 	dc.l	scl_opr		;  01,10  zero,inf  = nan with operr
    449 	dc.l	scl_snan	;  01,11  zero,nan  = nan
    450 	dc.l	scl_inf		;  10,00  inf,norm  = +-inf
    451 	dc.l	scl_inf		;  10,01  inf,zero  = +-inf
    452 	dc.l	scl_opr		;  10,10  inf,inf   = nan with operr
    453  	dc.l	scl_snan	;  10,11  inf,nan   = nan
    454  	dc.l	scl_dnan	;  11,00  nan,norm  = nan
    455  	dc.l	scl_dnan	;  11,01  nan,zero  = nan
    456  	dc.l	scl_dnan	;  11,10  nan,inf   = nan
    457 	dc.l	scl_dnan	;  11,11  nan,nan   = nan
    458 
    459 	xdef	pscale
    460 pscale:
    461 	bfextu	STAG(a6){0:3},d0 ;stag in d0
    462 	bfextu	DTAG(a6){0:3},d1 ;dtag in d1
    463 	bclr.l	#2,d0		;alias  denorm into norm
    464 	bclr.l	#2,d1		;alias  denorm into norm
    465 	lsl.b	#2,d1
    466 	or.b	d0,d1		;d1{4:2} = dtag, d1{1:0} = stag
    467 *				;dtag values     stag values:
    468 *				;000 = norm      00 = norm
    469 *				;001 = zero	 01 = zero
    470 *				;010 = inf	 10 = inf
    471 *				;011 = nan	 11 = nan
    472 *				;100 = dnrm
    473 *
    474 *
    475 	lea.l	pscalet,a1	;load start of jump table
    476 	move.l	(a1,d1.w*4),a1	;load a1 with label depending on tag
    477 	jmp	(a1)		;go to the routine
    478 
    479 scl_opr:
    480 	bra	t_operr
    481 
    482 scl_dnan:
    483 	bra	dst_nan
    484 
    485 scl_zro:
    486 	btst.b	#sign_bit,FPTEMP_EX(a6)	;test if + or -
    487 	beq	ld_pzero		;if pos then load +0
    488 	bra	ld_mzero		;if neg then load -0
    489 scl_inf:
    490 	btst.b	#sign_bit,FPTEMP_EX(a6)	;test if + or -
    491 	beq	ld_pinf			;if pos then load +inf
    492 	bra	ld_minf			;else neg load -inf
    493 scl_snan:
    494 	bra	src_nan
    495 *
    496 *	FSINCOS
    497 *
    498 	xdef	ssincosz
    499 ssincosz:
    500 	btst.b	#sign_bit,ETEMP(a6)	;get sign
    501 	beq.b	sincosp
    502 	fmove.x	MZERO,fp0
    503 	bra.b	sincoscom
    504 sincosp:
    505 	fmove.x PZERO,fp0
    506 sincoscom:
    507   	fmovem.x PONE,fp1	;do not allow FPSR to be affected
    508 	bra	sto_cos		;store cosine result
    509 
    510 	xdef	ssincosi
    511 ssincosi:
    512 	fmove.x QNAN,fp1	;load NAN
    513 	bsr	sto_cos		;store cosine result
    514 	fmove.x QNAN,fp0	;load NAN
    515 	bra	t_operr
    516 
    517 	xdef	ssincosnan
    518 ssincosnan:
    519 	move.l	ETEMP_EX(a6),FP_SCR1(a6)
    520 	move.l	ETEMP_HI(a6),FP_SCR1+4(a6)
    521 	move.l	ETEMP_LO(a6),FP_SCR1+8(a6)
    522 	bset.b	#signan_bit,FP_SCR1+4(a6)
    523 	fmovem.x FP_SCR1(a6),fp1
    524 	bsr	sto_cos
    525 	bra	src_nan
    526 *
    527 * This code forces default values for the zero, inf, and nan cases 
    528 * in the transcendentals code.  The CC bits must be set in the
    529 * stacked FPSR to be correctly reported.
    530 *
    531 ***Returns +PI/2
    532 	xdef	ld_ppi2
    533 ld_ppi2:
    534 	fmove.x PPIBY2,fp0		;load +pi/2
    535 	bra	t_inx2			;set inex2 exc
    536 
    537 ***Returns -PI/2
    538 	xdef	ld_mpi2
    539 ld_mpi2:
    540 	fmove.x MPIBY2,fp0		;load -pi/2
    541 	or.l	#neg_mask,USER_FPSR(a6)	;set N bit
    542 	bra	t_inx2			;set inex2 exc
    543 
    544 ***Returns +inf
    545 	xdef	ld_pinf
    546 ld_pinf:
    547 	fmove.x PINF,fp0		;load +inf
    548 	or.l	#inf_mask,USER_FPSR(a6)	;set I bit
    549 	rts
    550 
    551 ***Returns -inf
    552 	xdef	ld_minf
    553 ld_minf:
    554 	fmove.x MINF,fp0		;load -inf
    555 	or.l	#neg_mask+inf_mask,USER_FPSR(a6)	;set N and I bits
    556 	rts
    557 
    558 ***Returns +1
    559 	xdef	ld_pone
    560 ld_pone:
    561 	fmove.x PONE,fp0		;load +1
    562 	rts
    563 
    564 ***Returns -1
    565 	xdef	ld_mone
    566 ld_mone:
    567 	fmove.x MONE,fp0		;load -1
    568 	or.l	#neg_mask,USER_FPSR(a6)	;set N bit
    569 	rts
    570 
    571 ***Returns +0
    572 	xdef	ld_pzero
    573 ld_pzero:
    574 	fmove.x PZERO,fp0		;load +0
    575 	or.l	#z_mask,USER_FPSR(a6)	;set Z bit
    576 	rts
    577 
    578 ***Returns -0
    579 	xdef	ld_mzero
    580 ld_mzero:
    581 	fmove.x MZERO,fp0		;load -0
    582 	or.l	#neg_mask+z_mask,USER_FPSR(a6)	;set N and Z bits
    583 	rts
    584 
    585 	end
    586