Hi, Something broke the bitfield handling recently and before I delve deeper into it, I'm hoping someone admits guilt. :)
This is taken from execute/20040709-1.c: struct K { unsigned int k : 6, l : 1, j : 10, i : 15; }; struct K retmeK (struct K x) { return x; } This produces the following code: retmeK: link.w %fp,#0 move.l %d3,-(%sp) move.l %d2,-(%sp) clr.l %d0 move.l 8(%fp),%d1 bfextu %d1{#7:#10},%d3 bfextu %d1{#17:#15},%d2 bfins %d2,%d0{#17:#15} bfins %d3,%d0{#7:#10} -> moveq #26,%d2 lsr.l %d2,%d1 bfins %d1,%d0{#0:#7} move.l (%sp)+,%d2 move.l (%sp)+,%d3 unlk %fp rts The problem here is that the shift is off by one. The copying of the k/l field is already wrong when it gets to the RTL phase: (insn 11 10 13 3 (set (subreg:SI (reg:QI 32 [ x$B0F7 ]) 0) (zero_extract:SI (reg/v:SI 35 [ x ]) (const_int 7 [0x7]) (const_int 0 [0x0]))) -1 (nil) (nil)) (insn 15 14 16 3 (set (subreg:SI (reg:QI 36) 0) (zero_extract:SI (subreg:SI (reg:QI 32 [ x$B0F7 ]) 0) (const_int 7 [0x7]) (const_int 24 [0x18]))) -1 (nil) (nil)) (insn 16 15 17 3 (set (zero_extract:SI (reg:SI 33 [ D.1548 ]) (const_int 7 [0x7]) (const_int 0 [0x0])) (subreg:SI (reg:QI 36) 0)) -1 (nil) (nil)) The offset of 24 in insn 15 is wrong. I'm not that familiar with the tree optimizers, so I'm hoping for some help. Even without this bug gcc usage of bitfield instruction has become a little insane lately, e.g. 2.95/3.4 produce this code: retmeK: link.w %a6,#0 move.l 8(%a6),%d0 unlk %a6 rts How can I get this back? In general bitfield instructions are a bit more expensive, they are ok for extracting integer values when needed, but for simply copying values like this it's overkill, what makes this worse is that the rtl optimizers can often do as much with this (and in combination with subreg it's not getting better...) I'd be willing to look into this, but I need a little help here. Thanks. bye, Roman