-
Notifications
You must be signed in to change notification settings - Fork 3
/
libmathq15_xc16.s
137 lines (101 loc) · 2.33 KB
/
libmathq15_xc16.s
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
; This file includes assembly-tuned functions for:
; q15_mul()
; q15_div()
; q15_add()
; q15_abs()
.include "xc.inc"
.text
.global _q15_mul
.global _q15_div
.global _q15_add
.global _q15_abs
_q15_mul:
; w3:w2 = w1 * w0
mul.ss w0, w1, w2
; w0 = (w3:w2) >> 15
rlc w2, w2
rlc w3, w3
; w0 = w3
mov w3, w0
return
_q15_div:
; w2 = w0
; w3 = w1
mov w0, w2
mov w1, w3
; w4 = abs(w0)
call _q15_abs
mov w0, w4
; w5 = abs(w1)
mov w3, w0
call _q15_abs
mov w0, w5
; if w4 >= w5, then goto saturate
cpslt w4, w5
goto _q15_div_saturate
; if w2 == 0, then goto saturate
clr w4
cpsne w4, w3
goto _q15_div_saturate
; otherwise, arrange and goto divide
mov w2, w0
mov w3, w1
goto _q15_div_div
_q15_div_saturate:
; mask = 0x8000
mov #32768, w4
; w2 &= mask
and w2, w4, w2
; w3 &= mask
and w3, w4, w3
; w2 = w2 ^ w3
xor w2, w3, w2
; if w2 == 0, return 32767, otherwise, return -32768
mov #32767, w0
clr w1
cpseq w2, w1
mov #32768, w0
return
_q15_div_div:
; at this point w1 = divisor, w0 = dividend
; w2 = w1
; w5:w4 = w0 << 16
mov w1, w2
mov w0, w5
clr w4
; w5:w4 = w5:w4 >> 1
asr w5, #1, w5
; w0 = w5:w4 / w2
repeat #17
div.sd w4, w2
return
_q15_add:
add w0, w1, w2
btsc SR, #2 ; check the overflow bit
goto _q15_add_sat
mov w2, w0
return
; if the code gets here, then an overflow occured, need to saturate
; mask = 0x8000
_q15_add_sat:
; if w0 is negative, then saturate negative, otherwise positive
btsc w0, #15
goto _q15_add_neg_sat
_q15_add_pos_sat:
mov #32767, w0
return
_q15_add_neg_sat:
mov #32768, w0
return
_q15_abs:
btss w0, #15
return
; number is negative, so reverse its form
com w0, w1
inc w1, w0
; the number '-32768' can be incorrectly translated,
; so this must be checked
btsc w0, #15
dec w0, w0
return
.end