SDK 1.3.0 release
See release notes for details Co-authored-by: Brian Cooke <bdscooke@gmail.com> Co-authored-by: Luke Wren <wren6991@gmail.com> Co-authored-by: Uri Shaked <uri@urishaked.com> Co-authored-by: Zapta <zapta@users.noreply.github.com> Co-authored-by: Andrew Scheller <andrew.scheller@raspberrypi.com> Co-authored-by: Liam Fraser <liam@raspberrypi.com> Co-authored-by: Gabriel Wang <embedded_zhuoran@Hotmail.com> Co-authored-by: Matias Silva <matita.martins@gmail.com> Co-authored-by: dp111 <19616418+dp111@users.noreply.github.com> Co-authored-by: Leonardo La Rocca <46094699+leoli51@users.noreply.github.com> Co-authored-by: Mahyar Koshkouei <mk@deltabeard.com> Co-authored-by: Brian Starkey <stark3y@gmail.com> Co-authored-by: Philip Howard <github@gadgetoid.com> Co-authored-by: Mike Causer <mcauser@gmail.com> Co-authored-by: Martino Facchin <m.facchin@arduino.cc> Co-authored-by: ZodiusInfuser <christopher.parrott2@gmail.com> Co-authored-by: Manuel Wick <manuel@matronix.de> Co-authored-by: Matias Silva <git@matiasilva.com> Co-authored-by: Robert Pafford <19439938+rjp5th@users.noreply.github.com> Co-authored-by: Alasdair Allan <alasdair@raspberrypi.com> Co-authored-by: Engineer_Will <646689853@qq.com> Co-authored-by: Garatronic <31109090+garatronic@users.noreply.github.com>
This commit is contained in:
@ -83,7 +83,7 @@ __check_nan_d2:
|
||||
|
||||
.macro table_tail_call SF_TABLE_OFFSET
|
||||
push {r3, r4}
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
#ifndef NDEBUG
|
||||
movs r3, #0
|
||||
mov ip, r3
|
||||
@ -99,12 +99,12 @@ __check_nan_d2:
|
||||
push {r3, r4}
|
||||
ldr r3, =sd_table
|
||||
ldr r3, [r3, #\SF_TABLE_OFFSET]
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
mov ip, pc
|
||||
#endif
|
||||
str r3, [sp, #4]
|
||||
pop {r3, pc}
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
.byte \SF_TABLE_OFFSET, 0xdf
|
||||
.word \shim
|
||||
#endif
|
||||
@ -733,7 +733,7 @@ sincos_shim_bootstrap:
|
||||
push {r2, r3, r4}
|
||||
movs r3, #0x13
|
||||
ldrb r3, [r3]
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
cmp r3, #1
|
||||
bne 1f
|
||||
ldr r3, =dsincos_shim
|
||||
|
@ -12,16 +12,18 @@
|
||||
// IT IS ***NOT*** SAFE TO CALL THESE FUNCTION POINTERS FROM ARBITRARY CODE
|
||||
uint32_t sd_table[SF_TABLE_V2_SIZE / 2];
|
||||
|
||||
#if !PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#if !(PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED)
|
||||
static __attribute__((noreturn)) void missing_double_func_shim(void) {
|
||||
panic("missing double function");
|
||||
}
|
||||
#endif
|
||||
extern void double_table_shim_on_use_helper(void);
|
||||
|
||||
void __attribute__((weak)) *sf_clz_func;
|
||||
|
||||
void __aeabi_double_init(void) {
|
||||
int rom_version = rp2040_rom_version();
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
if (rom_version == 1) {
|
||||
|
||||
// this is a little tricky.. we only want to pull in a shim if the corresponding function
|
||||
@ -63,4 +65,6 @@ void __aeabi_double_init(void) {
|
||||
// we use the unused entry for SINCOS
|
||||
sd_table[SF_TABLE_V3_FSINCOS / 4] = (uintptr_t) double_table_shim_on_use_helper;
|
||||
}
|
||||
|
||||
sf_clz_func = rom_func_lookup(ROM_FUNC_CLZ32);
|
||||
}
|
||||
|
@ -41,11 +41,25 @@ typedef int64_t i64;
|
||||
#define DUNPACK(x,e,m) e=((x)>>52)&0x7ff,m=((x)&0x000fffffffffffffULL)|0x0010000000000000ULL
|
||||
#define DUNPACKS(x,s,e,m) s=((x)>>63),DUNPACK((x),(e),(m))
|
||||
|
||||
_Pragma("GCC diagnostic push")
|
||||
_Pragma("GCC diagnostic ignored \"-Wstrict-aliasing\"")
|
||||
typedef union {
|
||||
double d;
|
||||
ui64 ix;
|
||||
} double_ui64;
|
||||
|
||||
static inline double ui642double(ui64 ix) {
|
||||
double_ui64 tmp;
|
||||
tmp.ix = ix;
|
||||
return tmp.d;
|
||||
}
|
||||
|
||||
static inline ui64 double2ui64(double d) {
|
||||
double_ui64 tmp;
|
||||
tmp.d = d;
|
||||
return tmp.ix;
|
||||
}
|
||||
|
||||
static inline bool disnan(double x) {
|
||||
ui64 ix=*(ui64*)&x;
|
||||
ui64 ix= double2ui64(x);
|
||||
// checks the top bit of the low 32 bit of the NAN, but it I think that is ok
|
||||
return ((uint32_t)(ix >> 31)) > 0xffe00000u;
|
||||
}
|
||||
@ -59,17 +73,17 @@ static inline bool disnan(double x) {
|
||||
#endif
|
||||
|
||||
static inline int dgetsignexp(double x) {
|
||||
ui64 ix=*(ui64*)&x;
|
||||
ui64 ix=double2ui64(x);
|
||||
return (ix>>52)&0xfff;
|
||||
}
|
||||
|
||||
static inline int dgetexp(double x) {
|
||||
ui64 ix=*(ui64*)&x;
|
||||
ui64 ix=double2ui64(x);
|
||||
return (ix>>52)&0x7ff;
|
||||
}
|
||||
|
||||
static inline double dldexp(double x,int de) {
|
||||
ui64 ix=*(ui64*)&x,iy;
|
||||
ui64 ix=double2ui64(x),iy;
|
||||
int e;
|
||||
e=dgetexp(x);
|
||||
if(e==0||e==0x7ff) return x;
|
||||
@ -77,7 +91,7 @@ static inline double dldexp(double x,int de) {
|
||||
if(e<=0) iy=ix&0x8000000000000000ULL; // signed zero for underflow
|
||||
else if(e>=0x7ff) iy=(ix&0x8000000000000000ULL)|0x7ff0000000000000ULL; // signed infinity on overflow
|
||||
else iy=ix+((ui64)de<<52);
|
||||
return *(double*)&iy;
|
||||
return ui642double(iy);
|
||||
}
|
||||
|
||||
double WRAPPER_FUNC(ldexp)(double x, int de) {
|
||||
@ -87,9 +101,9 @@ double WRAPPER_FUNC(ldexp)(double x, int de) {
|
||||
|
||||
|
||||
static inline double dcopysign(double x,double y) {
|
||||
ui64 ix=*(ui64*)&x,iy=*(ui64*)&y;
|
||||
ui64 ix=double2ui64(x),iy=double2ui64(y);
|
||||
ix=((ix&0x7fffffffffffffffULL)|(iy&0x8000000000000000ULL));
|
||||
return *(double*)&ix;
|
||||
return ui642double(ix);
|
||||
}
|
||||
|
||||
double WRAPPER_FUNC(copysign)(double x, double y) {
|
||||
@ -104,7 +118,7 @@ static inline int dispinf(double x) { return dgetsignexp(x)==0x7ff; }
|
||||
static inline int disminf(double x) { return dgetsignexp(x)==0xfff; }
|
||||
|
||||
static inline int disint(double x) {
|
||||
ui64 ix=*(ui64*)&x,m;
|
||||
ui64 ix=double2ui64(x),m;
|
||||
int e=dgetexp(x);
|
||||
if(e==0) return 1; // 0 is an integer
|
||||
e-=0x3ff; // remove exponent bias
|
||||
@ -117,7 +131,7 @@ static inline int disint(double x) {
|
||||
}
|
||||
|
||||
static inline int disoddint(double x) {
|
||||
ui64 ix=*(ui64*)&x,m;
|
||||
ui64 ix=double2ui64(x),m;
|
||||
int e=dgetexp(x);
|
||||
e-=0x3ff; // remove exponent bias
|
||||
if(e<0) return 0; // |x|<1; 0 is not odd
|
||||
@ -130,24 +144,24 @@ static inline int disoddint(double x) {
|
||||
}
|
||||
|
||||
static inline int disstrictneg(double x) {
|
||||
ui64 ix=*(ui64*)&x;
|
||||
ui64 ix=double2ui64(x);
|
||||
if(diszero(x)) return 0;
|
||||
return ix>>63;
|
||||
}
|
||||
|
||||
static inline int disneg(double x) {
|
||||
ui64 ix=*(ui64*)&x;
|
||||
ui64 ix=double2ui64(x);
|
||||
return ix>>63;
|
||||
}
|
||||
|
||||
static inline double dneg(double x) {
|
||||
ui64 ix=*(ui64*)&x;
|
||||
ui64 ix=double2ui64(x);
|
||||
ix^=0x8000000000000000ULL;
|
||||
return *(double*)&ix;
|
||||
return ui642double(ix);
|
||||
}
|
||||
|
||||
static inline int dispo2(double x) {
|
||||
ui64 ix=*(ui64*)&x;
|
||||
ui64 ix=double2ui64(x);
|
||||
if(diszero(x)) return 0;
|
||||
if(disinf(x)) return 0;
|
||||
ix&=0x000fffffffffffffULL;
|
||||
@ -164,33 +178,33 @@ static inline double dnan_or(double x) {
|
||||
|
||||
double WRAPPER_FUNC(trunc)(double x) {
|
||||
check_nan_d1(x);
|
||||
ui64 ix=*(ui64*)&x,m;
|
||||
ui64 ix=double2ui64(x),m;
|
||||
int e=dgetexp(x);
|
||||
e-=0x3ff; // remove exponent bias
|
||||
if(e<0) { // |x|<1
|
||||
ix&=0x8000000000000000ULL;
|
||||
return *(double*)&ix;
|
||||
return ui642double(ix);
|
||||
}
|
||||
e=52-e; // bit position in mantissa with significance 1
|
||||
if(e<=0) return x; // |x| large, so must be an integer
|
||||
m=(1ULL<<e)-1; // mask for bits of significance <1
|
||||
ix&=~m;
|
||||
return *(double*)&ix;
|
||||
return ui642double(ix);
|
||||
}
|
||||
|
||||
double WRAPPER_FUNC(round)(double x) {
|
||||
check_nan_d1(x);
|
||||
ui64 ix=*(ui64*)&x,m;
|
||||
ui64 ix=double2ui64(x),m;
|
||||
int e=dgetexp(x);
|
||||
e-=0x3ff; // remove exponent bias
|
||||
if(e<-1) { // |x|<0.5
|
||||
ix&=0x8000000000000000ULL;
|
||||
return *(double*)&ix;
|
||||
return ui642double(ix);
|
||||
}
|
||||
if(e==-1) { // 0.5<=|x|<1
|
||||
ix&=0x8000000000000000ULL;
|
||||
ix|=0x3ff0000000000000ULL; // ±1
|
||||
return *(double*)&ix;
|
||||
return ui642double(ix);
|
||||
}
|
||||
e=52-e; // bit position in mantissa with significance 1, <=52
|
||||
if(e<=0) return x; // |x| large, so must be an integer
|
||||
@ -198,16 +212,16 @@ double WRAPPER_FUNC(round)(double x) {
|
||||
ix+=m;
|
||||
m=m+m-1; // mask for bits of significance <1
|
||||
ix&=~m;
|
||||
return *(double*)&ix;
|
||||
return ui642double(ix);
|
||||
}
|
||||
|
||||
double WRAPPER_FUNC(floor)(double x) {
|
||||
check_nan_d1(x);
|
||||
ui64 ix=*(ui64*)&x,m;
|
||||
ui64 ix=double2ui64(x),m;
|
||||
int e=dgetexp(x);
|
||||
if(e==0) { // x==0
|
||||
ix&=0x8000000000000000ULL;
|
||||
return *(double*)&ix;
|
||||
return ui642double(ix);
|
||||
}
|
||||
e-=0x3ff; // remove exponent bias
|
||||
if(e<0) { // |x|<1, not zero
|
||||
@ -219,16 +233,16 @@ double WRAPPER_FUNC(floor)(double x) {
|
||||
m=(1ULL<<e)-1; // mask for bit of significance <1
|
||||
if(disneg(x)) ix+=m; // add 1-ε to magnitude if negative
|
||||
ix&=~m; // truncate
|
||||
return *(double*)&ix;
|
||||
return ui642double(ix);
|
||||
}
|
||||
|
||||
double WRAPPER_FUNC(ceil)(double x) {
|
||||
check_nan_d1(x);
|
||||
ui64 ix=*(ui64*)&x,m;
|
||||
ui64 ix=double2ui64(x),m;
|
||||
int e=dgetexp(x);
|
||||
if(e==0) { // x==0
|
||||
ix&=0x8000000000000000ULL;
|
||||
return *(double*)&ix;
|
||||
return ui642double(ix);
|
||||
}
|
||||
e-=0x3ff; // remove exponent bias
|
||||
if(e<0) { // |x|<1, not zero
|
||||
@ -240,7 +254,7 @@ double WRAPPER_FUNC(ceil)(double x) {
|
||||
m=(1ULL<<e)-1; // mask for bit of significance <1
|
||||
if(!disneg(x)) ix+=m; // add 1-ε to magnitude if positive
|
||||
ix&=~m; // truncate
|
||||
return *(double*)&ix;
|
||||
return ui642double(ix);
|
||||
}
|
||||
|
||||
double WRAPPER_FUNC(asin)(double x) {
|
||||
@ -549,7 +563,7 @@ static i64 drem_0(i64 mx,i64 my,int e,int*pquo) {
|
||||
|
||||
double WRAPPER_FUNC(fmod)(double x,double y) {
|
||||
check_nan_d2(x, y);
|
||||
ui64 ix=*(ui64*)&x,iy=*(ui64*)&y;
|
||||
ui64 ix=double2ui64(x),iy=double2ui64(y);
|
||||
int sx,ex,ey;
|
||||
i64 mx,my;
|
||||
DUNPACKS(ix,sx,ex,mx);
|
||||
@ -568,7 +582,7 @@ double WRAPPER_FUNC(fmod)(double x,double y) {
|
||||
|
||||
double WRAPPER_FUNC(remquo)(double x,double y,int*quo) {
|
||||
check_nan_d2(x, y);
|
||||
ui64 ix=*(ui64*)&x,iy=*(ui64*)&y;
|
||||
ui64 ix=double2ui64(x),iy=double2ui64(y);
|
||||
int sx,sy,ex,ey,q;
|
||||
i64 mx,my;
|
||||
DUNPACKS(ix,sx,ex,mx);
|
||||
@ -609,5 +623,4 @@ double WRAPPER_FUNC(drem)(double x,double y) { check_nan_d2(x, y); return remquo
|
||||
|
||||
double WRAPPER_FUNC(remainder)(double x,double y) { check_nan_d2(x, y); return remquo(x,y,0); }
|
||||
|
||||
_Pragma("GCC diagnostic pop") // strict-aliasing
|
||||
_Pragma("GCC diagnostic pop") // conversion
|
@ -63,7 +63,7 @@ regular_func double_table_shim_on_use_helper
|
||||
str r0, [sp, #12]
|
||||
pop {r0-r2, pc}
|
||||
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1
|
||||
#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED
|
||||
// Note that the V1 ROM has no double support, so this is basically the identical
|
||||
// library, and shim inter-function calls do not bother to redirect back thru the
|
||||
// wrapper functions
|
||||
@ -1218,11 +1218,6 @@ double_section dcordic_rot_step
|
||||
mov r9,r3
|
||||
bx r14
|
||||
|
||||
ret_dzero:
|
||||
movs r0,#0
|
||||
movs r1,#0
|
||||
bx r14
|
||||
|
||||
@ convert packed double in r0:r1 to signed/unsigned 32/64-bit integer/fixed-point value in r0:r1 [with r2 places after point], with rounding towards -Inf
|
||||
@ fixed-point versions only work with reasonable values in r2 because of the way dunpacks works
|
||||
|
||||
@ -1264,7 +1259,7 @@ regular_func double2fix64_shim
|
||||
eors r1,r1,r0 @ generate extreme fixed-point values
|
||||
pop {r15}
|
||||
|
||||
double_section double2uint64_shim
|
||||
double_section double2uint64_shim
|
||||
regular_func double2uint64_shim
|
||||
movs r2,#0 @ and fall through
|
||||
regular_func double2ufix64_shim
|
||||
@ -1288,7 +1283,12 @@ d2fix:
|
||||
asrs r3,r1,#31
|
||||
ldr r4, =d2fix_a
|
||||
bx r4
|
||||
|
||||
|
||||
ret_dzero:
|
||||
movs r0,#0
|
||||
movs r1,#0
|
||||
bx r14
|
||||
|
||||
.weak d2fix_a // weak because it exists in float code too
|
||||
regular_func d2fix_a
|
||||
@ here
|
||||
@ -2181,4 +2181,4 @@ dtab_exp:
|
||||
.word 0x40000000, 0x00000000 @ log 1+2^-32 Q62
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user