Support for more portable alignment handling in assembly code, based on patches

from Bryan Ford <baford@schirf.cs.utah.edu>:
* read.c (potable): Added balign and p2align, for aligning by bytes or powers
of two independent of what ".align" does for a given target.
* doc/as.texinfo: Document them.
This commit is contained in:
Ken Raeburn 1995-04-26 20:02:18 +00:00
parent 094a7e4392
commit 931a8fab1b
3 changed files with 176 additions and 73 deletions

View File

@ -1,3 +1,12 @@
Wed Apr 26 15:54:10 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
Support for more portable alignment handling in assembly code,
based on patches from Bryan Ford <baford@schirf.cs.utah.edu>:
* read.c (potable): Added balign and p2align, for aligning by
bytes or powers of two independent of what ".align" does for a
given target.
* doc/as.texinfo: Document them.
Tue Apr 25 11:12:04 1995 Rob Savoye <rob@thepub.cygnus.com>
* configure, configure.in: Look for m68k-*-vxworks* rather than

View File

@ -208,7 +208,7 @@ Here is a brief summary of how to invoke @code{@value{AS}}. For details,
@c HPPA has no machine-dependent assembler options (yet).
@end ifset
@ifset SPARC
[ -Av6 | -Av7 | -Av8 | -Asparclite | -bump ]
[ -Av6 | -Av7 | -Av8 | -Av9 | -Asparclite | -bump ]
@end ifset
@ifset Z8000
@c Z8000 has no machine-dependent assembler options
@ -367,7 +367,7 @@ The following options are available when @code{@value{AS}} is configured
for the SPARC architecture:
@table @code
@item -Av6 | -Av7 | -Av8 | -Asparclite
@item -Av6 | -Av7 | -Av8 | -Av9 | -Asparclite
Explicitly select a variant of the SPARC architecture.
@item -bump
@ -2653,6 +2653,7 @@ Some machine configurations provide additional directives.
* App-File:: @code{.app-file @var{string}}
* Ascii:: @code{.ascii "@var{string}"}@dots{}
* Asciz:: @code{.asciz "@var{string}"}@dots{}
* Balign:: @code{.balign @var{abs-expr} , @var{abs-expr}}
* Byte:: @code{.byte @var{expressions}}
* Comm:: @code{.comm @var{symbol} , @var{length} }
* Data:: @code{.data @var{subsection}}
@ -2704,6 +2705,7 @@ Some machine configurations provide additional directives.
* Nolist:: @code{.nolist}
* Octa:: @code{.octa @var{bignums}}
* Org:: @code{.org @var{new-lc} , @var{fill}}
* P2align:: @code{.p2align @var{abs-expr} , @var{abs-expr}}
* Psize:: @code{.psize @var{lines}, @var{columns}}
* Quad:: @code{.quad @var{bignums}}
* Sbttl:: @code{.sbttl "@var{subheading}"}
@ -2774,21 +2776,29 @@ but ignores it.
@cindex @code{align} directive
Pad the location counter (in the current subsection) to a particular
storage boundary. The first expression (which must be absolute) is the
alignment required, as described below.
The second expression (also absolute) gives the value to be stored in
the padding bytes. It (and the comma) may be omitted. If it is
omitted, the padding bytes are zero.
The way the required alignment is specified varies from system to system.
For the a29k, HPPA, m86k, m88k, w65, sparc, and i386 using ELF format,
the first expression is the
alignment request in bytes. For example @samp{.align 8} advances
the location counter until it is a multiple of 8. If the location counter
is already a multiple of 8, no change is needed.
For other systems, including the i386 using a.out format, it is the
number of low-order zero bits the location counter must have after
advancement. For example @samp{.align 3} advances the location
counter until it a multiple of 8. If the location counter is already a
multiple of 8, no change is needed.
@ifset HPPA
For the HPPA, the first expression (which must be absolute) is the
alignment request in bytes. For example @samp{.align 8} advances
the location counter until it is a multiple of 8. If the location counter
is already a multiple of 8, no change is needed.
@end ifset
The second expression (also absolute) gives the value to be stored in
the padding bytes. It (and the comma) may be omitted. If it is
omitted, the padding bytes are zero.
This inconsistency is due to the different behaviors of the various
native assemblers for these systems which GAS must emulate.
GAS also provides @code{.balign} and @code{.p2align} directives,
described later, which have a consistent behavior across all
architectures (but are specific to GAS).
@node App-File
@section @code{.app-file @var{string}}
@ -2826,6 +2836,21 @@ trailing zero byte) into consecutive addresses.
@code{.asciz} is just like @code{.ascii}, but each string is followed by
a zero byte. The ``z'' in @samp{.asciz} stands for ``zero''.
@node Balign
@section @code{.balign @var{abs-expr} , @var{abs-expr}}
@cindex padding the location counter given number of bytes
@cindex @code{balign} directive
Pad the location counter (in the current subsection) to a particular
storage boundary. The first expression (which must be absolute) is the
alignment request in bytes. For example @samp{.balign 8} advances
the location counter until it is a multiple of 8. If the location counter
is already a multiple of 8, no change is needed.
The second expression (also absolute) gives the value to be stored in
the padding bytes. It (and the comma) may be omitted. If it is
omitted, the padding bytes are zero.
@node Byte
@section @code{.byte @var{expressions}}
@ -3378,6 +3403,22 @@ intervening bytes are filled with @var{fill} which should be an
absolute expression. If the comma and @var{fill} are omitted,
@var{fill} defaults to zero.
@node P2align
@section @code{.p2align @var{abs-expr} , @var{abs-expr}}
@cindex padding the location counter given a power of two
@cindex @code{p2align} directive
Pad the location counter (in the current subsection) to a particular
storage boundary. The first expression (which must be absolute) is the
number of low-order zero bits the location counter must have after
advancement. For example @samp{.p2align 3} advances the location
counter until it a multiple of 8. If the location counter is already a
multiple of 8, no change is needed.
The second expression (also absolute) gives the value to be stored in
the padding bytes. It (and the comma) may be omitted. If it is
omitted, the padding bytes are zero.
@node Psize
@section @code{.psize @var{lines} , @var{columns}}
@ -5912,42 +5953,42 @@ The following addressing modes are understood:
@samp{#@var{digits}}
@item Data Register
@samp{d0} through @samp{d7}
@samp{%d0} through @samp{%d7}
@item Address Register
@samp{a0} through @samp{a7}@*
@samp{a7} is also known as @samp{sp}, i.e. the Stack Pointer. @code{a6}
is also known as @samp{fp}, the Frame Pointer.
@samp{%a0} through @samp{%a7}@*
@samp{%a7} is also known as @samp{%sp}, i.e. the Stack Pointer. @code{%a6}
is also known as @samp{%fp}, the Frame Pointer.
@item Address Register Indirect
@samp{a0@@} through @samp{a7@@}
@samp{%a0@@} through @samp{%a7@@}
@item Address Register Postincrement
@samp{a0@@+} through @samp{a7@@+}
@samp{%a0@@+} through @samp{%a7@@+}
@item Address Register Predecrement
@samp{a0@@-} through @samp{a7@@-}
@samp{%a0@@-} through @samp{%a7@@-}
@item Indirect Plus Offset
@samp{@var{apc}@@(@var{digits})}
@samp{%@var{apc}@@(@var{digits})}
@item Index
@samp{@var{apc}@@(@var{digits},@var{register}:@var{size}:@var{scale})}
@samp{%@var{apc}@@(@var{digits},%@var{register}:@var{size}:@var{scale})}
or @samp{@var{apc}@@(@var{register}:@var{size}:@var{scale})}
or @samp{%@var{apc}@@(%@var{register}:@var{size}:@var{scale})}
@item Postindex
@samp{@var{apc}@@(@var{digits})@@(@var{digits},@var{register}:@var{size}:@var{scale})}
@samp{%@var{apc}@@(@var{digits})@@(@var{digits},%@var{register}:@var{size}:@var{scale})}
or @samp{@var{apc}@@(@var{digits})@@(@var{register}:@var{size}:@var{scale})}
or @samp{%@var{apc}@@(@var{digits})@@(%@var{register}:@var{size}:@var{scale})}
@item Preindex
@samp{@var{apc}@@(@var{digits},@var{register}:@var{size}:@var{scale})@@(@var{digits})}
@samp{%@var{apc}@@(@var{digits},%@var{register}:@var{size}:@var{scale})@@(@var{digits})}
or @samp{@var{apc}@@(@var{register}:@var{size}:@var{scale})@@(@var{digits})}
or @samp{%@var{apc}@@(%@var{register}:@var{size}:@var{scale})@@(@var{digits})}
@item Memory Indirect
@samp{@var{apc}@@(@var{digits})@@(@var{digits})}
@samp{%@var{apc}@@(@var{digits})@@(@var{digits})}
@item Absolute
@samp{@var{symbol}}, or @samp{@var{digits}}
@ -5959,13 +6000,12 @@ by @samp{:b}, @samp{:w}, or @samp{:l}.
@end ignore
@end table
For some configurations, especially those where the compiler normally
does not prepend an underscore to the names of user variables, the
assembler requires a @samp{%} before any use of a register name. This
is intended to let the assembler distinguish between user variables and
registers named @samp{a0} through @samp{a7}, and so on. The @samp{%} is
always accepted, but is only required for some configurations, notably
@samp{m68k-coff}.
For some configurations, especially those where the compiler normally does not
prepend an underscore to the names of user variables, the assembler requires a
@samp{%} before any use of a register name. This is intended to let the
assembler distinguish between C variables and registers named @samp{a0} through
@samp{a7}, and so on. The @samp{%} is always accepted, but is not required for
certain configurations, notably @samp{sun3}.
@node M68K-Moto-Syntax
@section Motorola Syntax
@ -5973,53 +6013,43 @@ always accepted, but is only required for some configurations, notably
@cindex Motorola syntax for the 680x0
@cindex alternate syntax for the 680x0
The standard Motorola syntax for this chip differs from the syntax
already discussed (@pxref{M68K-Syntax,,Syntax}). @code{@value{AS}} can
accept some forms of Motorola syntax for operands, even if @sc{mit} syntax is
used for other operands in the same instruction. The
two kinds of syntax are fully compatible; our support for Motorola syntax is
simply incomplete at present.
@ignore
@c FIXME! I can't figure out what this means. Surely the "always" is in some
@c restricted context, for instance. It's not necessary for the preceding text
@c to explain this, so just ignore it for now; re-enable someday when someone
@c has time to explain it better.
, because the Motorola syntax never uses
the @samp{@@} character and the @sc{mit} syntax always does, except in
cases where the syntaxes are identical.
@end ignore
The standard Motorola syntax for this chip differs from the syntax already
discussed (@pxref{M68K-Syntax,,Syntax}). @code{@value{AS}} can accept some
forms of Motorola syntax for operands, even if @sc{mit} syntax is used for
other operands in the same instruction. The two kinds of syntax are fully
compatible; our support for Motorola syntax is simply incomplete at present.
@cindex M680x0 syntax
@cindex syntax, M680x0
In particular, you may write or generate M68K assembler with the
following conventions:
(In the following table @dfn{apc} stands for any of the address
registers (@samp{a0} through @samp{a7}), nothing, (@samp{}), the
Program Counter (@samp{pc}), or the zero-address relative to the
program counter (@samp{zpc}).)
(In the following table @dfn{%apc} stands for any of the address registers
(@samp{%a0} through @samp{%a7}), nothing (@samp{}), the Program Counter
(@samp{%pc}), or the zero-address relative to the program counter
(@samp{%zpc}).)
@cindex M680x0 addressing modes
@cindex addressing modes, M680x0
The following additional addressing modes are understood:
@table @dfn
@item Address Register Indirect
@samp{a0} through @samp{a7}@*
@samp{a7} is also known as @samp{sp}, i.e. the Stack Pointer. @code{a6}
is also known as @samp{fp}, the Frame Pointer.
@samp{%a0} through @samp{%a7}@*
@samp{%a7} is also known as @samp{%sp}, i.e. the Stack Pointer. @code{%a6}
is also known as @samp{%fp}, the Frame Pointer.
@item Address Register Postincrement
@samp{(a0)+} through @samp{(a7)+}
@samp{(%a0)+} through @samp{(%a7)+}
@item Address Register Predecrement
@samp{-(a0)} through @samp{-(a7)}
@samp{-(%a0)} through @samp{-(%a7)}
@item Indirect Plus Offset
@samp{@var{digits}(@var{apc})}
@samp{@var{digits}(%@var{apc})}
@item Index
@samp{@var{digits}(@var{apc},(@var{register}.@var{size}*@var{scale}))}@*
or @samp{(@var{apc},@var{register}.@var{size}*@var{scale})}@*
@samp{@var{digits}(%@var{apc},(%@var{register}.@var{size}*@var{scale}))}@*
or @samp{(%@var{apc},%@var{register}.@var{size}*@var{scale})}@*
In either case, @var{size} and @var{scale} are optional
(@var{scale} defaults to @samp{1}, @var{size} defaults to @samp{l}).
@var{scale} can be @samp{1}, @samp{2}, @samp{4}, or @samp{8}.
@ -6284,10 +6314,11 @@ successively higher architectures as it encounters instructions that
only exist in the higher levels.
@table @code
@item -Av6 | -Av7 | -Av8 | -Asparclite
@item -Av6 | -Av7 | -Av8 | -Av9 | -Asparclite
@kindex -Av6
@kindex Av7
@kindex -Av8
@kindex -Av9
@kindex -Asparclite
Use one of the @samp{-A} options to select one of the SPARC
architectures explicitly. If you select an architecture explicitly,
@ -6322,6 +6353,10 @@ The Sparc version of @code{@value{AS}} supports the following additional
machine directives:
@table @code
@item .align
@cindex @code{align} directive, SPARC
This must be followed by the desired alignment in bytes.
@item .common
@cindex @code{common} directive, SPARC
This must be followed by a symbol name, a positive number, and
@ -6355,8 +6390,13 @@ This is functionally identical to the @code{.space} directive.
@item .word
@cindex @code{word} directive, SPARC
On the Sparc, the .word directive produces 32 bit values,
On the Sparc, the @code{.word} directive produces 32 bit values,
instead of the 16 bit values it produces on many other machines.
@item .xword
@cindex @code{xword} directive, SPARC
On the Sparc V9 processor, the @code{.xword} directive produces
64 bit values.
@end table
@end ifset
@ -6382,6 +6422,7 @@ instead of the 16 bit values it produces on many other machines.
* i386-Memory:: Memory References
* i386-jumps:: Handling of Jump Instructions
* i386-Float:: Floating Point
* i386-16bit:: Writing 16-bit Code
* i386-Notes:: Notes
@end menu
@ -6758,6 +6799,51 @@ of the @samp{fn@dots{}} instructions. For example, @samp{fsave} and
instructions are made equivalent to @samp{f@dots{}} instructions. If
@samp{fwait} is desired it must be explicitly coded.
@node i386-16bit
@section Writing 16-bit Code
@cindex i386 16-bit code
@cindex 16-bit code, i386
@cindex real-mode code, i386
@cindex @code{code16} directive, i386
@cindex @code{code32} directive, i386
While GAS normally writes only ``pure'' 32-bit i386 code, it has limited
support for writing code to run in real mode or in 16-bit protected mode
code segments. To do this, insert a @samp{.code16} directive before the
assembly language instructions to be run in 16-bit mode. You can switch
GAS back to writing normal 32-bit code with the @samp{.code32} directive.
GAS understands exactly the same assembly language syntax in 16-bit mode as
in 32-bit mode. The function of any given instruction is exactly the same
regardless of mode, as long as the resulting object code is executed in the
mode for which GAS wrote it. So, for example, the @samp{ret} mnemonic
produces a 32-bit return instruction regardless of whether it is to be run
in 16-bit or 32-bit mode. (If GAS is in 16-bit mode, it will add an
operand size prefix to the instruction to force it to be a 32-bit return.)
This means, for one thing, that you can use GNU CC to write code to be run
in real mode or 16-bit protected mode. Just insert the statement
@samp{asm(".code16");} at the beginning of your C source file, and while
GNU CC will still be generating 32-bit code, GAS will automatically add all
the necessary size prefixes to make that code run in 16-bit mode. Of
course, since GNU CC only writes small-model code (it doesn't know how to
attach segment selectors to pointers like native x86 compilers do), any
16-bit code you write with GNU CC will essentially be limited to a 64K
address space. Also, there will be a code size and performance penalty
due to all the extra address and operand size prefixes GAS has to add to
the instructions.
Note that placing GAS in 16-bit mode does not mean that the resulting
code will necessarily run on a 16-bit pre-80386 processor. To write code
that runs on such a processor, you would have to refrain from using
@emph{any} 32-bit constructs which require GAS to output address or
operand size prefixes. At the moment this would be rather difficult,
because GAS currently supports @emph{only} 32-bit addressing modes: when
writing 16-bit code, it @emph{always} outputs address size prefixes for any
instruction that uses a non-register addressing mode. So you can write
code that runs on 16-bit processors, but only if that code never references
memory.
@node i386-Notes
@section Notes

View File

@ -195,6 +195,7 @@ static const pseudo_typeS potable[] =
{"align", s_align_ptwo, 0},
{"ascii", stringer, 0},
{"asciz", stringer, 1},
{"balign", s_align_bytes, 0},
/* block */
{"byte", cons, 1},
{"comm", s_comm, 0},
@ -238,6 +239,7 @@ static const pseudo_typeS potable[] =
{"nolist", listing_list, 0}, /* Turn listing off */
{"octa", cons, 16},
{"org", s_org, 0},
{"p2align", s_align_ptwo, 0},
{"psize", listing_psize, 0}, /* set paper size */
/* print */
{"quad", cons, 8},
@ -988,11 +990,18 @@ s_app_line (ignore)
/* The given number is that of the next line. */
l = get_absolute_expression () - 1;
new_logical_line ((char *) NULL, l);
if (l < 0)
/* Some of the back ends can't deal with non-positive line numbers.
Besides, it's silly. */
as_warn ("Line numbers must be positive; line number %d rejected.", l+1);
else
{
new_logical_line ((char *) NULL, l);
#ifdef LISTING
if (listing)
listing_source_line (l);
if (listing)
listing_source_line (l);
#endif
}
demand_empty_rest_of_line ();
}
@ -1426,14 +1435,12 @@ s_space (mult)
int mult;
{
expressionS exp;
long temp_repeat, temp_fill;
long temp_fill;
char *p = 0;
/* Just like .fill, but temp_size = 1 */
expression (&exp);
if (exp.X_op == O_constant
/* for testing purposes */
&& 0)
if (exp.X_op == O_constant)
{
long repeat;
@ -1450,7 +1457,7 @@ s_space (mult)
if (!need_pass_2)
p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
temp_repeat, (char *) 0);
repeat, (char *) 0);
}
else
{
@ -1458,13 +1465,14 @@ s_space (mult)
p = frag_var (rs_space, 1, 1, (relax_substateT) 0,
make_expr_symbol (&exp), 0L, (char *) 0);
}
if (get_absolute_expression_and_terminator (&temp_repeat) == ',')
SKIP_WHITESPACE ();
if (*input_line_pointer == ',')
{
input_line_pointer++;
temp_fill = get_absolute_expression ();
}
else
{
input_line_pointer--; /* Backup over what was not a ','. */
temp_fill = 0;
}
if (p)