cproc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/cproc
Log | Files | Refs | Submodules | README | LICENSE

commit 5eb638ef6c5e2b1abb927ad395aa6f15fcb3e92a
parent 4f56de1d1ae28ef3222577c8d38479a1ad1d2a99
Author: Michael Forney <mforney@mforney.org>
Date:   Mon, 15 Apr 2019 22:21:27 -0700

expr: Handle compound assignment of bit-fields

Diffstat:
Mexpr.c | 12+++++++++++-
Atests/bitfield-compound-assign.c | 7+++++++
Atests/bitfield-compound-assign.qbe | 21+++++++++++++++++++++
3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/expr.c b/expr.c @@ -867,7 +867,7 @@ mkassignexpr(struct expr *l, struct expr *r) struct expr * assignexpr(struct scope *s) { - struct expr *e, *l, *r, *tmp; + struct expr *e, *l, *r, *tmp, *bit; enum tokenkind op; l = condexpr(s); @@ -895,11 +895,21 @@ assignexpr(struct scope *s) if (!op) return mkassignexpr(l, r); /* rewrite `E1 OP= E2` as `T = &E1, *T = *T OP E2`, where T is a temporary slot */ + if (l->kind == EXPRBITFIELD) { + bit = l; + l = l->bitfield.base; + } else { + bit = NULL; + } tmp = mkexpr(EXPRTEMP, mkpointertype(l->type, l->qual)); tmp->lvalue = true; tmp->temp = NULL; e = mkassignexpr(tmp, mkunaryexpr(TBAND, l)); l = mkunaryexpr(TMUL, tmp); + if (bit) { + bit->bitfield.base = l; + l = bit; + } r = mkbinaryexpr(&tok.loc, op, l, r); e->next = mkassignexpr(l, r); l = mkexpr(EXPRCOMMA, l->type); diff --git a/tests/bitfield-compound-assign.c b/tests/bitfield-compound-assign.c @@ -0,0 +1,7 @@ +struct { + int : 4, x : 9, : 3; +} s; + +void f(void) { + s.x += 3; +} diff --git a/tests/bitfield-compound-assign.qbe b/tests/bitfield-compound-assign.qbe @@ -0,0 +1,21 @@ +export +function $f() { +@start.1 +@body.2 + %.1 =l copy $s + %.2 =l mul 0, 1 + %.3 =l add %.1, %.2 + %.4 =l copy %.3 + %.5 =w loadsw %.4 + %.6 =w shl %.5, 19 + %.7 =w sar %.6, 23 + %.8 =w add %.7, 3 + %.9 =w loaduw %.4 + %.10 =w and %.9, 18446744073709543439 + %.11 =w shl %.8, 4 + %.12 =w and %.11, 8176 + %.13 =w or %.10, %.12 + storew %.13, %.4 + ret +} +export data $s = align 4 { z 4 }