diff options
-rw-r--r-- | ops.h | 4 | ||||
-rw-r--r-- | qbe.c | 85 | ||||
-rw-r--r-- | test/float-to-uint32.qbe | 2 | ||||
-rw-r--r-- | test/float-to-uint64.qbe | 14 | ||||
-rw-r--r-- | test/uint32-to-float.qbe | 5 | ||||
-rw-r--r-- | test/uint64-to-float.qbe | 16 |
6 files changed, 19 insertions, 107 deletions
@@ -84,9 +84,13 @@ OP(IEXTUB, "extub") OP(IEXTS, "exts") OP(ITRUNCD, "truncd") OP(ISTOSI, "stosi") +OP(ISTOUI, "stoui") OP(IDTOSI, "dtosi") +OP(IDTOUI, "dtoui") OP(ISWTOF, "swtof") +OP(IUWTOF, "uwtof") OP(ISLTOF, "sltof") +OP(IULTOF, "ultof") /* cast and copy */ OP(ICAST, "cast") @@ -398,77 +398,6 @@ funcload(struct func *f, struct type *t, struct lvalue lval) return funcbits(f, t, v, lval.bits); } -/* TODO: move these conversions to QBE */ -static struct value * -utof(struct func *f, int dst, int src, struct value *v) -{ - struct value *odd, *big; - struct block *join; - - if (src == 'w') { - v = funcinst(f, IEXTUW, 'l', v, NULL); - return funcinst(f, ISLTOF, dst, v, NULL); - } - - join = mkblock("utof_join"); - join->phi.blk[0] = mkblock("utof_small"); - join->phi.blk[1] = mkblock("utof_big"); - - big = funcinst(f, ICSLTL, 'w', v, mkintconst(0)); - funcjnz(f, big, NULL, join->phi.blk[1], join->phi.blk[0]); - - funclabel(f, join->phi.blk[0]); - join->phi.val[0] = funcinst(f, ISLTOF, dst, v, NULL); - funcjmp(f, join); - - funclabel(f, join->phi.blk[1]); - odd = funcinst(f, IAND, 'l', v, mkintconst(1)); - v = funcinst(f, ISHR, 'l', v, mkintconst(1)); - v = funcinst(f, IOR, 'l', v, odd); /* round to odd */ - v = funcinst(f, ISLTOF, dst, v, NULL); - join->phi.val[1] = funcinst(f, IADD, dst, v, v); - - funclabel(f, join); - functemp(f, &join->phi.res); - join->phi.class = dst; - return &join->phi.res; -} - -static struct value * -ftou(struct func *f, int dst, int src, struct value *v) -{ - struct value *big, *maxflt, *maxint; - struct block *join; - enum instkind op = src == 's' ? ISTOSI : IDTOSI; - - if (dst == 'w') - return funcinst(f, op, 'l', v, NULL); - - join = mkblock("ftou_join"); - join->phi.blk[0] = mkblock("ftou_small"); - join->phi.blk[1] = mkblock("ftou_big"); - - maxflt = mkfltconst(src == 's' ? VALUE_FLTCONST : VALUE_DBLCONST, 0x1p63); - maxint = mkintconst(1ull<<63); - - big = funcinst(f, src == 's' ? ICGES : ICGED, 'w', v, maxflt); - funcjnz(f, big, NULL, join->phi.blk[1], join->phi.blk[0]); - - funclabel(f, join->phi.blk[0]); - join->phi.val[0] = funcinst(f, op, dst, v, NULL); - funcjmp(f, join); - - funclabel(f, join->phi.blk[1]); - v = funcinst(f, ISUB, src, v, maxflt); - v = funcinst(f, op, dst, v, NULL); - join->phi.val[1] = funcinst(f, IXOR, dst, v, maxint); - - funclabel(f, join); - functemp(f, &join->phi.res); - join->phi.class = dst; - return &join->phi.res; -} - static struct value * convert(struct func *f, struct type *dst, struct type *src, struct value *l) { @@ -515,16 +444,18 @@ convert(struct func *f, struct type *dst, struct type *src, struct value *l) default: fatal("internal error; unknown integer conversion"); } } else { - if (!dst->u.basic.issigned) - return ftou(f, class, src->size == 8 ? 'd' : 's', l); - op = src->size == 8 ? IDTOSI : ISTOSI; + if (dst->u.basic.issigned) + op = src->size == 8 ? IDTOSI : ISTOSI; + else + op = src->size == 8 ? IDTOUI : ISTOUI; } } else { class = dst->size == 8 ? 'd' : 's'; if (src->prop & PROPINT) { - if (!src->u.basic.issigned) - return utof(f, class, src->size == 8 ? 'l' : 'w', l); - op = src->size == 8 ? ISLTOF : ISWTOF; + if (src->u.basic.issigned) + op = src->size == 8 ? ISLTOF : ISWTOF; + else + op = src->size == 8 ? IULTOF : IUWTOF; } else { assert(src->prop & PROPFLOAT); if (src->size == dst->size) diff --git a/test/float-to-uint32.qbe b/test/float-to-uint32.qbe index 2cfc65f..a06c5fd 100644 --- a/test/float-to-uint32.qbe +++ b/test/float-to-uint32.qbe @@ -3,6 +3,6 @@ function w $f() { @start.1 @body.2 %.1 =s call $g() - %.2 =l stosi %.1 + %.2 =w stoui %.1 ret %.2 } diff --git a/test/float-to-uint64.qbe b/test/float-to-uint64.qbe index 363fc30..2055abd 100644 --- a/test/float-to-uint64.qbe +++ b/test/float-to-uint64.qbe @@ -3,16 +3,6 @@ function l $f() { @start.1 @body.2 %.1 =s call $g() - %.2 =w cges %.1, s_9.2233720368547758e+18 - jnz %.2, @ftou_big.5, @ftou_small.4 -@ftou_small.4 - %.3 =l stosi %.1 - jmp @ftou_join.3 -@ftou_big.5 - %.4 =s sub %.1, s_9.2233720368547758e+18 - %.5 =l stosi %.4 - %.6 =l xor %.5, 9223372036854775808 -@ftou_join.3 - %.7 =l phi @ftou_small.4 %.3, @ftou_big.5 %.6 - ret %.7 + %.2 =l stoui %.1 + ret %.2 } diff --git a/test/uint32-to-float.qbe b/test/uint32-to-float.qbe index 0e90531..75c2e1e 100644 --- a/test/uint32-to-float.qbe +++ b/test/uint32-to-float.qbe @@ -3,7 +3,6 @@ function s $f() { @start.1 @body.2 %.1 =w call $g() - %.2 =l extuw %.1 - %.3 =s sltof %.2 - ret %.3 + %.2 =s uwtof %.1 + ret %.2 } diff --git a/test/uint64-to-float.qbe b/test/uint64-to-float.qbe index 4c3cf92..8e14a8a 100644 --- a/test/uint64-to-float.qbe +++ b/test/uint64-to-float.qbe @@ -3,18 +3,6 @@ function s $f() { @start.1 @body.2 %.1 =l call $g() - %.2 =w csltl %.1, 0 - jnz %.2, @utof_big.5, @utof_small.4 -@utof_small.4 - %.3 =s sltof %.1 - jmp @utof_join.3 -@utof_big.5 - %.4 =l and %.1, 1 - %.5 =l shr %.1, 1 - %.6 =l or %.5, %.4 - %.7 =s sltof %.6 - %.8 =s add %.7, %.7 -@utof_join.3 - %.9 =s phi @utof_small.4 %.3, @utof_big.5 %.8 - ret %.9 + %.2 =s ultof %.1 + ret %.2 } |