From: Ken Raeburn Date: Wed, 26 Apr 1995 20:02:18 +0000 (+0000) Subject: Support for more portable alignment handling in assembly code, based on patches X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=931a8fab1b43ccf65c169feeea6001294b55e86a;p=binutils-gdb.git Support for more portable alignment handling in assembly code, based on patches from Bryan Ford : * 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. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 59469c3e1fd..93c2f5db7c9 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +Wed Apr 26 15:54:10 1995 Ken Raeburn + + Support for more portable alignment handling in assembly code, + based on patches from Bryan Ford : + * 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 * configure, configure.in: Look for m68k-*-vxworks* rather than diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo index dbb69cf9fa6..72321008dc0 100644 --- a/gas/doc/as.texinfo +++ b/gas/doc/as.texinfo @@ -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 -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. +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. -@ifset HPPA -For the HPPA, the first expression (which must be absolute) is the +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. -@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. +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. + +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 diff --git a/gas/read.c b/gas/read.c index 2b20177d3f1..9d40608af41 100644 --- a/gas/read.c +++ b/gas/read.c @@ -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)