David Boddie
unread,Sep 24, 2023, 4:26:19 PM9/24/23Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to infer...@googlegroups.com, 9f...@9fans.net
I'm using the Inferno Thumb compiler, tc, to compile Inferno (unsurprisingly)
and encountered a problem. Since 9front appears to have the same compiler, I
thought that I should mention it on both 9fans and Inferno mailing lists.
The problem is with the libmath/fdlibm/e_exp.c when compiled using tc,
5c (arm), 0c (spim), and maybe others. The relevant chunk of code is the
first branch of this:
if(k >= -1021) {
__HI(y) += (k<<20); /* add k to y's exponent */
return y;
} else {
__HI(y) += ((k+1000)<<20);/* add k to y's exponent */
return y*twom1000;
}
where __HI is defined as
#define __HI(x) *(1+(int*)&x)
for little-endian doubles.
The code generated by tc for the k >= -1021 branch is this, which I've
annotated:
MOVD F0,F3 y
CMP $-1021,R4, compare k to -1021
BLT ,9(PC) k < -1021, skip past RET below
MOVW R4,R1
SLL $20,R1 k << 20
MOVW y-4(SP),R2 load the high word of y in memory
ADD R1,R2 add k << 20 to it
MOVW R2,y-4(SP) store the result back to memory
MOVD F3,F0 the unmodified y is the return value
RET ,
So, the compiler operates on the value in memory without updating the value
in register F3.
Turning off registerization results in this code instead:
MOVD F0,y-8(SP) update y in memory
MOVW k-44(SP),R1 load k
CMP $-1021,R1, compare k to -1021
BLT ,10(PC) k < -1021, skip past RET below
MOVW k-44(SP),R1
SLL $20,R1 k << 20
MOVW y-4(SP),R2 load the high word of y in memory
ADD R1,R2 add k << 20 to it
MOVW R2,y-4(SP) store the result back to memory
MOVD y-8(SP),F0 load the modified y to be returned
NOP ,R0
RET ,
Is the problem with the compiler or with the C code? Although I get the
feeling that the compiler should figure out that the value of y is being
modified, I don't know if it's being done in a valid way, or a way that
compilers are expected to handle.
It could be an endianness-related thing: vc appears to do the right thing.
Having said that, so does 8c, as far as I can tell.
Any thoughts?
David