diff options
| author | Michael Forney <mforney@mforney.org> | 2022-02-10 15:49:11 -0800 | 
|---|---|---|
| committer | Michael Forney <mforney@mforney.org> | 2022-02-10 15:49:16 -0800 | 
| commit | 5dcd9299333326013be09062029e59c51b097786 (patch) | |
| tree | 553a50e749be9924ce0f1df9cf1f1a17d5af3a8c | |
| parent | f57f61b49c05c6705da909c9c29172ea3602bdee (diff) | |
| download | cproc-5dcd9299333326013be09062029e59c51b097786.tar.xz | |
qbe: Switch to new unsigned-float conversion operators
| -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  }  | 
