|
|
1.1 root 1: #
2: # double ldexp (value, exp)
3: # double value;
4: # int exp;
5: #
6: # Ldexp returns value*2**exp, if that result is in range.
7: # If underflow occurs, it returns zero. If overflow occurs,
8: # it returns a value of appropriate sign and largest
9: # possible magnitude. In case of either overflow or underflow,
10: # the external int "errno" is set to ERANGE. Note that errno is
11: # not modified if no error occurs, so if you intend to test it
12: # after you use ldexp, you had better set it to something
13: # other than ERANGE first (zero is a reasonable value to use).
14: #
15: # Constants
16: #
17: .set erange,34 # error number for range error
18:
19: .data
20: .globl _errno # error flag
21:
22: huge: .word 0x7fff # The largest number that can
23: .word 0xffff # be represented in a long floating
24: .word 0xffff # number. This is given in hex in order
25: .word 0xffff # to avoid floating conversions
26: #
27: # Entry point
28: #
29: .text
30: .globl _ldexp
31: _ldexp: .word 0x0000 # We use r2, but do not save it
32:
33: movd 4(ap),r0 # Fetch "value"
34:
35: extzv $7,$8,r0,r2 # r2 := biased exponent
36: jeql ld1 # If it's zero, we're done
37:
38: addl2 12(ap),r2 # r2 := new biased exponent
39: jleq under # if it's <= 0, we have an underflow
40: cmpl r2,$256 # Otherwise check if it's too big
41: jgeq over # jump if overflow
42: #
43: # Construct the result and return
44: #
45: insv r2,$7,$8,r0 # Put the exponent back in the result
46: ld1: ret
47: #
48: # Underflow
49: #
50: under: clrd r0 # Result is zero
51: jbr err # Join general error code
52: #
53: # Overflow
54: #
55: over: movd huge,r0 # Largest possible floating magnitude
56: jbc $15,4(ap),err # Jump if argument was positive
57: mnegd r0,r0 # If arg < 0, make result negative
58:
59: err: movl $erange,_errno # Indicate range error
60: ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.