3 ms·
> I've never seen anyone store 10 byte IEEE-754 values in memory. But you can, if you are after precision as the OP apparently was. I'm not sure what this c-w
by qb45 10y ago
> I've never seen anyone store 10 byte IEEE-754 values in memory.
But you can, if you are after precision as the OP apparently was.
I'm not sure what this c-word is doing in your post, I thought we were talking assembly, but as far as c-things go, at least gcc and clang represent long double as 80b extended precision on x86.
So, for example, compiling this beauty (which is too large for x87 stack):
long double a[64], b[64], c[64], d[64];
// load a,b,c,d from somewhere
long double x =
((((((((a[0]+a[1])+(a[2]+a[3]))+((a[4]+a[5])+(a[6]+a[7])))
+(((a[8]+a[9])+(a[10]+a[11]))+((a[12]+a[13])+(a[14]+a[15]))))
+((((a[16]+a[17])+(a[18]+a[19]))+((a[20]+a[21])+(a[22]+a[23])))
+(((a[24]+a[25])+(a[26]+a[27]))+((a[28]+a[29])+(a[30]+a[31])))))
+(((((a[32]+a[33])+(a[34]+a[35]))+((a[36]+a[37])+(a[38]+a[39])))
+(((a[40]+a[41])+(a[42]+a[43]))+((a[44]+a[45])+(a[46]+a[47]))))
+((((a[48]+a[49])+(a[50]+a[51]))+((a[52]+a[53])+(a[54]+a[55])))
+(((a[56]+a[57])+(a[58]+a[59]))+((a[60]+a[61])+(a[62]+a[63]))))))
+((((((b[0]+b[1])+(b[2]+b[3]))+((b[4]+b[5])+(b[6]+b[7])))
+(((b[8]+b[9])+(b[10]+b[11]))+((b[12]+b[13])+(b[14]+b[15]))))
+((((b[16]+b[17])+(b[18]+b[19]))+((b[20]+b[21])+(b[22]+b[23])))
+(((b[24]+b[25])+(b[26]+b[27]))+((b[28]+b[29])+(b[30]+b[31])))))
+(((((b[32]+b[33])+(b[34]+b[35]))+((b[36]+b[37])+(b[38]+b[39])))
+(((b[40]+b[41])+(b[42]+b[43]))+((b[44]+b[45])+(b[46]+b[47]))))
+((((b[48]+b[49])+(b[50]+b[51]))+((b[52]+b[53])+(b[54]+b[55])))
+(((b[56]+b[57])+(b[58]+b[59]))+((b[60]+b[61])+(b[62]+b[63])))))))
+(((((((c[0]+c[1])+(c[2]+c[3]))+((c[4]+c[5])+(c[6]+c[7])))
+(((c[8]+c[9])+(c[10]+c[11]))+((c[12]+c[13])+(c[14]+c[15]))))
+((((c[16]+c[17])+(c[18]+c[19]))+((c[20]+c[21])+(c[22]+c[23])))
+(((c[24]+c[25])+(c[26]+c[27]))+((c[28]+c[29])+(c[30]+c[31])))))
+(((((c[32]+c[33])+(c[34]+c[35]))+((c[36]+c[37])+(c[38]+c[39])))
+(((c[40]+c[41])+(c[42]+c[43]))+((c[44]+c[45])+(c[46]+c[47]))))
+((((c[48]+c[49])+(c[50]+c[51]))+((c[52]+c[53])+(c[54]+c[55])))
+(((c[56]+c[57])+(c[58]+c[59]))+((c[60]+c[61])+(c[62]+c[63]))))))
+((((((d[0]+d[1])+(d[2]+d[3]))+((d[4]+d[5])+(d[6]+d[7])))
+(((d[8]+d[9])+(d[10]+d[11]))+((d[12]+d[13])+(d[14]+d[15]))))
+((((d[16]+d[17])+(d[18]+d[19]))+((d[20]+d[21])+(d[22]+d[23])))
+(((d[24]+d[25])+(d[26]+d[27]))+((d[28]+d[29])+(d[30]+d[31])))))
+(((((d[32]+d[33])+(d[34]+d[35]))+((d[36]+d[37])+(d[38]+d[39])))
+(((d[40]+d[41])+(d[42]+d[43]))+((d[44]+d[45])+(d[46]+d[47]))))
+((((d[48]+d[49])+(d[50]+d[51]))+((d[52]+d[53])+(d[54]+d[55])))
+(((d[56]+d[57])+(d[58]+d[59]))+((d[60]+d[61])+(d[62]+d[63]))))))))
;
produces only 80b spills (fstpt in GNU syntax):
$ objdump -d fpmonster |grep fst
400457: db 7c 1c 10 fstpt 0x10(%rsp,%rbx,1)
400462: db bc 1c 10 04 00 00 fstpt 0x410(%rsp,%rbx,1)
400470: db bc 1c 10 08 00 00 fstpt 0x810(%rsp,%rbx,1)
40047e: db bc 1c 10 0c 00 00 fstpt 0xc10(%rsp,%rbx,1)
400b47: db 7c 24 10 fstpt 0x10(%rsp)
400d91: db 3c 24 fstpt (%rsp)
Clearly, extended precision can be done right both in C and raw assembly.
> People store doubles, and people get upset
That's their fault :) and another story altogether. For reproducible low precision, indeed SSE is the way to go.