diff options
| author | grischka <grischka> | 2014-09-23 12:30:08 +0200 |
|---|---|---|
| committer | grischka <grischka> | 2014-09-23 12:30:08 +0200 |
| commit | 9d7fb3336049243a16ce20ba907946d1de9e1c0d (patch) | |
| tree | 9c0b9009b9447f0749a070a2d14df814b83bb15e | |
| parent | 87d879aa7b3a75245e5e1a0fe15ba08105457df2 (diff) | |
| download | tinycc-9d7fb3336049243a16ce20ba907946d1de9e1c0d.tar.gz tinycc-9d7fb3336049243a16ce20ba907946d1de9e1c0d.tar.bz2 | |
tccgen: use lvalue as result from bitfield assignment
test case:
#include <stdio.h>
int main(int argc, char **argv)
{
struct _s { unsigned a:9, b:5, c:7; } _s, *s = &_s;
int n = 250;
s->a = s->b = s->c = n + 4;
printf("--> %d / %d / %d\n", s->a, s->b, s->c);
return 0;
}
before:
--> 254 / 30 / 126
now:
--> 30 / 30 / 126
| -rw-r--r-- | tccgen.c | 12 |
1 files changed, 5 insertions, 7 deletions
@@ -2520,16 +2520,15 @@ ST_FUNC void vstore(void) /* leave source on stack */ } else if (ft & VT_BITFIELD) { /* bitfield store handling */ + + /* save lvalue as expression result (example: s.b = s.a = n;) */ + vdup(), vtop[-1] = vtop[-2]; + bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f; bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f; /* remove bit field info to avoid loops */ vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)); - /* duplicate source into other register */ - gv_dup(); - vswap(); - vrott(3); - if((ft & VT_BTYPE) == VT_BOOL) { gen_cast(&vtop[-1].type); vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED); @@ -2561,8 +2560,7 @@ ST_FUNC void vstore(void) gen_op('|'); /* store result */ vstore(); - - /* pop off shifted source from "duplicate source..." above */ + /* ... and discard */ vpop(); } else { |
