libqbe/test/fpcnv.ssa
Michael Forney d6c9669c3c Fix conversion from float/double to unsigned int
signed int can't represent all the values of unsigned int, so we
need to do the conversion to signed long, and use the lower 32 bits
as the result.
2023-08-26 15:16:45 +02:00

129 lines
2.4 KiB
Text

# floating point casts and conversions
export
function s $fneg(s %f) {
@fneg
%b0 =w cast %f
%b1 =w xor 2147483648, %b0
%rs =s cast %b1
ret %rs
}
export
function d $ftrunc(d %f) {
@ftrunc
%l0 =w dtosi %f
%rt =d swtof %l0
ret %rt
}
export
function s $wtos(w %w) {
@start
%rt =s uwtof %w
ret %rt
}
export
function d $wtod(w %w) {
@start
%rt =d uwtof %w
ret %rt
}
export
function s $ltos(l %l) {
@start
%rt =s ultof %l
ret %rt
}
export
function d $ltod(l %l) {
@start
%rt =d ultof %l
ret %rt
}
export
function w $stow(s %f) {
@start
%rt =w stoui %f
ret %rt
}
export
function w $dtow(d %f) {
@start
%rt =w dtoui %f
ret %rt
}
export
function l $stol(s %f) {
@start
%rt =l stoui %f
ret %rt
}
export
function l $dtol(d %f) {
@start
%rt =l dtoui %f
ret %rt
}
# >>> driver
# #include <limits.h>
#
# extern float fneg(float);
# extern double ftrunc(double);
#
# extern float wtos(unsigned int);
# extern double wtod(unsigned int);
# extern float ltos(long long unsigned int);
# extern double ltod(long long unsigned int);
#
# extern unsigned int stow(float);
# extern unsigned int dtow(double);
# extern unsigned long long stol(float);
# extern unsigned long long dtol(double);
#
# unsigned long long iin[] = { 0, 1, 16, 234987, 427386245, 0x7fff0000,
# 0xffff0000, 23602938196141, 72259248152500195, 9589010795705032704ull,
# 0xdcf5fbe299d0148aull, 0xffffffff00000000ull, -1 };
#
# double fin[] = { 0.17346516197824458, 442.0760005466251, 4342856.879893436,
# 4294967295.0, 98547543006.49626, 236003043787688.3, 9.499222733527032e+18,
# 1.1936266170755652e+19 };
#
# int main() {
# int i;
#
# if (fneg(1.23f) != -1.23f) return 1;
# if (ftrunc(3.1415) != 3.0) return 2;
# if (ftrunc(-1.234) != -1.0) return 3;
#
# for (i=0; i<sizeof(iin)/sizeof(iin[0]); i++) {
# if (wtos(iin[i]) != (float) (unsigned int)iin[i])
# return 4;
# if (wtod(iin[i]) != (double)(unsigned int)iin[i])
# return 5;
# if (ltos(iin[i]) != (float) iin[i])
# return 6;
# if (ltod(iin[i]) != (double)iin[i])
# return 7;
# }
# for (i=0; i<sizeof(fin)/sizeof(fin[0]); i++) {
# if (stol((float)fin[i]) != (unsigned long long)(float)fin[i])
# return 8;
# if (dtol(fin[i]) != (unsigned long long)fin[i])
# return 9;
# if((unsigned long long)fin[i] > UINT_MAX)
# continue;
# if (stow((float)fin[i]) != (unsigned int)(float)fin[i])
# return 10;
# if (dtow(fin[i]) != (unsigned int)fin[i])
# return 11;
# }
# return 0;
# }
# <<<