Relaxation is a generic term used when the size of some instruction or data depends upon the value of some symbol or other data.
GAS knows to relax a particular type of PC relative relocation using a table. You can also define arbitrarily complex forms of relaxation yourself.
If you do not define md_relax_frag
, and you do define
TC_GENERIC_RELAX_TABLE
, GAS will relax rs_machine_dependent
frags
based on the frag subtype and the displacement to some specified target
address. The basic idea is that several machines have different addressing
modes for instructions that can specify different ranges of values, with
successive modes able to access wider ranges, including the entirety of the
previous range. Smaller ranges are assumed to be more desirable (perhaps the
instruction requires one word instead of two or three); if this is not the
case, don't describe the smaller-range, inferior mode.
The fr_subtype
field of a frag is an index into a CPU-specific
relaxation table. That table entry indicates the range of values that can be
stored, the number of bytes that will have to be added to the frag to
accomodate the addressing mode, and the index of the next entry to examine if
the value to be stored is outside the range accessible by the current
addressing mode. The fr_symbol
field of the frag indicates what symbol
is to be accessed; the fr_offset
field is added in.
If the fr_pcrel_adjust
field is set, which currently should only happen
for the NS32k family, the TC_PCREL_ADJUST
macro is called on the frag to
compute an adjustment to be made to the displacement.
The value fitted by the relaxation code is always assumed to be a displacement
from the current frag. (More specifically, from fr_fix
bytes into the
frag.)
The end of the relaxation sequence is indicated by a "next" value of 0. This means that the first entry in the table can't be used.
For some configurations, the linker can do relaxing within a section of an object file. If call instructions of various sizes exist, the linker can determine which should be used in each instance, when a symbol's value is resolved. In order for the linker to avoid wasting space and having to insert no-op instructions, it must be able to expand or shrink the section contents while still preserving intra-section references and meeting alignment requirements.
For the i960 using b.out format, no expansion is done; instead, each `.align' directive causes extra space to be allocated, enough that when the linker is relaxing a section and removing unneeded space, it can discard some or all of this extra padding and cause the following data to be correctly aligned.
For the H8/300, I think the linker expands calls that can't reach, and doesn't worry about alignment issues; the cpu probably never needs any significant alignment beyond the instruction size.
The relaxation table type contains these fields:
long rlx_forward
long rlx_backward
rlx_length
rlx_more
The relaxation is done in relax_segment
in `write.c'. The
difference in the length fields between the original mode and the one finally
chosen by the relaxing code is taken as the size by which the current frag will
be increased in size. For example, if the initial relaxing mode has a length
of 2 bytes, and because of the size of the displacement, it gets upgraded to a
mode with a size of 6 bytes, it is assumed that the frag will grow by 4 bytes.
(The initial two bytes should have been part of the fixed portion of the frag,
since it is already known that they will be output.) This growth must be
effected by md_convert_frag
; it should increase the fr_fix
field
by the appropriate size, and fill in the appropriate bytes of the frag.
(Enough space for the maximum growth should have been allocated in the call to
frag_var as the second argument.)
If relocation records are needed, they should be emitted by
md_estimate_size_before_relax
. This function should examine the target
symbol of the supplied frag and correct the fr_subtype
of the frag if
needed. When this function is called, if the symbol has not yet been defined,
it will not become defined later; however, its value may still change if the
section it is in gets relaxed.
Usually, if the symbol is in the same section as the frag (given by the
sec argument), the narrowest likely relaxation mode is stored in
fr_subtype
, and that's that.
If the symbol is undefined, or in a different section (and therefore moveable
to an arbitrarily large distance), the largest available relaxation mode is
specified, fix_new
is called to produce the relocation record,
fr_fix
is increased to include the relocated field (remember, this
storage was allocated when frag_var
was called), and frag_wane
is
called to convert the frag to an rs_fill
frag with no variant part.
Sometimes changing addressing modes may also require rewriting the instruction.
It can be accessed via fr_opcode
or fr_fix
.
Sometimes fr_var
is increased instead, and frag_wane
is not
called. I'm not sure, but I think this is to keep fr_fix
referring to
an earlier byte, and fr_subtype
set to rs_machine_dependent
so
that md_convert_frag
will get called.
If using a simple table is not suitable, you may implement arbitrarily complex relaxation semantics yourself. For example, the MIPS backend uses this to emit different instruction sequences depending upon the size of the symbol being accessed.
When you assemble an instruction that may need relaxation, you should allocate
a frag using frag_var
or frag_variant
with a type of
rs_machine_dependent
. You should store some sort of information in the
fr_subtype
field so that you can figure out what to do with the frag
later.
When GAS reaches the end of the input file, it will look through the frags and work out their final sizes.
GAS will first call md_estimate_size_before_relax
on each
rs_machine_dependent
frag. This function must return an estimated size
for the frag.
GAS will then loop over the frags, calling md_relax_frag
on each
rs_machine_dependent
frag. This function should return the change in
size of the frag. GAS will keep looping over the frags until none of the frags
changes size.
Go to the first, previous, next, last section, table of contents.