1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
/*
* expandsf.s
*
* Expands a single float into a flag byte, a sign byte, an exponent,
* and a mantissa.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Librcx floating point code, released May 27, 1999.
*
* The Initial Developer of the Original Code is Kekoa Proudfoot.
* Portions created by Kekoa Proudfoot are Copyright (C) 1999
* Kekoa Proudfoot. All Rights Reserved.
*
* Contributor(s): Kekoa Proudfoot <kekoa@graphics.stanford.edu>
*/
.section .text
;;
;; function: expandsf
;; input: float in r5r6
;; output: flags in r3h, sign in r3l, exp in r4, mant in r5r6
;; flag bits: 0=zero, 1=inf, 2=nan
;;
.global ___expandsf
___expandsf:
; Clear flag byte
sub.b r3h,r3h ; clear flags (r3h)
; Extract sign (to r3l)
mov.b r5h,r3l ; extract byte
and.b #0x80,r3l ; mask to get sign bit
; Extract exponent (to r4)
sub.w r4,r4 ; clear exponent (r4)
mov.b r5h,r4l ; copy upper 7 bits of exponent from r5h
bld #7,r5l ; load lsb to carry (lsb is msb of r5l)
rotxl.b r4l ; rotate to align
; Clear upper mantissa bit (mantissa is in r5l r6h r6l)
bclr #7,r5l ; clear upper bit of second mantissa byte
; Upper byte of mantissa (r5h) as a temporary, for now
; Set it to non-zero if mantissa (r5l r6h r6l) is non-zero
mov.b r5l,r5h ; set temp (r5h) non-zero if mantissa non-zero
or.b r6h,r5h
or.b r6l,r5h
; Is the exponent non-zero? Note r4h is known to be zero.
mov.b r4l,r4l ; if exponent (r4l) non-zero
beq else_0
; Does the exponent indicate infinity or NaN? Note r4h is zero.
cmp.b #0xff,r4l ; if exponent (r4l) is ff
bne endif_1
; Set the infinity flag if the mantissa is zero
; Set the NaN flag if the mantissa is non-zero
; Use temp in r5h to see if mantissa is zero or not
add.b #0xff,r5h ; set carry if temp non-zero (destroying temp)
bist #1,r3h ; set inf flag to ~carry (mantissa zero)
bst #2,r3h ; set nan flag to carry (mantissa non-zero)
; Make exponent huge so it dominates finites
; Simplifies e.g. adding finite to inf or dividing inf by finite
mov.b #0x01,r4h ; set lsb of upper exponent byte
endif_1:
; Set the hidden one bit in the mantissa
bset #7,r5l ; set hidden one bit
bra endif_0
else_0:
; Exponent is zero.
; Is the mantissa non-zero, indicating a denorm?
; Use temp in r5h to see if mantissa is zero or not
mov.b r5h,r5h ; if mantissa is non-zero
beq else_2
; Set the exponent to 1, its true value
mov.b #0x01,r4l ; set exponent (r4l) to one
; Normalize the mantissa
; Do/while appropriate because must shift left at least one place
dowhile_3:
; Shift mantissa one place to left
add.w r6,r6 ; shift mantissa left 1 place by adding
addx.b r5l,r5l ; note only 3 significant bytes
; Decrement exponent
subs #1,r4
; Is one bit set? (one bit is in 1 << 23 or 00800000 position)
btst #7,r5l ; check 00800000 bit of mantissa
beq dowhile_3 ; zero indicates bit not set yet
bra endif_2
else_2:
; Mantissa is zero, indicating a zero value
; Set the zero flag
bset #0,r3h ; set zero flag
endif_2:
endif_0:
; Clear the upper mantissa byte, which we used as a temporary
sub.b r5h,r5h ; clear upper mantissa byte
rts
|