]> granicus.if.org Git - yasm/commitdiff
Implement GAS syntax ".local" directive. This is used by GCC to generate
authorPeter Johnson <peter@tortall.net>
Mon, 23 Jan 2006 00:16:38 +0000 (00:16 -0000)
committerPeter Johnson <peter@tortall.net>
Mon, 23 Jan 2006 00:16:38 +0000 (00:16 -0000)
.local sym; .comm sym; rather than directly using .lcomm sym.  Handle this
usage as well.  While we're here, also implement alignment for .lcomm and
refactor .lcomm handling and alignment handling.

* gas-token.re: Recognize .local.
* gas-bison.y (DIR_LOCAL): Implement .local.
(DIR_COMM): Recognize .local ; .comm case and call define_lcomm().
(DIR_LCOMM): Move functionality into..
(define_lcomm): Here, and implement alignment with..
(gas_parser_align): That now takes raw exprs.  The valparam part of that is
now implemented in..
(gas_parser_dir_align): Formerly gas_parser_align.
(DIR_ALIGN): Use gas_parser_dir_align() instead.

* symrec.c (yasm_symtab_get): New function to just get a symbol based on name
without actually "referencing" it.
* symrec.h (yasm_symtab_get): Prototype.

* coretype.h (yasm_sym_vis): Add YASM_SYM_DLOCAL for flagging that a symbol
is explicitly flagged as a local symbol (rather than just default that way).

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

libyasm/coretype.h
libyasm/symrec.c
libyasm/symrec.h
modules/parsers/gas/gas-bison.y
modules/parsers/gas/gas-token.re
modules/parsers/gas/tests/Makefile.inc
modules/parsers/gas/tests/localcomm.asm [new file with mode: 0644]
modules/parsers/gas/tests/localcomm.errwarn [new file with mode: 0644]
modules/parsers/gas/tests/localcomm.hex [new file with mode: 0644]

index 80580b5aebcc2696f6d5fbd403e0ff01ff64c636..0ece06cc9d6a2e46091dbc46816ebcba1f9e2737 100644 (file)
@@ -158,7 +158,8 @@ typedef enum {
     YASM_SYM_LOCAL = 0,                /**< Default, local only */
     YASM_SYM_GLOBAL = 1 << 0,  /**< If symbol is declared GLOBAL */
     YASM_SYM_COMMON = 1 << 1,  /**< If symbol is declared COMMON */
-    YASM_SYM_EXTERN = 1 << 2   /**< If symbol is declared EXTERN */
+    YASM_SYM_EXTERN = 1 << 2,  /**< If symbol is declared EXTERN */
+    YASM_SYM_DLOCAL = 1 << 3   /**< If symbol is explicitly declared LOCAL */
 } yasm_sym_vis;
 
 /** Determine the distance between the starting offsets of two bytecodes.
index 43e43aff8191a8e450565d16f9f896dd99eeb928..b2b94bb1a0c1a318889fdde975a830d1549b53fd 100644 (file)
@@ -185,6 +185,12 @@ yasm_symtab_use(yasm_symtab *symtab, const char *name, unsigned long line)
     return rec;
 }
 
+yasm_symrec *
+yasm_symtab_get(yasm_symtab *symtab, const char *name)
+{
+    return HAMT_search(symtab->sym_table, name);
+}
+
 static /*@dependent@*/ yasm_symrec *
 symtab_define(yasm_symtab *symtab, const char *name, sym_type type,
              int in_table, unsigned long line)
index 4d4a879d08b8ec6174e220cb7a38c8afcd3b2cc5..ae38fb05f8fbfb92c17cc993b0470b3f18f36665 100644 (file)
@@ -54,6 +54,18 @@ void yasm_symtab_destroy(/*@only@*/ yasm_symtab *symtab);
 /*@dependent@*/ yasm_symrec *yasm_symtab_use
     (yasm_symtab *symtab, const char *name, unsigned long line);
 
+/** Get a reference to a symbol, without "using" it.  Should be used for cases
+ * when an internal assembler usage of a symbol shouldn't be treated like a
+ * normal user symbol usage.
+ * \param symtab    symbol table
+ * \param name     symbol name
+ * \param line      virtual line where referenced
+ * \return Symbol (dependent pointer, do not free).  May be NULL if symbol
+ *         doesn't exist.
+ */
+/*@null@*/ /*@dependent@*/ yasm_symrec *yasm_symtab_get
+    (yasm_symtab *symtab, const char *name);
+
 /** Define a symbol as an EQU value.
  * \param symtab    symbol table
  * \param name     symbol (EQU) name
index 2a9d8b3ba97205b41cd37ca17f18e603ebe2d72d..2b745d29f37482c70bc621fe2d65383a18d42a97 100644 (file)
@@ -43,6 +43,8 @@ RCSID("$Id$");
 #include "modules/parsers/gas/gas-defs.h"
 
 static void define_label(yasm_parser_gas *parser_gas, char *name, int local);
+static void define_lcomm(yasm_parser_gas *parser_gas, /*@only@*/ char *name,
+                        yasm_expr *size, /*@null@*/ yasm_expr *align);
 static yasm_section *gas_get_section
     (yasm_parser_gas *parser_gas, char *name, /*@null@*/ char *flags,
      /*@null@*/ char *type, /*@null@*/ yasm_valparamhead *objext_valparams,
@@ -51,9 +53,13 @@ static void gas_switch_section(yasm_parser_gas *parser_gas, char *name,
                               /*@null@*/ char *flags, /*@null@*/ char *type,
                               /*@null@*/ yasm_valparamhead *objext_valparams,
                               int builtin);
-static yasm_bytecode *gas_parser_align(yasm_parser_gas *parser_gas,
-                                      yasm_valparamhead *valparams,
-                                      int power2);
+static yasm_bytecode *gas_parser_align
+    (yasm_parser_gas *parser_gas, yasm_section *sect, yasm_expr *boundval,
+     /*@null@*/ yasm_expr *fillval, /*@null@*/ yasm_expr *maxskipval,
+     int power2);
+static yasm_bytecode *gas_parser_dir_align(yasm_parser_gas *parser_gas,
+                                          yasm_valparamhead *valparams,
+                                          int power2);
 static void gas_parser_directive
     (yasm_parser_gas *parser_gas, const char *name,
      yasm_valparamhead *valparams,
@@ -107,8 +113,8 @@ static void gas_parser_directive
 %token DIR_2BYTE DIR_4BYTE DIR_ALIGN DIR_ASCII DIR_ASCIZ DIR_BALIGN
 %token DIR_BSS DIR_BYTE DIR_COMM DIR_DATA DIR_DOUBLE DIR_ENDR DIR_EXTERN
 %token DIR_EQU DIR_FILE DIR_FLOAT DIR_GLOBAL DIR_IDENT DIR_INT DIR_LINE
-%token DIR_LOC DIR_LCOMM DIR_OCTA DIR_ORG DIR_P2ALIGN DIR_REPT DIR_SECTION
-%token DIR_SHORT DIR_SIZE DIR_SKIP DIR_SLEB128 DIR_STRING DIR_TEXT
+%token DIR_LOC DIR_LOCAL DIR_LCOMM DIR_OCTA DIR_ORG DIR_P2ALIGN DIR_REPT
+%token DIR_SECTION DIR_SHORT DIR_SIZE DIR_SKIP DIR_SLEB128 DIR_STRING DIR_TEXT
 %token DIR_TFLOAT DIR_TYPE DIR_QUAD DIR_ULEB128 DIR_VALUE DIR_WEAK DIR_WORD
 %token DIR_ZERO
 
@@ -220,42 +226,63 @@ lineexp: instr
        /* FIXME: Whether this is power-of-two or not depends on arch and
         * objfmt.
         */
-       $$ = gas_parser_align(parser_gas, &$2, 0);
+       $$ = gas_parser_dir_align(parser_gas, &$2, 0);
     }
     | DIR_P2ALIGN dirvals2 {
-       $$ = gas_parser_align(parser_gas, &$2, 1);
+       $$ = gas_parser_dir_align(parser_gas, &$2, 1);
     }
     | DIR_BALIGN dirvals2 {
-       $$ = gas_parser_align(parser_gas, &$2, 0);
+       $$ = gas_parser_dir_align(parser_gas, &$2, 0);
     }
     | DIR_ORG INTNUM {
        /* TODO: support expr instead of intnum */
        $$ = yasm_bc_create_org(yasm_intnum_get_uint($2), cur_line);
     }
     /* Data visibility directives */
+    | DIR_LOCAL label_id {
+       yasm_symtab_declare(parser_gas->symtab, $2, YASM_SYM_DLOCAL, cur_line);
+       yasm_xfree($2);
+       $$ = NULL;
+    }
     | DIR_GLOBAL label_id {
        yasm_objfmt_global_declare(parser_gas->objfmt, $2, NULL, cur_line);
        yasm_xfree($2);
        $$ = NULL;
     }
     | DIR_COMM label_id ',' expr {
-       yasm_objfmt_common_declare(parser_gas->objfmt, $2, $4, NULL, cur_line);
-       yasm_xfree($2);
+       /* If already explicitly declared local, treat like LCOMM */
+       /*@null@*/ /*@dependent@*/ yasm_symrec *sym =
+           yasm_symtab_get(parser_gas->symtab, $2);
+       if (sym && yasm_symrec_get_visibility(sym) == YASM_SYM_DLOCAL) {
+           define_lcomm(parser_gas, $2, $4, NULL);
+       } else {
+           yasm_objfmt_common_declare(parser_gas->objfmt, $2, $4, NULL,
+                                      cur_line);
+           yasm_xfree($2);
+       }
        $$ = NULL;
     }
     | DIR_COMM label_id ',' expr ',' expr {
-       /* Give third parameter as objext valparam for use as alignment */
-       yasm_valparamhead vps;
-       yasm_valparam *vp;
+       /* If already explicitly declared local, treat like LCOMM */
+       /*@null@*/ /*@dependent@*/ yasm_symrec *sym =
+           yasm_symtab_get(parser_gas->symtab, $2);
+       if (sym && yasm_symrec_get_visibility(sym)) {
+           define_lcomm(parser_gas, $2, $4, $6);
+       } else {
+           /* Give third parameter as objext valparam for use as alignment */
+           yasm_valparamhead vps;
+           yasm_valparam *vp;
 
-       yasm_vps_initialize(&vps);
-       vp = yasm_vp_create(NULL, $6);
-       yasm_vps_append(&vps, vp);
+           yasm_vps_initialize(&vps);
+           vp = yasm_vp_create(NULL, $6);
+           yasm_vps_append(&vps, vp);
 
-       yasm_objfmt_common_declare(parser_gas->objfmt, $2, $4, &vps, cur_line);
+           yasm_objfmt_common_declare(parser_gas->objfmt, $2, $4, &vps,
+                                      cur_line);
 
-       yasm_vps_delete(&vps);
-       yasm_xfree($2);
+           yasm_vps_delete(&vps);
+           yasm_xfree($2);
+       }
        $$ = NULL;
     }
     | DIR_EXTERN label_id {
@@ -279,27 +306,11 @@ lineexp: instr
        $$ = NULL;
     }
     | DIR_LCOMM label_id ',' expr {
-       /* Put into .bss section. */
-       /*@dependent@*/ yasm_section *bss =
-           gas_get_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL,
-                           NULL, 1);
-       /* TODO: default alignment */
-       yasm_symtab_define_label(p_symtab, $2, yasm_section_bcs_last(bss), 1,
-                                cur_line);
-       yasm_section_bcs_append(bss, yasm_bc_create_reserve($4, 1, cur_line));
-       yasm_xfree($2);
+       define_lcomm(parser_gas, $2, $4, NULL);
        $$ = NULL;
     }
     | DIR_LCOMM label_id ',' expr ',' expr {
-       /* Put into .bss section. */
-       /*@dependent@*/ yasm_section *bss =
-           gas_get_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL,
-                           NULL, 1);
-       /* TODO: force alignment */
-       yasm_symtab_define_label(p_symtab, $2, yasm_section_bcs_last(bss), 1,
-                                cur_line);
-       yasm_section_bcs_append(bss, yasm_bc_create_reserve($4, 1, cur_line));
-       yasm_xfree($2);
+       define_lcomm(parser_gas, $2, $4, $6);
        $$ = NULL;
     }
     /* Integer data definition directives */
@@ -441,6 +452,10 @@ lineexp: instr
        /* TODO */
        $$ = NULL;
     }
+    | DIR_LOC INTNUM INTNUM {
+       /* TODO */
+       $$ = NULL;
+    }
     | DIR_LOC INTNUM INTNUM INTNUM {
        /* TODO */
        $$ = NULL;
@@ -750,6 +765,26 @@ define_label(yasm_parser_gas *parser_gas, char *name, int local)
     yasm_xfree(name);
 }
 
+static void
+define_lcomm(yasm_parser_gas *parser_gas, /*@only@*/ char *name,
+            yasm_expr *size, /*@null@*/ yasm_expr *align)
+{
+    /* Put into .bss section. */
+    /*@dependent@*/ yasm_section *bss =
+       gas_get_section(parser_gas, yasm__xstrdup(".bss"), NULL, NULL, NULL, 1);
+
+    if (align) {
+       /* XXX: assume alignment is in bytes, not power-of-two */
+       yasm_section_bcs_append(bss, gas_parser_align(parser_gas, bss, align,
+                               NULL, NULL, 0));
+    }
+
+    yasm_symtab_define_label(p_symtab, name, yasm_section_bcs_last(bss), 1,
+                            cur_line);
+    yasm_section_bcs_append(bss, yasm_bc_create_reserve(size, 1, cur_line));
+    yasm_xfree(name);
+}
+
 static yasm_section *
 gas_get_section(yasm_parser_gas *parser_gas, char *name,
                /*@null@*/ char *flags, /*@null@*/ char *type,
@@ -805,12 +840,42 @@ gas_switch_section(yasm_parser_gas *parser_gas, char *name,
 }
 
 static yasm_bytecode *
-gas_parser_align(yasm_parser_gas *parser_gas, yasm_valparamhead *valparams,
-                int power2)
+gas_parser_align(yasm_parser_gas *parser_gas, yasm_section *sect,
+                yasm_expr *boundval, /*@null@*/ yasm_expr *fillval,
+                /*@null@*/ yasm_expr *maxskipval, int power2)
+{
+    yasm_intnum *boundintn;
+
+    /* 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);
+
+    /* Largest .align in the section specifies section alignment. */
+    boundintn = yasm_expr_get_intnum(&boundval, NULL);
+    if (boundintn) {
+       unsigned long boundint = yasm_intnum_get_uint(boundintn);
+
+       /* Alignments must be a power of two. */
+       if ((boundint & (boundint - 1)) == 0) {
+           if (boundint > yasm_section_get_align(sect))
+               yasm_section_set_align(sect, boundint, cur_line);
+       }
+    }
+
+    return yasm_bc_create_align(boundval, fillval, maxskipval,
+                               yasm_section_is_code(sect) ?
+                                   yasm_arch_get_fill(parser_gas->arch) : NULL,
+                               cur_line);
+}
+
+static yasm_bytecode *
+gas_parser_dir_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;
-    yasm_intnum *boundintn;
 
     bound = yasm_vps_first(valparams);
     boundval = bound->param;
@@ -835,31 +900,8 @@ gas_parser_align(yasm_parser_gas *parser_gas, yasm_valparamhead *valparams,
 
     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);
-
-    /* If .align is the first bytecode in the section, it's really specifying
-     * section alignment.
-     */
-    boundintn = yasm_expr_get_intnum(&boundval, NULL);
-    if (boundintn) {
-       unsigned long boundint = yasm_intnum_get_uint(boundintn);
-
-       /* Alignments must be a power of two. */
-       if ((boundint & (boundint - 1)) == 0) {
-           if (boundint > yasm_section_get_align(parser_gas->cur_section))
-               yasm_section_set_align(parser_gas->cur_section, boundint,
-                                      cur_line);
-       }
-    }
-
-    return yasm_bc_create_align(boundval, fillval, maxskipval,
-                               yasm_section_is_code(parser_gas->cur_section) ?
-                                   yasm_arch_get_fill(parser_gas->arch) : NULL,
-                               cur_line);
+    return gas_parser_align(parser_gas, parser_gas->cur_section, boundval,
+                           fillval, maxskipval, power2);
 }
 
 static void
index 67bcb6bff6485026ca4e160343607fc5812e6cd0..f6e97bca6a870a57db74ee2721e591d6d80ec402 100644 (file)
@@ -366,6 +366,7 @@ scan:
        '.lcomm'        { parser_gas->state = INSTDIR; RETURN(DIR_LCOMM); }
        '.line'         { parser_gas->state = INSTDIR; RETURN(DIR_LINE); }
        '.loc'          { parser_gas->state = INSTDIR; RETURN(DIR_LOC); }
+       '.local'        { parser_gas->state = INSTDIR; RETURN(DIR_LOCAL); }
        '.long'         { parser_gas->state = INSTDIR; RETURN(DIR_INT); }
        '.octa'         { parser_gas->state = INSTDIR; RETURN(DIR_OCTA); }
        '.org'          { parser_gas->state = INSTDIR; RETURN(DIR_ORG); }
index b463f8f1bba7b421b445a816322248ae450bb07f..a55f97af3d6b98498b0c42bc32732e97ccd585b5 100644 (file)
@@ -30,6 +30,9 @@ EXTRA_DIST += modules/parsers/gas/tests/jmpcall.hex
 EXTRA_DIST += modules/parsers/gas/tests/leb128.asm
 EXTRA_DIST += modules/parsers/gas/tests/leb128.errwarn
 EXTRA_DIST += modules/parsers/gas/tests/leb128.hex
+EXTRA_DIST += modules/parsers/gas/tests/localcomm.asm
+EXTRA_DIST += modules/parsers/gas/tests/localcomm.errwarn
+EXTRA_DIST += modules/parsers/gas/tests/localcomm.hex
 EXTRA_DIST += modules/parsers/gas/tests/reggroup-err.asm
 EXTRA_DIST += modules/parsers/gas/tests/reggroup-err.errwarn
 EXTRA_DIST += modules/parsers/gas/tests/reggroup.asm
diff --git a/modules/parsers/gas/tests/localcomm.asm b/modules/parsers/gas/tests/localcomm.asm
new file mode 100644 (file)
index 0000000..17f33e6
--- /dev/null
@@ -0,0 +1,18 @@
+       .text
+       .local  failmsg
+       .comm   failmsg,100,32
+       .local  failed
+       .comm   failed,1000,32
+       .local  from_dec_data
+       .comm   from_dec_data,8,8
+       .local  op2static
+       .comm   op2static,8,8
+       .local  op1static
+       .comm   op1static,8,8
+       .local  spare
+       .comm   spare,8,8
+       .local  result
+       .comm   result,8,8
+       .local  conv_bv
+       .comm   conv_bv,8,8
+
diff --git a/modules/parsers/gas/tests/localcomm.errwarn b/modules/parsers/gas/tests/localcomm.errwarn
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/modules/parsers/gas/tests/localcomm.hex b/modules/parsers/gas/tests/localcomm.hex
new file mode 100644 (file)
index 0000000..93540be
--- /dev/null
@@ -0,0 +1,544 @@
+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 
+30 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+34 
+00 
+00 
+00 
+00 
+00 
+28 
+00 
+06 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+62 
+73 
+73 
+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 
+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 
+90 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+05 
+00 
+00 
+00 
+00 
+00 
+88 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+05 
+00 
+00 
+00 
+00 
+00 
+80 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+05 
+00 
+00 
+00 
+00 
+00 
+78 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+05 
+00 
+00 
+00 
+00 
+00 
+70 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+05 
+00 
+00 
+00 
+00 
+00 
+68 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+05 
+00 
+00 
+00 
+00 
+00 
+80 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+05 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+05 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+05 
+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 
+1c 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+26 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+0c 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+68 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+14 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+6c 
+00 
+00 
+00 
+c0 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+0c 
+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 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+08 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+98 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+20 
+00 
+00 
+00 
+00 
+00 
+00 
+00