Support for more portable alignment handling in assembly code, based on patches
authorKen Raeburn <raeburn@cygnus>
Wed, 26 Apr 1995 20:02:18 +0000 (20:02 +0000)
committerKen Raeburn <raeburn@cygnus>
Wed, 26 Apr 1995 20:02:18 +0000 (20:02 +0000)
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.

gas/ChangeLog
gas/doc/as.texinfo
gas/read.c

index 59469c3e1fd9337ab2ec49d5aed81ba732d7a022..93c2f5db7c9941920b92b12bb487e3177e1036e6 100644 (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
index dbb69cf9fa69b3069ca5d63f849417a73a55bddd..72321008dc090e300f5627c142f1c08ecd525236 100644 (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
-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
 
index 2b20177d3f16b8446d41386dc8b090c76d58adfa..9d40608af41a25a9077e013aea968abc41ae300d 100644 (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)