Issue 070426.2: Support bundled instructions
Background
On many VLIW architectures (e.g., Itanium, ARM), several independent
operations may be encoded into a single instruction. Even though the
individual operations often cannot be individually addressed, they can
often be executed individually, making it desirable to provide line
number information at the operation level rather than the instruction
level. This proposal describes a way to include that extra information
within a DWARF line number table.
In existing implementations, the compiler and debugger are left to
agree on an ad hoc convention for how to represent the individual
operations inside the instruction. On Itanium, for example, an
instruction (called a "bundle") is 16 bytes and contains 5 template
bits plus three 41-bit operations (called "slots"). On HP-UX, the
compiler uses the bundle address plus 0, 4, and 8 to represent the
three individual slots, respectively; on Linux, the compiler instead
uses the bundle address plus 0, 1, and 2. In the line number program
on HP-UX, the compiler sets minimum_instruction_length to 4,
permitting it to use increments of 1, 1, 2, 1, 1, 2, .... On Linux,
however, minimum_instruction_length is set to 1, and uses increments
of 1, 1, 14, 1, 1, 14, .... In both cases -- especially so on Linux --
the precious space of special opcodes in the line table program is
being used inefficiently. The ideal solution would be to set
minimum_instruction_length to 16/3, so the compiler could just use
uniform increments of 1 between all operations.
Proposal
The proposed changes to the DWARF specification are detailed below,
keyed to the section numbering for the December 20, 2005 version of
the DWARF-3 document.
I've used single quotation marks for terms that would normally be set
in a computer typeface.
6.2.2 State Machine Registers
Add the following new register:
op_index An unsigned integer representing the index of an operation
within a VLIW instruction. The index of the first operation
in an instruction is 0. For non-VLIW architectures, this
register will always be 0.
The 'address' and 'op_index' registers, taken together,
form an "operation pointer" that can reference any
individual operation within the instruction stream.
Just below the list of registers, add an initial value for op_index:
At the beginning of each sequence within a line number program, the
state of the registers is:
address 0
op_index 0
file 1
...
6.2.4 The Line Number Program Header
Modify the description of 'minimum_instruction_length' and add a new
item immediately following for 'maximum_operations_per_instruction':
4. mimimum_instruction_length (ubyte)
The size in bytes of the smallest target machine instruction. Line
number program opcodes that alter the address and op_index registers
use this and 'maximum_operations_per_instruction' in their
calculations.
5. maximum_operations_per_instruction (ubyte)
The maximum number of individual operations that may be encoded in an
instruction. Line number program opcodes that alter the address and
op_index registers use this and 'maximum_operations_per_instruction'
in their calculations.
For non-VLIW architectures, this field should be set to 1.
(Present only if the 'version' field is greater than or equal to 4.)
6.2.5.1 Special Opcodes
Modify the description of the effect of 'minimum_instruction_length':
2. Modify the "operation pointer" by incrementing the 'address' and
'op_index' registers. The arithmetic is described below.
...
All of the special opcodes do those same six things; they differ from
one another only in what values they add to the 'line', 'address', and
'op_index' registers.
(Note that the original wording for step 2 above implied that the
'address' register was always advanced by a non-negative number. That
was incorrect even for DWARF-2.)
Further down in the section:
A special opcode value is chosen based on the amount that needs to be
added to the 'line' register and the "operation pointer" (represented
by the 'address' and 'op_index' registers). ... The "operation advance"
represents the desired number of operations to skip when advancing the
"operation pointer", based on the assumption that each instruction
contains exactly the number of operations given by the value of
'maximum_operations_per_instruction'. An "operation advance" equal to
'maximum_operations_per_instruction' will advance the 'address'
register by 'minimum_instruction_length' bytes, and will leave the
'op_index' register unchanged. The special opcode is then calculated
using the following formula:
opcode = (desired line increment - line_base) +
(line_range * operation advance) + opcode_base
...
To decode a special opcode, subtract the 'opcode_base' from the opcode
itself to give the adjusted opcode. The "operation advance" is
determined by dividing the adjusted opcode by 'line_range'. The new
values of the 'address' and 'op_index' registers are calculated by
the following formulas:
new address = address + minimum_instruction_length *
((op_index + operation advance) div
maximum_operations_per_instruction)
new op_index = ((op_index + operation advance) rem
maximum_operations_per_instruction)
For these calculations, the 'div' and 'rem' operators are defined such
that:
a. (a div b) is an integer;
b. a = (a div b) * b + (a rem b); and
c. 0 <= (a rem b) < b.
(We could add an explanatory note to the effect that when
'maximum_operations_per_instruction' is 1, these calculations are
equivalent to the line table version 3 specifications.)
In the example given, change "address advance" to "operation advance".
6.2.5.2 Standard Opcodes
Modify the description of DW_LNS_advance_pc:
2. DW_LNS_advance_pc
The DW_LNS_advance_pc opcode takes a single unsigned LEB128 operand
and advances the "operation pointer" by modifying the 'address' and
'op_index' registers of the state machine according to the formulas
given in the preceding section.
Modify the description of DW_LNS_const_add_pc and DW_LNS_fixed_advance_pc:
8. DW_LNS_const_add_pc
The DW_LNS_const_add_pc opcode takes no operands. It advances the
"operation pointer" by the increment corresponding to that of special
opcode 255, according to the formulas given in Section 6.2.5.1.
...
9. DW_LNS_fixed_advance_pc
The DW_LNS_fixed_advance_pc opcode takes a single uhalf (unencoded)
operand, adds it to the 'address' register of the state machine, and
sets the 'op_index' register to 0. This is the only standard opcode
...
6.2.5.3 Extended Opcodes
Modify the description of DW_LNE_set_address:
2. DW_LNE_set_address
The DW_LNE_set_address opcode takes a single relocatable address as
an operand. The size of the operand is the size appropriate to hold
an address on the target machine. It sets the 'address' register to
the value given by the relocatable address, and sets the 'op_index'
register to 0.
7.21 Line Number Information
Change the version number to 4:
The version number in the line number program header is 4 for DWARF
Version 4.
Appendix F - Version Numbers
Specify the version number for the .debug_line section to be 4 for
DWARF Version 4.
-----------------
see also proposal 070519.1