diff options
-rw-r--r-- | gcc/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/c-parse.in | 112 | ||||
-rw-r--r-- | gcc/c-tree.h | 4 | ||||
-rw-r--r-- | gcc/c-typeck.c | 65 |
4 files changed, 110 insertions, 90 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3c3b8605748..346d86f1d86 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2004-02-12 Zack Weinberg <zack@codesourcery.com> + + * c-parse.in (maybe_type_qual): Delete. + (maybe_volatile, simple_asm_expr, asmdef, asm_stmt) + (asm_argument): New grammar rules. + (extdef_1): Use asmdef. + (maybeasm): Move down with other asm rules; use simple_asm_expr. + (xexpr): Move up with other expression rules. + (stmt): Use asm_stmt. + + * c-typeck.c (build_asm_expr): New function - body mostly + pulled from build_asm_stmt. + (build_asm_stmt): Just handle tacking on the volatile qualifier. + * c-tree.h (build_asm_expr, build_asm_stmt): Update prototypes. + 2004-02-12 Richard Sandiford <rsandifo@redhat.com> PR bootstrap/13617 @@ -197,7 +212,7 @@ 2004-02-10 Matt Kraai <kraai@alumni.cmu.edu> - * doc/install.texi: Remove extra cd. + * doc/install.texi: Remove extra cd. 2004-02-10 Ziemowit Laski <zlaski@apple.com> @@ -383,7 +398,7 @@ * config/m68k/linux.h, config/m68k/m68k.c: Remove traling whitespace. 2004-02-08 Andreas Schwab <schwab@suse.de> - Bernardo Innocenti <bernie@develer.com> + Bernardo Innocenti <bernie@develer.com> * config/m68k/m68k.h (REGISTER_NAMES): Prefix each name with REGISTER_PREFIX. diff --git a/gcc/c-parse.in b/gcc/c-parse.in index 6645dea896d..7a68dbf077f 100644 --- a/gcc/c-parse.in +++ b/gcc/c-parse.in @@ -200,9 +200,9 @@ do { \ %type <ttype> typespec_reserved_nonattr typespec_reserved_attr %type <ttype> typespec_nonreserved_nonattr -%type <ttype> scspec SCSPEC STATIC TYPESPEC TYPE_QUAL maybe_type_qual -%type <ttype> initdecls notype_initdecls initdcl notype_initdcl -%type <ttype> init maybeasm +%type <ttype> scspec SCSPEC STATIC TYPESPEC TYPE_QUAL maybe_volatile +%type <ttype> initdecls notype_initdecls initdcl notype_initdcl init +%type <ttype> simple_asm_expr maybeasm asmdef asm_stmt asm_argument %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers %type <ttype> maybe_attribute attributes attribute attribute_list attrib %type <ttype> any_word @@ -375,19 +375,12 @@ extdef: extdef_1: fndef | datadef + | asmdef + | extension extdef + { RESTORE_EXT_FLAGS ($1); } @@ifobjc | objcdef @@end_ifobjc - | ASM_KEYWORD '(' expr ')' ';' - { STRIP_NOPS ($3); - if ((TREE_CODE ($3) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND ($3, 0)) == STRING_CST) - || TREE_CODE ($3) == STRING_CST) - assemble_asm ($3); - else - error ("argument of `asm' is not a constant string"); } - | extension extdef - { RESTORE_EXT_FLAGS ($1); } ; datadef: @@ -1392,13 +1385,6 @@ notype_initdecls: | notype_initdecls ',' maybe_resetattrs notype_initdcl ; -maybeasm: - /* empty */ - { $$ = NULL_TREE; } - | ASM_KEYWORD '(' STRING ')' - { $$ = $3; } - ; - initdcl: declarator maybeasm maybe_attribute '=' { $<ttype>$ = start_decl ($1, current_declspecs, 1, @@ -2346,6 +2332,12 @@ for_init_stmt: { check_for_loop_decls (); } ; +xexpr: + /* empty */ + { $$ = NULL_TREE; } + | expr + ; + /* Parse a single real statement, not including any labels. */ stmt: compstmt @@ -2381,23 +2373,7 @@ stmt: | RETURN expr ';' { stmt_count++; $$ = c_expand_return ($2); } - | ASM_KEYWORD maybe_type_qual '(' expr ')' ';' - { stmt_count++; - $$ = simple_asm_stmt ($4); } - /* This is the case with just output operands. */ - | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ')' ';' - { stmt_count++; - $$ = build_asm_stmt ($2, $4, $6, NULL_TREE, NULL_TREE); } - /* This is the case with input operands as well. */ - | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':' - asm_operands ')' ';' - { stmt_count++; - $$ = build_asm_stmt ($2, $4, $6, $8, NULL_TREE); } - /* This is the case with clobbered registers as well. */ - | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':' - asm_operands ':' asm_clobbers ')' ';' - { stmt_count++; - $$ = build_asm_stmt ($2, $4, $6, $8, $10); } + | asm_stmt | GOTO identifier ';' { tree decl; stmt_count++; @@ -2499,19 +2475,65 @@ label: CASE expr_no_commas ':' } ; -/* Either a type-qualifier or nothing. First thing in an `asm' statement. */ +/* Asm expressions and statements */ -maybe_type_qual: - /* empty */ +/* simple_asm_expr is used in restricted contexts, where a full + expression with inputs and outputs does not make sense. */ +simple_asm_expr: + ASM_KEYWORD '(' STRING ')' + { $$ = $3; } + ; + +/* maybeasm: used for assembly names for declarations */ +maybeasm: + /* empty */ { $$ = NULL_TREE; } - | TYPE_QUAL - { } + | simple_asm_expr ; -xexpr: +/* asmdef: asm() outside a function body. */ +asmdef: + simple_asm_expr ';' + { assemble_asm ($1); } + ; + +/* Full-blown asm statement with inputs, outputs, clobbers, and + volatile tag allowed. */ +asm_stmt: + ASM_KEYWORD maybe_volatile '(' asm_argument ')' ';' + { stmt_count++; + $$ = build_asm_stmt ($2, $4); } + ; + +asm_argument: + /* no operands */ + STRING + { $$ = build_asm_expr ($1, 0, 0, 0, true); } + /* output operands */ + | STRING ':' asm_operands + { $$ = build_asm_expr ($1, $3, 0, 0, false); } + /* output and input operands */ + | STRING ':' asm_operands ':' asm_operands + { $$ = build_asm_expr ($1, $3, $5, 0, false); } + /* output and input operands and clobbers */ + | STRING ':' asm_operands ':' asm_operands ':' asm_clobbers + { $$ = build_asm_expr ($1, $3, $5, $7, false); } + ; + +/* Either 'volatile' or nothing. First thing in an `asm' statement. */ + +maybe_volatile: /* empty */ - { $$ = NULL_TREE; } - | expr + { $$ = 0; } + | TYPE_QUAL + { if ($1 != ridpointers[RID_VOLATILE]) + { + warning ("%E qualifier ignored on asm", $1); + $$ = 0; + } + else + $$ = $1; + } ; /* These are the operands other than the first string and colon diff --git a/gcc/c-tree.h b/gcc/c-tree.h index e6c7b27857b..1de2e25eab7 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -291,8 +291,8 @@ extern void pedwarn_c90 (const char *, ...) ATTRIBUTE_PRINTF_1; extern void pedwarn_c99 (const char *, ...) ATTRIBUTE_PRINTF_1; extern tree c_start_case (tree); extern void c_finish_case (void); -extern tree simple_asm_stmt (tree); -extern tree build_asm_stmt (tree, tree, tree, tree, tree); +extern tree build_asm_expr (tree, tree, tree, tree, bool); +extern tree build_asm_stmt (tree, tree); extern tree c_convert_parm_for_inlining (tree, tree, tree, int); /* Set to 0 at beginning of a function definition, set to 1 if diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 95a2c3495cd..ff37fea9216 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -6002,52 +6002,28 @@ process_init_element (tree value) constructor_range_stack = 0; } -/* Build a simple asm-statement, from one string literal. */ +/* Build a complete asm-statement, whose components are a CV_QUALIFIER + (guaranteed to be 'volatile' or null) and ARGS (represented using + an ASM_STMT node). */ tree -simple_asm_stmt (tree expr) +build_asm_stmt (tree cv_qualifier, tree args) { - STRIP_NOPS (expr); - - if (TREE_CODE (expr) == ADDR_EXPR) - expr = TREE_OPERAND (expr, 0); - - if (TREE_CODE (expr) == STRING_CST) - { - tree stmt; - - /* Simple asm statements are treated as volatile. */ - stmt = add_stmt (build_stmt (ASM_STMT, ridpointers[(int) RID_VOLATILE], - expr, NULL_TREE, NULL_TREE, NULL_TREE)); - ASM_INPUT_P (stmt) = 1; - return stmt; - } - - error ("argument of `asm' is not a constant string"); - return NULL_TREE; + if (!TREE_OPERAND (args, 0)) + TREE_OPERAND (args, 0) = cv_qualifier; + return add_stmt (args); } -/* Build an asm-statement, whose components are a CV_QUALIFIER, a - STRING, some OUTPUTS, some INPUTS, and some CLOBBERS. */ - +/* Build an asm-expr, whose components are a STRING, some OUTPUTS, + some INPUTS, and some CLOBBERS. The latter three may be NULL. + SIMPLE indicates whether there was anything at all after the + string in the asm expression -- asm("blah") and asm("blah" : ) + are subtly different. We use a ASM_STMT node to represent this. */ tree -build_asm_stmt (tree cv_qualifier, tree string, tree outputs, tree inputs, - tree clobbers) +build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers, + bool simple) { tree tail; - - if (TREE_CODE (string) != STRING_CST) - { - error ("asm template is not a string constant"); - return NULL_TREE; - } - - if (cv_qualifier != NULL_TREE - && cv_qualifier != ridpointers[(int) RID_VOLATILE]) - { - warning ("%s qualifier ignored on asm", - IDENTIFIER_POINTER (cv_qualifier)); - cv_qualifier = NULL_TREE; - } + tree args; /* We can remove output conversions that change the type, but not the mode. */ @@ -6086,8 +6062,15 @@ build_asm_stmt (tree cv_qualifier, tree string, tree outputs, tree inputs, for (tail = inputs; tail; tail = TREE_CHAIN (tail)) TREE_VALUE (tail) = default_function_array_conversion (TREE_VALUE (tail)); - return add_stmt (build_stmt (ASM_STMT, cv_qualifier, string, - outputs, inputs, clobbers)); + args = build_stmt (ASM_STMT, 0, string, outputs, inputs, clobbers); + + /* Simple asm statements are treated as volatile. */ + if (simple) + { + TREE_OPERAND (args, 0) = ridpointers[RID_VOLATILE]; + ASM_INPUT_P (args) = 1; + } + return args; } /* Expand an ASM statement with operands, handling output operands |