This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
RFC: DW_CFA_offset_range
- From: Jakub Jelinek <jakub at redhat dot com>
- To: jason at redhat dot com
- Cc: gcc at gcc dot gnu dot org
- Date: Fri, 11 Jul 2003 17:57:30 +0200
- Subject: RFC: DW_CFA_offset_range
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
On s390/s390x, FDE for typical function looks like:
000006ec 00000028 000006f0 FDE cie=00000000 pc=fff41e7c..fff41f3a
DW_CFA_advance_loc: 4 to fff41e80
DW_CFA_offset: r15 at cfa-36
DW_CFA_offset: r14 at cfa-40
DW_CFA_offset: r13 at cfa-44
DW_CFA_offset: r12 at cfa-48
DW_CFA_offset: r11 at cfa-52
DW_CFA_offset: r10 at cfa-56
DW_CFA_offset: r9 at cfa-60
DW_CFA_offset: r8 at cfa-64
DW_CFA_offset: r7 at cfa-68
DW_CFA_offset: r6 at cfa-72
DW_CFA_advance_loc: 38 to fff41ea6
DW_CFA_def_cfa_offset: 192
DW_CFA_nop
DW_CFA_nop
(usually 3-10 DW_CFA_offset ops for consecutive register range).
This is for stm/stmg instructions do.
What do you think about saving some .eh_frame bytes by introducing
DW_CFA_offset_range (or DW_CFA_GNU_offset_range if not suitable
for official range), which would take 3 args:
1) uleb128 - first register column = first
2) uleb128 - last register column = last
3) sleb128 - offset
which would stand for:
if (first < last)
while (first <= last)
{ DW_CFA_offset (first, offset), offset += sizeof(word), ++first }
else
while (first >= last)
{ DW_CFA_offset (first, offset), offset += sizeof(word), --first }
so the above FDE could be written as:
000006ec 00000028 000006f0 FDE cie=00000000 pc=fff41e7c..fff41f3a
DW_CFA_advance_loc: 4 to fff41e80
DW_CFA_offset_range: r6..r15 at cfa-72
DW_CFA_advance_loc: 38 to fff41ea6
DW_CFA_def_cfa_offset: 192
Would be in the example above (assuming all offsets fit into 1 byte
and register numbers as well) 20 bytes without it and 4 bytes with that op.
I think even on non-s390* it is pretty common that 2 or more registers
are saved in consecutive stack block.
Jakub