]> granicus.if.org Git - yasm/commitdiff
Implement align and org bytecodes. While we're here, implement .zero
authorPeter Johnson <peter@tortall.net>
Mon, 3 Oct 2005 05:52:04 +0000 (05:52 -0000)
committerPeter Johnson <peter@tortall.net>
Mon, 3 Oct 2005 05:52:04 +0000 (05:52 -0000)
directive for GAS (it's generated by GCC).

* bytecode.c (bytecode_align): Update for full align implementation.
(yasm_bc_create_align): Likewise.
(bc_align_finalize): New.
(bc_align_resolve, bc_align_tobytes): Real implementation.
* bytecode.h (yasm_bc_create_align): Update to match.
* arch.h (get_fill, yasm_arch_get_fill): New, to get NOP fill patterns.
* x86arch.c (x86_get_fill): Implement.
* lc3barch.c (lc3b_get_fill): Likewise (probably buggy, there's no real NOP).

* bytecode.c (bytecode_org): New org bytecode.
(bc_org_callback, bc_org_destroy, bc_org_print, bc_org_resolve)
(bc_org_tobytes, yasm_bc_create_org): Implement.

* gas-parser.h (yasm_parser_gas): Add code_section flag to indicate when to
use code fill vs. data fill.
* gas-parser.c: Initialize flag.
* gas-bison.y: Update flag in various places.  Generate org bytecode.
Call gas_parser_align to generate align bytecode.
(gas_parser_align): Generate align bytecode.

* gas-bison.y: Implement .zero directive.
* gas-token.re: Likewise.

* align32, align64: New tests to test align directive NOP generation.

svn path=/trunk/yasm/; revision=1263

17 files changed:
libyasm/arch.h
libyasm/bytecode.c
libyasm/bytecode.h
modules/arch/lc3b/lc3barch.c
modules/arch/x86/tests/gas32/Makefile.inc
modules/arch/x86/tests/gas32/align32.asm [new file with mode: 0644]
modules/arch/x86/tests/gas32/align32.errwarn [new file with mode: 0644]
modules/arch/x86/tests/gas32/align32.hex [new file with mode: 0644]
modules/arch/x86/tests/gas64/Makefile.inc
modules/arch/x86/tests/gas64/align64.asm [new file with mode: 0644]
modules/arch/x86/tests/gas64/align64.errwarn [new file with mode: 0644]
modules/arch/x86/tests/gas64/align64.hex [new file with mode: 0644]
modules/arch/x86/x86arch.c
modules/parsers/gas/gas-bison.y
modules/parsers/gas/gas-parser.c
modules/parsers/gas/gas-parser.h
modules/parsers/gas/gas-token.re

index 72564c75e8624790d842cd5d7a777bd9eb9ba7d7..d4dc6fb7c58f339d580728a21e9f8f04a7127630 100644 (file)
@@ -166,6 +166,11 @@ typedef struct yasm_arch_module {
                            /*@null@*/ yasm_valparamhead *objext_valparams,
                            yasm_object *object, unsigned long line);
 
+    /** Module-level implementation of yasm_arch_get_fill().
+     * Call yasm_arch_get_fill() instead of calling this function.
+     */
+    const unsigned char ** (*get_fill) (const yasm_arch *arch);
+
     /** Module-level implementation of yasm_arch_finalize_insn().
      * Call yasm_arch_finalize_insn() instead of calling this function.
      */
@@ -456,6 +461,13 @@ int yasm_arch_parse_directive(yasm_arch *arch, const char *name,
                              /*@null@*/ yasm_valparamhead *objext_valparams,
                              yasm_object *object, unsigned long line);
 
+/** Get NOP fill patterns for 1-15 bytes of fill.
+ * \param arch         architecture
+ * \return 16-entry array of arrays; [0] is unused, [1] - [15] point to arrays
+ * of 1-15 bytes (respectively) in length.
+ */
+const unsigned char **yasm_arch_get_fill(const yasm_arch *arch);
+
 /** Finalize an instruction from a semi-generic insn description.  Note an
  * existing bytecode is required.
  * \param arch         architecture
@@ -616,6 +628,8 @@ yasm_effaddr *yasm_arch_ea_create(yasm_arch *arch, /*@keep@*/ yasm_expr *e);
                                  object, line) \
     ((yasm_arch_base *)arch)->module->parse_directive \
        (arch, name, valparams, objext_valparams, object, line)
+#define yasm_arch_get_fill(arch) \
+    ((yasm_arch_base *)arch)->module->get_fill(arch)
 #define yasm_arch_finalize_insn(arch, bc, prev_bc, data, num_operands, \
                                operands, num_prefixes, prefixes, \
                                num_segregs, segregs) \
index 2c212b0489a9ac23bfa2b308ba36c993b9d82aa4..bf424d367fdb6fd81c07d34985b7d14ed1703452 100644 (file)
@@ -81,9 +81,22 @@ typedef struct bytecode_incbin {
 } bytecode_incbin;
 
 typedef struct bytecode_align {
-    unsigned long boundary;    /* alignment boundary */
+    /*@only@*/ yasm_expr *boundary;    /* alignment boundary */
+
+    /* What to fill intervening locations with, NULL if using code_fill */
+    /*@only@*/ /*@null@*/ yasm_expr *fill;
+
+    /* Maximum number of bytes to skip, NULL if no maximum. */
+    /*@only@*/ /*@null@*/ yasm_expr *maxskip;
+
+    /* Code fill, NULL if using 0 fill */
+    /*@null@*/ const unsigned char **code_fill;
 } bytecode_align;
 
+typedef struct bytecode_org {
+    unsigned long start;       /* target starting offset within section */
+} bytecode_org;
+
 typedef struct bytecode_insn {
     /*@dependent@*/ yasm_arch *arch;
     unsigned long insn_data[4];
@@ -128,12 +141,21 @@ static int bc_incbin_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
 
 static void bc_align_destroy(void *contents);
 static void bc_align_print(const void *contents, FILE *f, int indent_level);
+static void bc_align_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
 static yasm_bc_resolve_flags bc_align_resolve
     (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
 static int bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
                            yasm_output_expr_func output_expr,
                            /*@null@*/ yasm_output_reloc_func output_reloc);
 
+static void bc_org_destroy(void *contents);
+static void bc_org_print(const void *contents, FILE *f, int indent_level);
+static yasm_bc_resolve_flags bc_org_resolve
+    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_org_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                         yasm_output_expr_func output_expr,
+                         /*@null@*/ yasm_output_reloc_func output_reloc);
+
 static void bc_insn_destroy(void *contents);
 static void bc_insn_print(const void *contents, FILE *f, int indent_level);
 static void bc_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
@@ -172,11 +194,19 @@ static const yasm_bytecode_callback bc_incbin_callback = {
 static const yasm_bytecode_callback bc_align_callback = {
     bc_align_destroy,
     bc_align_print,
-    yasm_bc_finalize_common,
+    bc_align_finalize,
     bc_align_resolve,
     bc_align_tobytes
 };
 
+static const yasm_bytecode_callback bc_org_callback = {
+    bc_org_destroy,
+    bc_org_print,
+    yasm_bc_finalize_common,
+    bc_org_resolve,
+    bc_org_tobytes
+};
+
 static const yasm_bytecode_callback bc_insn_callback = {
     bc_insn_destroy,
     bc_insn_print,
@@ -689,6 +719,9 @@ yasm_bc_create_incbin(char *filename, yasm_expr *start, yasm_expr *maxlen,
 static void
 bc_align_destroy(void *contents)
 {
+    bytecode_align *align = (bytecode_align *)contents;
+    if (align->fill)
+       yasm_expr_destroy(align->fill);
     yasm_xfree(contents);
 }
 
@@ -697,16 +730,54 @@ bc_align_print(const void *contents, FILE *f, int indent_level)
 {
     const bytecode_align *align = (const bytecode_align *)contents;
     fprintf(f, "%*s_Align_\n", indent_level, "");
-    fprintf(f, "%*sBoundary=%lu\n", indent_level, "", align->boundary);
+    fprintf(f, "%*sBoundary=", indent_level, "");
+    yasm_expr_print(align->boundary, f);
+    fprintf(f, "\n%*sFill=", indent_level, "");
+    yasm_expr_print(align->fill, f);
+    fprintf(f, "\n%*sMax Skip=", indent_level, "");
+    yasm_expr_print(align->maxskip, f);
+    fprintf(f, "\n");
+}
+
+static void
+bc_align_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
+{
+    bytecode_align *align = (bytecode_align *)bc->contents;
+    if (!yasm_expr_get_intnum(&align->boundary, NULL))
+       yasm__error(bc->line, N_("align boundary must be a constant"));
+    if (align->fill && !yasm_expr_get_intnum(&align->fill, NULL))
+       yasm__error(bc->line, N_("align fill must be a constant"));
+    if (align->maxskip && !yasm_expr_get_intnum(&align->maxskip, NULL))
+       yasm__error(bc->line, N_("align maximum skip must be a constant"));
 }
 
 static yasm_bc_resolve_flags
 bc_align_resolve(yasm_bytecode *bc, int save,
                 yasm_calc_bc_dist_func calc_bc_dist)
 {
-    yasm_internal_error(N_("TODO: align bytecode not implemented!"));
-    /*@notreached@*/
-    return YASM_BC_RESOLVE_ERROR;
+    bytecode_align *align = (bytecode_align *)bc->contents;
+    unsigned long end;
+    unsigned long boundary =
+       yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, NULL));
+
+    if (boundary == 0) {
+       bc->len = 0;
+       return YASM_BC_RESOLVE_MIN_LEN;
+    }
+
+    end = bc->offset;
+    if (bc->offset & (boundary-1))
+       end = (bc->offset & ~(boundary-1)) + boundary;
+
+    bc->len = end - bc->offset;
+
+    if (align->maxskip) {
+       unsigned long maxskip =
+           yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip, NULL));
+       if ((end - bc->offset) > maxskip)
+           bc->len = 0;
+    }
+    return YASM_BC_RESOLVE_MIN_LEN;
 }
 
 static int
@@ -714,21 +785,125 @@ bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
                 yasm_output_expr_func output_expr,
                 /*@unused@*/ yasm_output_reloc_func output_reloc)
 {
-    yasm_internal_error(N_("TODO: align bytecode not implemented!"));
-    /*@notreached@*/
-    return 1;
+    bytecode_align *align = (bytecode_align *)bc->contents;
+    unsigned long len, i;
+    unsigned long boundary =
+       yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, NULL));
+
+    if (boundary == 0)
+       return 0;
+    else {
+       unsigned long end = bc->offset;
+       if (bc->offset & (boundary-1))
+           end = (bc->offset & ~(boundary-1)) + boundary;
+       len = end - bc->offset;
+       if (len == 0)
+           return 0;
+       if (align->maxskip) {
+           unsigned long maxskip =
+               yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip,
+                                                         NULL));
+           if (len > maxskip)
+               return 0;
+       }
+    }
+
+    if (align->fill) {
+       unsigned long v;
+       v = yasm_intnum_get_uint(yasm_expr_get_intnum(&align->fill, NULL));
+       memset(*bufp, (int)v, len);
+       *bufp += len;
+    } else if (align->code_fill) {
+       while (len > 15) {
+           memcpy(*bufp, align->code_fill[15], 15);
+           *bufp += 15;
+           len -= 15;
+       }
+       memcpy(*bufp, align->code_fill[len], len);
+       *bufp += len;
+    } else {
+       /* Just fill with 0 */
+       memset(*bufp, 0, len);
+       *bufp += len;
+    }
+    return 0;
 }
 
 yasm_bytecode *
-yasm_bc_create_align(unsigned long boundary, unsigned long line)
+yasm_bc_create_align(yasm_expr *boundary, yasm_expr *fill,
+                    yasm_expr *maxskip, const unsigned char **code_fill,
+                    unsigned long line)
 {
     bytecode_align *align = yasm_xmalloc(sizeof(bytecode_align));
 
     align->boundary = boundary;
+    align->fill = fill;
+    align->maxskip = maxskip;
+    align->code_fill = code_fill;
 
     return yasm_bc_create_common(&bc_align_callback, align, line);
 }
 
+static void
+bc_org_destroy(void *contents)
+{
+    yasm_xfree(contents);
+}
+
+static void
+bc_org_print(const void *contents, FILE *f, int indent_level)
+{
+    const bytecode_org *org = (const bytecode_org *)contents;
+    fprintf(f, "%*s_Org_\n", indent_level, "");
+    fprintf(f, "%*sStart=%lu\n", indent_level, "", org->start);
+}
+
+static yasm_bc_resolve_flags
+bc_org_resolve(yasm_bytecode *bc, int save,
+              yasm_calc_bc_dist_func calc_bc_dist)
+{
+    bytecode_org *org = (bytecode_org *)bc->contents;
+
+    /* Check for overrun */
+    if (bc->offset > org->start) {
+       yasm__error(bc->line, N_("ORG overlap with already existing data"));
+       return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
+    }
+
+    /* Generate space to start offset */
+    bc->len = org->start - bc->offset;
+    return YASM_BC_RESOLVE_MIN_LEN;
+}
+
+static int
+bc_org_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+              yasm_output_expr_func output_expr,
+              /*@unused@*/ yasm_output_reloc_func output_reloc)
+{
+    bytecode_org *org = (bytecode_org *)bc->contents;
+    unsigned long len, i;
+
+    /* Sanity check for overrun */
+    if (bc->offset > org->start) {
+       yasm__error(bc->line, N_("ORG overlap with already existing data"));
+       return 1;
+    }
+    len = org->start - bc->offset;
+    for (i=0; i<len; i++)
+       YASM_WRITE_8(*bufp, 0);
+    return 0;
+}
+
+yasm_bytecode *
+yasm_bc_create_org(unsigned long start, unsigned long line)
+{
+    bytecode_org *org = yasm_xmalloc(sizeof(bytecode_org));
+
+    org->start = start;
+
+    return yasm_bc_create_common(&bc_org_callback, org, line);
+}
+
 static void
 bc_insn_destroy(void *contents)
 {
index 79d940b9788d884fd132994e5d1c33f933a2f408..c3b478bb7b0480fec76dc9bf716eb4d59dc71535 100644 (file)
@@ -166,11 +166,29 @@ void yasm_bc_set_multiple(yasm_bytecode *bc, /*@keep@*/ yasm_expr *e);
 
 /** Create a bytecode that aligns the following bytecode to a boundary.
  * \param boundary     byte alignment (must be a power of two)
+ * \param fill         fill data (if NULL, code_fill or 0 is used)
+ * \param maxskip      maximum number of bytes to skip
+ * \param code_fill    code fill data (if NULL, 0 is used)
  * \param line         virtual line (from yasm_linemap)
  * \return Newly allocated bytecode.
+ * \note The precedence on generated fill is as follows:
+ *       - from fill parameter (if not NULL)
+ *       - from code_fill parameter (if not NULL)
+ *       - 0
  */
 /*@only@*/ yasm_bytecode *yasm_bc_create_align
-    (unsigned long boundary, unsigned long line);
+    (/*@keep@*/ yasm_expr *boundary, /*@keep@*/ /*@null@*/ yasm_expr *fill,
+     /*@keep@*/ /*@null@*/ yasm_expr *maxskip,
+     /*@null@*/ const unsigned char **code_fill, unsigned long line);
+
+/** Create a bytecode that puts the following bytecode at a fixed section
+ * offset.
+ * \param start                section offset of following bytecode
+ * \param line         virtual line (from yasm_linemap)
+ * \return Newly allocated bytecode.
+ */
+/*@only@*/ yasm_bytecode *yasm_bc_create_org
+    (unsigned long start, unsigned long line);
 
 /** Create a bytecode that represents a single instruction.
  * \param arch         instruction's architecture
index e2071ab8c829361be282709113a72fae68f6ac6b..f8f26c53e9dee8832380774d999de6ff89f6097e 100644 (file)
@@ -89,6 +89,35 @@ lc3b_parse_directive(/*@unused@*/ yasm_arch *arch,
     return 1;
 }
 
+static const unsigned char **
+lc3b_get_fill(const yasm_arch *arch)
+{
+    /* NOP pattern is AND r0, r0, r0 repeated */
+    static const char *fill[16] = {
+       NULL,           /* unused */
+       NULL,           /* 1 - illegal; all opcodes are 2 bytes long */
+       "\x50\x00",                     /* 4 */
+       NULL,                           /* 3 - illegal */
+       "\x50\x00\x50\x00",             /* 4 */
+       NULL,                           /* 5 - illegal */
+       "\x50\x00\x50\x00\x50\x00",     /* 6 */
+       NULL,                           /* 7 - illegal */
+       "\x50\x00\x50\x00\x50\x00"      /* 8 */
+       "\x50\x00",
+       NULL,                           /* 9 - illegal */
+       "\x50\x00\x50\x00\x50\x00"      /* 10 */
+       "\x50\x00\x50\x00",
+       NULL,                           /* 11 - illegal */
+       "\x50\x00\x50\x00\x50\x00"      /* 12 */
+       "\x50\x00\x50\x00\x50\x00",
+       NULL,                           /* 13 - illegal */
+       "\x50\x00\x50\x00\x50\x00"      /* 14 */
+       "\x50\x00\x50\x00\x50\x00\x50\x00",
+       NULL                            /* 15 - illegal */
+    };
+    return (const unsigned char **)fill;
+}
+
 static unsigned int
 lc3b_get_reg_size(/*@unused@*/ yasm_arch *arch, /*@unused@*/ unsigned long reg)
 {
@@ -147,6 +176,7 @@ yasm_arch_module yasm_lc3b_LTX_arch = {
     yasm_lc3b__parse_check_prefix,
     yasm_lc3b__parse_check_targetmod,
     lc3b_parse_directive,
+    lc3b_get_fill,
     yasm_lc3b__finalize_insn,
     lc3b_floatnum_tobytes,
     yasm_lc3b__intnum_fixup_rel,
index 4fa07307b73a652b7e7b488f4c4d4b439cdc3d67..e8b5d1d24d7db06e6265e52264de39a4a200102c 100644 (file)
@@ -3,6 +3,9 @@
 TESTS += modules/arch/x86/tests/gas32/x86_gas32_test.sh
 
 EXTRA_DIST += modules/arch/x86/tests/gas32/x86_gas32_test.sh
+EXTRA_DIST += modules/arch/x86/tests/gas32/align32.asm
+EXTRA_DIST += modules/arch/x86/tests/gas32/align32.errwarn
+EXTRA_DIST += modules/arch/x86/tests/gas32/align32.hex
 EXTRA_DIST += modules/arch/x86/tests/gas32/gas-movdq32.asm
 EXTRA_DIST += modules/arch/x86/tests/gas32/gas-movdq32.errwarn
 EXTRA_DIST += modules/arch/x86/tests/gas32/gas-movdq32.hex
diff --git a/modules/arch/x86/tests/gas32/align32.asm b/modules/arch/x86/tests/gas32/align32.asm
new file mode 100644 (file)
index 0000000..7d5dfa6
--- /dev/null
@@ -0,0 +1,82 @@
+.text
+# 15 fill
+.byte 0xff
+.p2align 4
+# 14 fill
+.byte 0xff
+.byte 0xff
+.p2align 4
+# 13 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 4
+# 12 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 4
+# 11 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 4
+# 10 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 4
+# 9 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 4
+# 8 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 4
+# 7 fill
+.byte 0xff
+.p2align 3
+# 6 fill
+.byte 0xff
+.byte 0xff
+.p2align 3
+# 5 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 3
+# 4 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 3
+# 3 fill
+.byte 0xff
+.p2align 2
+# 2 fill
+.byte 0xff
+.byte 0xff
+.p2align 2
+# 1 fill
+.byte 0xff
+.p2align 1
+
diff --git a/modules/arch/x86/tests/gas32/align32.errwarn b/modules/arch/x86/tests/gas32/align32.errwarn
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/modules/arch/x86/tests/gas32/align32.hex b/modules/arch/x86/tests/gas32/align32.hex
new file mode 100644 (file)
index 0000000..66b48bb
--- /dev/null
@@ -0,0 +1,536 @@
+7f 
+45 
+4c 
+46 
+01 
+01 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+03 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+50 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+34 
+00 
+00 
+00 
+00 
+00 
+28 
+00 
+05 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+ff 
+eb 
+0d 
+90 
+90 
+90 
+90 
+90 
+90 
+90 
+90 
+90 
+90 
+90 
+90 
+90 
+ff 
+ff 
+8d 
+b4 
+26 
+00 
+00 
+00 
+00 
+8d 
+bc 
+27 
+00 
+00 
+00 
+00 
+ff 
+ff 
+ff 
+8d 
+b6 
+00 
+00 
+00 
+00 
+8d 
+bc 
+27 
+00 
+00 
+00 
+00 
+ff 
+ff 
+ff 
+ff 
+8d 
+b6 
+00 
+00 
+00 
+00 
+8d 
+bf 
+00 
+00 
+00 
+00 
+ff 
+ff 
+ff 
+ff 
+ff 
+8d 
+74 
+26 
+00 
+8d 
+bc 
+27 
+00 
+00 
+00 
+00 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+8d 
+76 
+00 
+8d 
+bc 
+27 
+00 
+00 
+00 
+00 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+89 
+f6 
+8d 
+bc 
+27 
+00 
+00 
+00 
+00 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+90 
+8d 
+b4 
+26 
+00 
+00 
+00 
+00 
+ff 
+8d 
+b4 
+26 
+00 
+00 
+00 
+00 
+ff 
+ff 
+8d 
+b6 
+00 
+00 
+00 
+00 
+ff 
+ff 
+ff 
+90 
+8d 
+74 
+26 
+00 
+ff 
+ff 
+ff 
+ff 
+8d 
+74 
+26 
+00 
+ff 
+8d 
+76 
+00 
+ff 
+ff 
+89 
+f6 
+ff 
+90 
+00 
+00 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+2e 
+73 
+79 
+6d 
+74 
+61 
+62 
+00 
+2e 
+73 
+68 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+00 
+00 
+00 
+00 
+2d 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+f1 
+ff 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+17 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+ec 
+00 
+00 
+00 
+21 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+01 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+0f 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+14 
+01 
+00 
+00 
+30 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+aa 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
index 050d1f75791fba89083f07c8c166d0dfdd47787b..8d87fd9a95c88bc265834ae2eae7a607ccc89f04 100644 (file)
@@ -3,6 +3,9 @@
 TESTS += modules/arch/x86/tests/gas64/x86_gas64_test.sh
 
 EXTRA_DIST += modules/arch/x86/tests/gas64/x86_gas64_test.sh
+EXTRA_DIST += modules/arch/x86/tests/gas64/align64.asm
+EXTRA_DIST += modules/arch/x86/tests/gas64/align64.errwarn
+EXTRA_DIST += modules/arch/x86/tests/gas64/align64.hex
 EXTRA_DIST += modules/arch/x86/tests/gas64/gas-cbw.asm
 EXTRA_DIST += modules/arch/x86/tests/gas64/gas-cbw.errwarn
 EXTRA_DIST += modules/arch/x86/tests/gas64/gas-cbw.hex
diff --git a/modules/arch/x86/tests/gas64/align64.asm b/modules/arch/x86/tests/gas64/align64.asm
new file mode 100644 (file)
index 0000000..7d5dfa6
--- /dev/null
@@ -0,0 +1,82 @@
+.text
+# 15 fill
+.byte 0xff
+.p2align 4
+# 14 fill
+.byte 0xff
+.byte 0xff
+.p2align 4
+# 13 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 4
+# 12 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 4
+# 11 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 4
+# 10 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 4
+# 9 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 4
+# 8 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 4
+# 7 fill
+.byte 0xff
+.p2align 3
+# 6 fill
+.byte 0xff
+.byte 0xff
+.p2align 3
+# 5 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 3
+# 4 fill
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.byte 0xff
+.p2align 3
+# 3 fill
+.byte 0xff
+.p2align 2
+# 2 fill
+.byte 0xff
+.byte 0xff
+.p2align 2
+# 1 fill
+.byte 0xff
+.p2align 1
+
diff --git a/modules/arch/x86/tests/gas64/align64.errwarn b/modules/arch/x86/tests/gas64/align64.errwarn
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/modules/arch/x86/tests/gas64/align64.hex b/modules/arch/x86/tests/gas64/align64.hex
new file mode 100644 (file)
index 0000000..3e9c5c1
--- /dev/null
@@ -0,0 +1,672 @@
+7f 
+45 
+4c 
+46 
+02 
+01 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+3e 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+60 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+05 
+00 
+01 
+00 
+ff 
+66 
+66 
+66 
+90 
+66 
+66 
+66 
+90 
+66 
+66 
+66 
+90 
+66 
+66 
+90 
+ff 
+ff 
+66 
+66 
+66 
+90 
+66 
+66 
+66 
+90 
+66 
+66 
+90 
+66 
+66 
+90 
+ff 
+ff 
+ff 
+66 
+66 
+66 
+90 
+66 
+66 
+90 
+66 
+66 
+90 
+66 
+66 
+90 
+ff 
+ff 
+ff 
+ff 
+66 
+66 
+66 
+90 
+66 
+66 
+66 
+90 
+66 
+66 
+66 
+90 
+ff 
+ff 
+ff 
+ff 
+ff 
+66 
+66 
+66 
+90 
+66 
+66 
+66 
+90 
+66 
+66 
+90 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+66 
+66 
+66 
+90 
+66 
+66 
+90 
+66 
+66 
+90 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+66 
+66 
+90 
+66 
+66 
+90 
+66 
+66 
+90 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+ff 
+66 
+66 
+66 
+90 
+66 
+66 
+66 
+90 
+ff 
+66 
+66 
+66 
+90 
+66 
+66 
+90 
+ff 
+ff 
+66 
+66 
+90 
+66 
+66 
+90 
+ff 
+ff 
+ff 
+66 
+66 
+90 
+66 
+90 
+ff 
+ff 
+ff 
+ff 
+66 
+66 
+66 
+90 
+ff 
+66 
+66 
+90 
+ff 
+ff 
+66 
+90 
+ff 
+90 
+00 
+00 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+2e 
+73 
+79 
+6d 
+74 
+61 
+62 
+00 
+2e 
+73 
+68 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+00 
+00 
+00 
+00 
+2d 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+04 
+00 
+f1 
+ff 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+17 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+ec 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+21 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+0f 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+14 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+48 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+18 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+aa 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
index 7486afb2bed04662f2cc23ced9c8126d6e1451aa..b6aaeab0b5c3a07f88d2c7c2a1080b590577f730 100644 (file)
@@ -128,6 +128,108 @@ x86_parse_directive(yasm_arch *arch, const char *name,
        return 1;
 }
 
+static const unsigned char **
+x86_get_fill(const yasm_arch *arch)
+{
+    const yasm_arch_x86 *arch_x86 = (const yasm_arch_x86 *)arch;
+
+    /* Fill patterns that GAS uses. */
+    static const char *fill16[16] = {
+       NULL,                           /* unused                       */
+       "\x90",                         /* 1 - nop                      */
+       "\x89\xf6",                     /* 2 - mov si, si               */
+       "\x8d\x74\x00",                 /* 3 - lea si, [si+byte 0]      */
+       "\x8d\xb4\x00\x00",             /* 4 - lea si, [si+word 0]      */
+       "\x90"                          /* 5 - nop                      */
+       "\x8d\xb4\x00\x00",             /*     lea si, [si+word 0]      */
+       "\x89\xf6"                      /* 6 - mov si, si               */
+       "\x8d\xbd\x00\x00",             /*     lea di, [di+word 0]      */
+       "\x8d\x74\x00"                  /* 7 - lea si, [si+byte 0]      */
+       "\x8d\xbd\x00\x00",             /*     lea di, [di+word 0]      */
+       "\x8d\xb4\x00\x00"              /* 8 - lea si, [si+word 0]      */
+       "\x8d\xbd\x00\x00"              /*     lea di, [di+word 0]      */
+       "\xeb\x07\x90\x90\x90\x90\x90"  /* 9 - jmp $+9; nop fill        */
+       "\x90\x90",
+       "\xeb\x08\x90\x90\x90\x90\x90"  /* 10 - jmp $+10; nop fill      */
+       "\x90\x90\x90",
+       "\xeb\x09\x90\x90\x90\x90\x90"  /* 11 - jmp $+11; nop fill      */
+       "\x90\x90\x90\x90",
+       "\xeb\x0a\x90\x90\x90\x90\x90"  /* 12 - jmp $+12; nop fill      */
+       "\x90\x90\x90\x90\x90",
+       "\xeb\x0b\x90\x90\x90\x90\x90"  /* 13 - jmp $+13; nop fill      */
+       "\x90\x90\x90\x90\x90\x90",
+       "\xeb\x0c\x90\x90\x90\x90\x90"  /* 14 - jmp $+14; nop fill      */
+       "\x90\x90\x90\x90\x90\x90\x90",
+       "\xeb\x0d\x90\x90\x90\x90\x90"  /* 15 - jmp $+15; nop fill      */
+       "\x90\x90\x90\x90\x90\x90\x90\x90"
+    };
+    static const char *fill32[16] = {
+       NULL,                           /* unused                       */
+       "\x90",                         /* 1 - nop                      */
+       "\x89\xf6",                     /* 2 - mov esi, esi             */
+       "\x8d\x76\x00",                 /* 3 - lea esi, [esi+byte 0]    */
+       "\x8d\x74\x26\x00",             /* 4 - lea esi, [esi*1+byte 0]  */
+       "\x90"                          /* 5 - nop                      */
+       "\x8d\x74\x26\x00",             /*     lea esi, [esi*1+byte 0]  */
+       "\x8d\xb6\x00\x00\x00\x00",     /* 6 - lea esi, [esi+dword 0]   */
+       "\x8d\xb4\x26\x00\x00\x00\x00", /* 7 - lea esi, [esi*1+dword 0] */
+       "\x90"                          /* 8 - nop                      */
+       "\x8d\xb4\x26\x00\x00\x00\x00", /*     lea esi, [esi*1+dword 0] */
+       "\x89\xf6"                      /* 9 - mov esi, esi             */
+       "\x8d\xbc\x27\x00\x00\x00\x00", /*     lea edi, [edi*1+dword 0] */
+       "\x8d\x76\x00"                  /* 10 - lea esi, [esi+byte 0]   */
+       "\x8d\xbc\x27\x00\x00\x00\x00", /*      lea edi, [edi+dword 0]  */
+       "\x8d\x74\x26\x00"              /* 11 - lea esi, [esi*1+byte 0] */
+       "\x8d\xbc\x27\x00\x00\x00\x00", /*      lea edi, [edi*1+dword 0]*/
+       "\x8d\xb6\x00\x00\x00\x00"      /* 12 - lea esi, [esi+dword 0]  */
+       "\x8d\xbf\x00\x00\x00\x00",     /*      lea edi, [edi+dword 0]  */
+       "\x8d\xb6\x00\x00\x00\x00"      /* 13 - lea esi, [esi+dword 0]  */
+       "\x8d\xbc\x27\x00\x00\x00\x00", /*      lea edi, [edi*1+dword 0]*/
+       "\x8d\xb4\x26\x00\x00\x00\x00"  /* 14 - lea esi, [esi*1+dword 0]*/
+       "\x8d\xbc\x27\x00\x00\x00\x00", /*      lea edi, [edi*1+dword 0]*/
+       "\xeb\x0d\x90\x90\x90\x90\x90"  /* 15 - jmp $+15; nop fill      */
+       "\x90\x90\x90\x90\x90\x90\x90\x90"
+    };
+    static const char *fill64[16] = {
+       NULL,                           /* unused                       */
+       "\x90",                         /* 1 - nop                      */
+       "\x66\x90",                     /* 2 - o16; nop                 */
+       "\x66\x66\x90",                 /* 3 - o16; o16; nop            */
+       "\x66\x66\x66\x90",             /* 4 - o16; o16; o16; nop       */
+       "\x66\x66\x90\x66\x90",         /* 5 */
+       "\x66\x66\x90\x66\x66\x90",     /* 6 */
+       "\x66\x66\x66\x90\x66\x66\x90", /* 7 */
+       "\x66\x66\x66\x90\x66\x66\x66"  /* 8 */
+       "\x90",
+       "\x66\x66\x90\x66\x66\x90\x66"  /* 9 */
+       "\x66\x90",
+       "\x66\x66\x66\x90\x66\x66\x90"  /* 10 */
+       "\x66\x66\x90",
+       "\x66\x66\x66\x90\x66\x66\x66"  /* 11 */
+       "\x90\x66\x66\x90",
+       "\x66\x66\x66\x90\x66\x66\x66"  /* 12 */
+       "\x90\x66\x66\x66\x90",
+       "\x66\x66\x66\x90\x66\x66\x90"  /* 13 */
+       "\x66\x66\x90\x66\x66\x90",
+       "\x66\x66\x66\x90\x66\x66\x66"  /* 14 */
+       "\x90\x66\x66\x90\x66\x66\x90",
+       "\x66\x66\x66\x90\x66\x66\x66"  /* 15 */
+       "\x90\x66\x66\x66\x90\x66\x66\x90"
+    };
+    switch (arch_x86->mode_bits) {
+       case 16:
+           return (const unsigned char **)fill16;
+       case 32:
+           return (const unsigned char **)fill32;
+       case 64:
+           return (const unsigned char **)fill64;
+       default:
+           yasm_internal_error(N_("Invalid mode_bits in x86_get_fill"));
+           /*@notreached@*/
+           return NULL;
+    }
+}
+
 unsigned int
 yasm_x86__get_reg_size(yasm_arch *arch, unsigned long reg)
 {
@@ -269,6 +371,7 @@ yasm_arch_module yasm_x86_LTX_arch = {
     yasm_x86__parse_check_prefix,
     yasm_x86__parse_check_targetmod,
     x86_parse_directive,
+    x86_get_fill,
     yasm_x86__finalize_insn,
     yasm_x86__floatnum_tobytes,
     yasm_x86__intnum_fixup_rel,
index b608f36942b409c13ea35135df6134bf64a96ade..0148090f2f9f23ce5ca7467f193d1e1b7d6a5a6e 100644 (file)
@@ -48,6 +48,9 @@ static yasm_section *gas_get_section(yasm_parser_gas *parser_gas, char *name,
                                     /*@null@*/ char *type);
 static void gas_switch_section(yasm_parser_gas *parser_gas, char *name,
                               /*@null@*/ char *flags, /*@null@*/ char *type);
+static yasm_bytecode *gas_parser_align(yasm_parser_gas *parser_gas,
+                                      yasm_valparamhead *valparams,
+                                      int power2);
 static yasm_bytecode *gas_define_strings(yasm_parser_gas *parser_gas,
                                         yasm_valparamhead *vps, int withzero);
 static yasm_bytecode *gas_define_data(yasm_parser_gas *parser_gas,
@@ -102,7 +105,7 @@ static void gas_parser_directive
 %token DIR_EQU DIR_FILE DIR_FLOAT DIR_GLOBAL DIR_IDENT DIR_INT DIR_LOC
 %token DIR_LCOMM DIR_OCTA DIR_ORG DIR_P2ALIGN DIR_REPT DIR_SECTION
 %token DIR_SHORT DIR_SIZE DIR_SKIP DIR_STRING
-%token DIR_TEXT DIR_TFLOAT DIR_TYPE DIR_QUAD DIR_WORD
+%token DIR_TEXT DIR_TFLOAT DIR_TYPE DIR_QUAD DIR_WORD DIR_ZERO
 
 %type <bc> line lineexp instr
 
@@ -155,26 +158,20 @@ lineexp: instr
     }
     /* Alignment directives */
     | DIR_ALIGN datavals2 {
-       /* FIXME: Whether this is power-of-two or not depends on arch */
-       /*@dependent@*/ yasm_valparam *bound, *fill = NULL, *maxskip = NULL;
-       bound = yasm_vps_first(&$2);
-       if (bound)
-           fill = yasm_vps_next(bound);
-       else
-           yasm__error(cur_line,
-                       N_("align directive must specify alignment"));
-       if (fill)
-           maxskip = yasm_vps_next(fill);
-       $$ = (yasm_bytecode *)NULL;
+       /* FIXME: Whether this is power-of-two or not depends on arch and
+        * objfmt.
+        */
+       $$ = gas_parser_align(parser_gas, &$2, 0);
     }
     | DIR_P2ALIGN datavals2 {
-       $$ = (yasm_bytecode *)NULL;
+       $$ = gas_parser_align(parser_gas, &$2, 1);
     }
     | DIR_BALIGN datavals2 {
-       $$ = (yasm_bytecode *)NULL;
+       $$ = gas_parser_align(parser_gas, &$2, 0);
     }
-    | DIR_ORG expr {
-       $$ = (yasm_bytecode *)NULL;
+    | DIR_ORG INTNUM {
+       /* TODO: support expr instead of intnum */
+       $$ = yasm_bc_create_org(yasm_intnum_get_uint($2), cur_line);
     }
     /* Data visibility directives */
     | DIR_GLOBAL label_id {
@@ -274,6 +271,16 @@ lineexp: instr
        $$ = gas_define_data(parser_gas, &$2, 16);
        yasm_vps_delete(&$2);
     }
+    | DIR_ZERO expr {
+       yasm_datavalhead dvs;
+
+       yasm_dvs_initialize(&dvs);
+       yasm_dvs_append(&dvs, yasm_dv_create_expr(
+           p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0)))));
+       $$ = yasm_bc_create_data(&dvs, 1, cur_line);
+
+       yasm_bc_set_multiple($$, $2);
+    }
     /* Floating point data definition directives */
     | DIR_FLOAT datavals {
        $$ = gas_define_data(parser_gas, &$2, 4);
@@ -351,6 +358,10 @@ lineexp: instr
        /* TODO */
        $$ = NULL;
     }
+    | DIR_FILE STRING {
+       /* TODO */
+       $$ = NULL;
+    }
     | DIR_LOC INTNUM INTNUM INTNUM {
        /* TODO */
        $$ = NULL;
@@ -671,6 +682,49 @@ gas_switch_section(yasm_parser_gas *parser_gas, char *name,
        parser_gas->prev_bc = yasm_section_bcs_last(new_section);
     } else
        yasm__error(cur_line, N_("invalid section name `%s'"), name);
+    parser_gas->code_section = !strcmp(name, ".text");
+}
+
+static yasm_bytecode *
+gas_parser_align(yasm_parser_gas *parser_gas, yasm_valparamhead *valparams,
+                int power2)
+{
+    /*@dependent@*/ yasm_valparam *bound, *fill = NULL, *maxskip = NULL;
+    yasm_expr *boundval, *fillval = NULL, *maxskipval = NULL;
+
+    bound = yasm_vps_first(valparams);
+    boundval = bound->param;
+    bound->param = NULL;
+    if (bound && boundval) {
+       fill = yasm_vps_next(bound);
+    } else {
+       yasm__error(cur_line, N_("align directive must specify alignment"));
+       return NULL;
+    }
+
+    if (fill) {
+       fillval = fill->param;
+       fill->param = NULL;
+       maxskip = yasm_vps_next(fill);
+    }
+
+    if (maxskip) {
+       maxskipval = maxskip->param;
+       maxskip->param = NULL;
+    }
+
+    yasm_vps_delete(valparams);
+
+    /* Convert power of two to number of bytes if necessary */
+    if (power2)
+       boundval = yasm_expr_create(YASM_EXPR_SHL,
+                                   yasm_expr_int(yasm_intnum_create_uint(1)),
+                                   yasm_expr_expr(boundval), cur_line);
+
+    return yasm_bc_create_align(boundval, fillval, maxskipval,
+                               parser_gas->code_section ?
+                                   yasm_arch_get_fill(parser_gas->arch) : NULL,
+                               cur_line);
 }
 
 static yasm_bytecode *
index 31bf78a706ba6497a1170891c635d8a5003608d7..8b98fa93b2657113209fc9d35ac0a76dd448edf3 100644 (file)
@@ -77,6 +77,8 @@ gas_parser_do_parse(yasm_object *object, yasm_preproc *pp, yasm_arch *a,
 
     parser_gas.state = INITIAL;
 
+    parser_gas.code_section = !strcmp(yasm_section_get_name(def_sect), ".text");
+
     /* yacc debugging, needs YYDEBUG set in bison.y.in to work */
     parser_gas.debug = 1;
 
index 50137960b700ac34250c3e3f0f89e9ba341c34ea..acdbe3ef96ba0aa181bd198b89add6b2600c7b6f 100644 (file)
@@ -70,6 +70,8 @@ typedef struct yasm_parser_gas {
        INITIAL,
        SECTION_DIRECTIVE
     } state;
+
+    int code_section;
 } yasm_parser_gas;
 
 /* shorter access names to commonly used parser_gas fields */
index 1d775e3516af3e835a4c679eeb4bcf28f27bcad5..18c5134af89bb2fcfacae3522cd093a5cea8a56b 100644 (file)
@@ -324,6 +324,7 @@ scan:
        ".type"         { RETURN(DIR_TYPE); }
        ".quad"         { RETURN(DIR_QUAD); }
        ".word"         { RETURN(DIR_WORD); }
+       ".zero"         { RETURN(DIR_ZERO); }
 
        /* label or maybe directive */
        [.][a-zA-Z0-9_$.]* {