Skip to content

Commit 77ee40b

Browse files
committed
Added QEXP and QLOG implementations for P1
1 parent cbf6059 commit 77ee40b

10 files changed

Lines changed: 529 additions & 520 deletions

File tree

include/libsys/p1_utils.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//
2+
// common utilities for P1 (pasm and bytecode)
3+
//
4+
// Copyright 2020,2026 Total Spectrum Software Inc.
5+
// SPDX-License-Identifier: MIT
6+
//
7+
8+
// calculate log base 2 of an unsigned num as a 5.27 fixed point number
9+
// uses the lookup table in ROM
10+
// algorithm comes from Propeller manual
11+
unsigned _qlog(unsigned num)
12+
{
13+
unsigned exp;
14+
unsigned r;
15+
unsigned r2;
16+
unsigned frac;
17+
exp = __builtin_clz(num);
18+
num = num << exp; // left justify
19+
// we will look up based on 11 bits, so the bottom 16 bits are the fraction
20+
frac = num & 0xffff;
21+
num = (num >> (30-11)) & 0xffe; // 30 because we will multiply by 2 for word access
22+
r = *((unsigned short *)(0xC000 + num));
23+
r2 = *((unsigned short *)(0xC002 + num));
24+
r = r + (((r2-r)*frac) >> 16);
25+
exp = exp ^ 0x1f;
26+
r = r | (exp << 16);
27+
28+
r = r << (27-16);
29+
return r;
30+
}
31+
// calculate 2^num, where "num" is a 5.27 fixed point num
32+
// uses the lookup table in ROM
33+
//
34+
// algorithm comes from Propeller manual
35+
unsigned _qexp(unsigned orig_num)
36+
{
37+
unsigned exp;
38+
unsigned r, r2;
39+
unsigned frac;
40+
unsigned num = orig_num;
41+
42+
exp = (num >> 27);
43+
// the original value is 5.27
44+
// we will look up based on 11 bits, so the bottom 16 bits are the fraction
45+
frac = num & 0xffff;
46+
num = (num >> (26-11)) & 0x0ffe;
47+
//__builtin_printf("...num=0x%08x lookup=%08x exp=%d\n", orig_num, num, exp);
48+
r = *((unsigned short *)(0xD000 + num));
49+
r2 = *((unsigned short *)(0xD002 + num));
50+
//__builtin_printf("...r1=0x%08x r2=%08x frac=%04x\n", r, r2, frac);
51+
r = r + ((frac * (r2-r)) >> 16);
52+
r = r << 15; // shift into 30..15
53+
r |= 0x80000000;
54+
//printf("...r=0x%08x\n", r);
55+
exp ^= 0x1f;
56+
r = r >> exp;
57+
return r;
58+
}

include/libsys/powers.c

Lines changed: 4 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// code for doing exponentials and logarithms
33
// Copyright 2020 Total Spectrum Software Inc.
4-
// MIT licensed
4+
// SPDX-License-Identifier: MIT
55
//
66

77
#define CONST_E 2.71828182846f
@@ -18,83 +18,6 @@ typedef union ForU {
1818
static inline unsigned __asuint(float f) { ForU u; u.f = f; return u.u; }
1919
static inline float __asfloat(unsigned d) { ForU u; u.u = d; return u.f; }
2020

21-
#ifdef __P2__
22-
23-
// calculate log2(mant) as a 5.27 fixed point number
24-
unsigned __builtin_qlog(unsigned mant)
25-
{
26-
unsigned r;
27-
__asm {
28-
qlog mant
29-
getqx r
30-
};
31-
return r;
32-
}
33-
34-
// calculate 2^mant, where mant is a 5.27 fixed point number
35-
unsigned __builtin_qexp(unsigned mant)
36-
{
37-
unsigned r;
38-
__asm {
39-
qexp mant
40-
getqx r
41-
};
42-
return r;
43-
}
44-
#else
45-
// calculate log base 2 of an unsigned num as a 5.27 fixed point number
46-
// uses the lookup table in ROM
47-
// algorithm comes from Propeller manual
48-
unsigned __builtin_qlog(unsigned num)
49-
{
50-
unsigned exp;
51-
unsigned r;
52-
unsigned r2;
53-
unsigned frac;
54-
exp = __builtin_clz(num);
55-
num = num << exp; // left justify
56-
// we will look up based on 11 bits, so the bottom 16 bits are the fraction
57-
frac = num & 0xffff;
58-
num = (num >> (30-11)) & 0xffe; // 30 because we will multiply by 2 for word access
59-
r = *((unsigned short *)(0xC000 + num));
60-
r2 = *((unsigned short *)(0xC002 + num));
61-
r = r + (((r2-r)*frac) >> 16);
62-
exp = exp ^ 0x1f;
63-
r = r | (exp << 16);
64-
65-
r = r << (27-16);
66-
return r;
67-
}
68-
// calculate 2^num, where "num" is a 5.27 fixed point num
69-
// uses the lookup table in ROM
70-
// algorithm comes from Propeller manual
71-
unsigned __builtin_qexp(unsigned orig_num)
72-
{
73-
unsigned exp;
74-
unsigned r, r2;
75-
unsigned frac;
76-
unsigned num = orig_num;
77-
78-
exp = (num >> 27);
79-
// the original value is 5.27
80-
// we will look up based on 11 bits, so the bottom 16 bits are the fraction
81-
frac = num & 0xffff;
82-
num = (num >> (26-11)) & 0x0ffe;
83-
//__builtin_printf("...num=0x%08x lookup=%08x exp=%d\n", orig_num, num, exp);
84-
r = *((unsigned short *)(0xD000 + num));
85-
r2 = *((unsigned short *)(0xD002 + num));
86-
//__builtin_printf("...r1=0x%08x r2=%08x frac=%04x\n", r, r2, frac);
87-
r = r + ((frac * (r2-r)) >> 16);
88-
r = r << 15; // shift into 30..15
89-
r |= 0x80000000;
90-
//printf("...r=0x%08x\n", r);
91-
exp ^= 0x1f;
92-
r = r >> exp;
93-
return r;
94-
}
95-
96-
#endif
97-
9821
//
9922
// floating point: calculate log base 2 of a float number
10023
//
@@ -165,7 +88,7 @@ float __builtin_log2f(float x)
16588
}
16689
}
16790
#endif
168-
r = __builtin_qlog(mant);
91+
r = _qlog(mant);
16992
// at this point r is a 5.27 fixed point number giving log2(mant)
17093
// note that mant was 1.23 by construction, so the upper 5 bits
17194
// is "24", i.e. we have 0xbnnnnnn
@@ -213,7 +136,7 @@ float __builtin_exp2f(float x)
213136
//printf("... u=%08x\n", u);
214137
u = u<<11; // 5.27
215138
u |= (16<<27);
216-
r = __builtin_qexp(u); // as a 16.16 number
139+
r = _qexp(u); // as a 16.16 number
217140
//printf("... r=%08x\n", r);
218141

219142
if (n >= 0) {
@@ -259,7 +182,7 @@ float __builtin_exp2f(float x)
259182
}
260183
u |= (24<<27);
261184
//printf("..u=%x (input) ", u);
262-
r = __builtin_qexp(u);
185+
r = _qexp(u);
263186
//printf("..u=%x r=%x\n", u, r);
264187
// round:
265188
r = (r+1)>>1;

sys/bytecode_rom.spin

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,3 +674,5 @@ pri _int64_cmps(alo, ahi, blo, bhi) : r | s
674674
r |= 1
675675

676676

677+
pri file "libsys/p1_utils.c" _qexp(n=+long) : r=+long
678+
pri file "libsys/p1_utils.c" _qlog(n=+long) : r=+long

sys/bytecode_rom.spin.h

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sys/nucode_util.spin

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,10 +480,10 @@ pri _sdiv64(ahi, alo, b) : q,r | shi, slo, sign
480480
pri _muldiv64(mult1, mult2, divisor) : r
481481
%bytecode("MULDIV64")
482482

483-
pri _qexp(v) : r
483+
pri _qexp(v = +long) : r = +long
484484
%bytecode("QEXP")
485485

486-
pri _qlog(v) : r
486+
pri _qlog(v = +long) : r = +long
487487
%bytecode("QLOG")
488488

489489
pri _ones(v = +long) : r = +long

0 commit comments

Comments
 (0)