static void get_asm_expr_operands (funct_state local, tree stmt) { int noutputs = list_length (ASM_OUTPUTS (stmt)); const char **oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *)); int i; tree link; const char *constraint; bool allows_mem, allows_reg, is_inout; for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link)) { oconstraints[i] = constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); parse_output_constraint (&constraint, i, 0, 0, &allows_mem, &allows_reg, &is_inout); check_lhs_var (local, TREE_VALUE (link)); } for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link)) { constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints, &allows_mem, &allows_reg); check_rhs_var (local, TREE_VALUE (link)); } for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link)) if (simple_cst_equal(TREE_VALUE (link), memory_identifier_string) == 1) /* Abandon all hope, ye who enter here. */ local->pure_const_state = IPA_NEITHER; if (ASM_VOLATILE_P (stmt)) local->pure_const_state = IPA_NEITHER; }
void expand_stmt (tree t) { while (t && t != error_mark_node) { int saved_stmts_are_full_exprs_p; /* Set up context appropriately for handling this statement. */ saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p (); prep_stmt (t); switch (TREE_CODE (t)) { case FILE_STMT: input_filename = FILE_STMT_FILENAME (t); break; case RETURN_STMT: genrtl_return_stmt (t); t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached); goto process_t; case EXPR_STMT: genrtl_expr_stmt_value (EXPR_STMT_EXPR (t), TREE_ADDRESSABLE (t), TREE_CHAIN (t) == NULL || (TREE_CODE (TREE_CHAIN (t)) == SCOPE_STMT && TREE_CHAIN (TREE_CHAIN (t)) == NULL)); break; case DECL_STMT: genrtl_decl_stmt (t); break; case FOR_STMT: genrtl_for_stmt (t); break; case WHILE_STMT: genrtl_while_stmt (t); break; case DO_STMT: genrtl_do_stmt (t); break; case IF_STMT: genrtl_if_stmt (t); break; case COMPOUND_STMT: genrtl_compound_stmt (t); break; case BREAK_STMT: genrtl_break_stmt (); t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached); goto process_t; case CONTINUE_STMT: genrtl_continue_stmt (); t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached); goto process_t; case SWITCH_STMT: genrtl_switch_stmt (t); break; case CASE_LABEL: genrtl_case_label (t); break; case LABEL_STMT: expand_label (LABEL_STMT_LABEL (t)); break; case GOTO_STMT: /* Emit information for branch prediction. */ if (!GOTO_FAKE_P (t) && TREE_CODE (GOTO_DESTINATION (t)) == LABEL_DECL && flag_guess_branch_prob) { rtx note = emit_note (NOTE_INSN_PREDICTION); NOTE_PREDICTION (note) = NOTE_PREDICT (PRED_GOTO, NOT_TAKEN); } genrtl_goto_stmt (GOTO_DESTINATION (t)); t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached); goto process_t; case ASM_STMT: genrtl_asm_stmt (ASM_CV_QUAL (t), ASM_STRING (t), ASM_OUTPUTS (t), ASM_INPUTS (t), ASM_CLOBBERS (t), ASM_INPUT_P (t)); break; case SCOPE_STMT: genrtl_scope_stmt (t); break; case CLEANUP_STMT: genrtl_cleanup_stmt (t); break; default: if (lang_expand_stmt) (*lang_expand_stmt) (t); else abort (); break; } /* Go on to the next statement in this scope. */ t = TREE_CHAIN (t); process_t: /* Restore saved state. */ current_stmt_tree ()->stmts_are_full_exprs_p = saved_stmts_are_full_exprs_p; } }