diff options
author | Michael Forney <mforney@mforney.org> | 2021-07-05 22:26:52 -0700 |
---|---|---|
committer | Michael Forney <mforney@mforney.org> | 2021-07-05 22:26:57 -0700 |
commit | 7bf0c0fb11af04d50cf7c374a44aa6101cca9c9d (patch) | |
tree | 4a54ad7462e00b49e2e7b981daedcd94f408ed5a /qbe.c | |
parent | 003f6a14b05bb16fa6f950dc193a8cbd62e0836d (diff) |
qbe: Fix bitfield sign extension with types shorter than int
Diffstat (limited to 'qbe.c')
-rw-r--r-- | qbe.c | 14 |
1 files changed, 9 insertions, 5 deletions
@@ -280,13 +280,17 @@ funcalloc(struct func *f, struct decl *d) static struct value * funcbits(struct func *f, struct type *t, struct value *v, struct bitfield b) { - int class; + int class, bits; class = t->size <= 4 ? 'w' : 'l'; - if (b.after) - v = funcinst(f, ISHL, class, v, mkintconst(b.after)); - if (b.before + b.after) - v = funcinst(f, t->basic.issigned ? ISAR : ISHR, class, v, mkintconst(b.before + b.after)); + bits = b.after; + if (bits) { + bits += (t->size + 3 & ~3) - t->size << 3; + v = funcinst(f, ISHL, class, v, mkintconst(bits)); + } + bits += b.before; + if (bits) + v = funcinst(f, t->basic.issigned ? ISAR : ISHR, class, v, mkintconst(bits)); return v; } |