From: Peter Johnson Date: Sat, 11 Mar 2006 01:47:41 +0000 (-0000) Subject: * gas-token.re: Recognize ".fill" directive. X-Git-Tag: v0.5.0rc2~5^2~27 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e71919051390f0a81c2fc30a6a0f616f549887ac;p=yasm * gas-token.re: Recognize ".fill" directive. * gas-bison.y: Implement ".fill" directive. * gas-fill.asm: New test for .fill directive. svn path=/trunk/yasm/; revision=1415 --- diff --git a/modules/parsers/gas/gas-bison.y b/modules/parsers/gas/gas-bison.y index b0a61d3a..0dcc515d 100644 --- a/modules/parsers/gas/gas-bison.y +++ b/modules/parsers/gas/gas-bison.y @@ -60,6 +60,10 @@ static yasm_bytecode *gas_parser_align static yasm_bytecode *gas_parser_dir_align(yasm_parser_gas *parser_gas, yasm_valparamhead *valparams, int power2); +static yasm_bytecode *gas_parser_dir_fill + (yasm_parser_gas *parser_gas, /*@only@*/ yasm_expr *repeat, + /*@only@*/ /*@null@*/ yasm_expr *size, + /*@only@*/ /*@null@*/ yasm_expr *value); static void gas_parser_directive (yasm_parser_gas *parser_gas, const char *name, yasm_valparamhead *valparams, @@ -112,11 +116,11 @@ static void gas_parser_directive %token LINE %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_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 +%token DIR_EQU DIR_FILE DIR_FILL DIR_FLOAT DIR_GLOBAL DIR_IDENT DIR_INT +%token DIR_LINE DIR_LOC DIR_LOCAL DIR_LCOMM DIR_OCTA DIR_ORG DIR_P2ALIGN +%token DIR_REPT DIR_SECTION DIR_SHORT DIR_SIZE DIR_SKIP DIR_SLEB128 DIR_STRING +%token DIR_TEXT DIR_TFLOAT DIR_TYPE DIR_QUAD DIR_ULEB128 DIR_VALUE DIR_WEAK +%token DIR_WORD DIR_ZERO %type lineexp instr @@ -390,6 +394,16 @@ lineexp: instr yasm_bc_set_multiple($$, $2); } + /* fill data definition directive */ + | DIR_FILL expr { + $$ = gas_parser_dir_fill(parser_gas, $2, NULL, NULL); + } + | DIR_FILL expr ',' expr { + $$ = gas_parser_dir_fill(parser_gas, $2, $4, NULL); + } + | DIR_FILL expr ',' expr ',' expr { + $$ = gas_parser_dir_fill(parser_gas, $2, $4, $6); + } /* Section directives */ | DIR_TEXT { gas_switch_section(parser_gas, yasm__xstrdup(".text"), NULL, NULL, @@ -960,6 +974,43 @@ gas_parser_dir_align(yasm_parser_gas *parser_gas, yasm_valparamhead *valparams, fillval, maxskipval, power2); } +static yasm_bytecode * +gas_parser_dir_fill(yasm_parser_gas *parser_gas, /*@only@*/ yasm_expr *repeat, + /*@only@*/ /*@null@*/ yasm_expr *size, + /*@only@*/ /*@null@*/ yasm_expr *value) +{ + yasm_datavalhead dvs; + yasm_bytecode *bc; + unsigned int ssize; + + if (size) { + /*@dependent@*/ /*@null@*/ yasm_intnum *intn; + intn = yasm_expr_get_intnum(&size, NULL); + if (!intn) { + yasm__error(cur_line, N_("size must be an absolute expression")); + yasm_expr_destroy(repeat); + yasm_expr_destroy(size); + if (value) + yasm_expr_destroy(value); + return NULL; + } + ssize = yasm_intnum_get_uint(intn); + } else + ssize = 1; + + if (!value) + value = yasm_expr_create_ident( + yasm_expr_int(yasm_intnum_create_uint(0)), cur_line); + + yasm_dvs_initialize(&dvs); + yasm_dvs_append(&dvs, yasm_dv_create_expr(value)); + bc = yasm_bc_create_data(&dvs, ssize, 0, cur_line); + + yasm_bc_set_multiple(bc, repeat); + + return bc; +} + static void gas_parser_directive(yasm_parser_gas *parser_gas, const char *name, yasm_valparamhead *valparams, diff --git a/modules/parsers/gas/gas-token.re b/modules/parsers/gas/gas-token.re index aa923634..71f95585 100644 --- a/modules/parsers/gas/gas-token.re +++ b/modules/parsers/gas/gas-token.re @@ -357,6 +357,7 @@ scan: '.equ' { parser_gas->state = INSTDIR; RETURN(DIR_EQU); } '.extern' { parser_gas->state = INSTDIR; RETURN(DIR_EXTERN); } '.file' { parser_gas->state = INSTDIR; RETURN(DIR_FILE); } + '.fill' { parser_gas->state = INSTDIR; RETURN(DIR_FILL); } '.float' { parser_gas->state = INSTDIR; RETURN(DIR_FLOAT); } '.global' { parser_gas->state = INSTDIR; RETURN(DIR_GLOBAL); } '.globl' { parser_gas->state = INSTDIR; RETURN(DIR_GLOBAL); } diff --git a/modules/parsers/gas/tests/Makefile.inc b/modules/parsers/gas/tests/Makefile.inc index a55f97af..f8125770 100644 --- a/modules/parsers/gas/tests/Makefile.inc +++ b/modules/parsers/gas/tests/Makefile.inc @@ -15,6 +15,9 @@ EXTRA_DIST += modules/parsers/gas/tests/datavis2.hex EXTRA_DIST += modules/parsers/gas/tests/execsect.asm EXTRA_DIST += modules/parsers/gas/tests/execsect.errwarn EXTRA_DIST += modules/parsers/gas/tests/execsect.hex +EXTRA_DIST += modules/parsers/gas/tests/gas-fill.asm +EXTRA_DIST += modules/parsers/gas/tests/gas-fill.errwarn +EXTRA_DIST += modules/parsers/gas/tests/gas-fill.hex EXTRA_DIST += modules/parsers/gas/tests/gas-instlabel.asm EXTRA_DIST += modules/parsers/gas/tests/gas-instlabel.errwarn EXTRA_DIST += modules/parsers/gas/tests/gas-instlabel.hex diff --git a/modules/parsers/gas/tests/gas-fill.asm b/modules/parsers/gas/tests/gas-fill.asm new file mode 100644 index 00000000..09c601d7 --- /dev/null +++ b/modules/parsers/gas/tests/gas-fill.asm @@ -0,0 +1,6 @@ +.text +.fill 5 +.fill 3, 1 +.fill 4, 2 +.fill 4, 8, 0x11223344 +.fill 4, 4, 0x11223344 diff --git a/modules/parsers/gas/tests/gas-fill.errwarn b/modules/parsers/gas/tests/gas-fill.errwarn new file mode 100644 index 00000000..e69de29b diff --git a/modules/parsers/gas/tests/gas-fill.hex b/modules/parsers/gas/tests/gas-fill.hex new file mode 100644 index 00000000..71654672 --- /dev/null +++ b/modules/parsers/gas/tests/gas-fill.hex @@ -0,0 +1,424 @@ +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 +e0 +00 +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 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +44 +33 +22 +11 +00 +00 +00 +00 +44 +33 +22 +11 +00 +00 +00 +00 +44 +33 +22 +11 +00 +00 +00 +00 +44 +33 +22 +11 +00 +00 +00 +00 +44 +33 +22 +11 +44 +33 +22 +11 +44 +33 +22 +11 +44 +33 +22 +11 +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 +17 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +80 +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 +a4 +00 +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 +a8 +00 +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 +40 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +00 +00 +00 +00 +00 +00 +00