diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-05-11 23:33:12 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-05-11 23:33:12 +0000 |
commit | ae231cbde5a6cd003fe6d6af2cb7e49fedf33a58 (patch) | |
tree | 66bde823d051c8d67a21d2f66fa55f57f5909ced /gcc/cfgexpand.c | |
parent | 2d564016f2f3f88cb2166326dac39969acf5c931 (diff) | |
download | gcc-ae231cbde5a6cd003fe6d6af2cb7e49fedf33a58.tar.gz |
Merge expand_asm_operands into expand_asm_stmt
Prepatory to converting from tree chains to vectors.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@223023 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r-- | gcc/cfgexpand.c | 167 |
1 files changed, 72 insertions, 95 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 69d00a00095..5d44c48b6c4 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -2522,22 +2522,78 @@ tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET *clobbered_regs) VOL nonzero means the insn is volatile; don't optimize it. */ static void -expand_asm_operands (tree string, tree outputs, tree inputs, - tree clobbers, tree labels, basic_block fallthru_bb, - int vol, location_t locus) +expand_asm_stmt (gasm *stmt) { + int noutputs, ninputs, nclobbers, nlabels, i; + tree string, outputs, inputs, clobbers, labels, tail, t; + location_t locus = gimple_location (stmt); + basic_block fallthru_bb = NULL; + + /* Meh... convert the gimple asm operands into real tree lists. + Eventually we should make all routines work on the vectors instead + of relying on TREE_CHAIN. */ + outputs = NULL_TREE; + noutputs = gimple_asm_noutputs (stmt); + if (noutputs > 0) + { + t = outputs = gimple_asm_output_op (stmt, 0); + for (i = 1; i < noutputs; i++) + t = TREE_CHAIN (t) = gimple_asm_output_op (stmt, i); + } + + inputs = NULL_TREE; + ninputs = gimple_asm_ninputs (stmt); + if (ninputs > 0) + { + t = inputs = gimple_asm_input_op (stmt, 0); + for (i = 1; i < ninputs; i++) + t = TREE_CHAIN (t) = gimple_asm_input_op (stmt, i); + } + + clobbers = NULL_TREE; + nclobbers = gimple_asm_nclobbers (stmt); + if (nclobbers > 0) + { + t = clobbers = gimple_asm_clobber_op (stmt, 0); + for (i = 1; i < nclobbers; i++) + t = TREE_CHAIN (t) = gimple_asm_clobber_op (stmt, i); + } + + labels = NULL_TREE; + nlabels = gimple_asm_nlabels (stmt); + if (nlabels > 0) + { + edge fallthru = find_fallthru_edge (gimple_bb (stmt)->succs); + if (fallthru) + fallthru_bb = fallthru->dest; + t = labels = gimple_asm_label_op (stmt, 0); + for (i = 1; i < nlabels; i++) + t = TREE_CHAIN (t) = gimple_asm_label_op (stmt, i); + } + + { + const char *s = gimple_asm_string (stmt); + string = build_string (strlen (s), s); + } + + if (gimple_asm_input_p (stmt)) + { + expand_asm_loc (string, gimple_asm_volatile_p (stmt), locus); + return; + } + + /* Record the contents of OUTPUTS before it is modified. */ + tree *orig_outputs = XALLOCAVEC (tree, noutputs); + for (i = 0; i < noutputs; ++i) + orig_outputs[i] = TREE_VALUE (gimple_asm_output_op (stmt, i)); + + bool vol = gimple_asm_volatile_p (stmt); + rtvec argvec, constraintvec, labelvec; rtx body; - int ninputs = list_length (inputs); - int noutputs = list_length (outputs); - int nlabels = list_length (labels); int ninout; - int nclobbers; HARD_REG_SET clobbered_regs; int clobber_conflict_found = 0; - tree tail; - tree t; - int i; /* Vector of RTX's of evaluated output operands. */ rtx *output_rtx = XALLOCAVEC (rtx, noutputs); int *inout_opnum = XALLOCAVEC (int, noutputs); @@ -2994,101 +3050,22 @@ expand_asm_operands (tree string, tree outputs, tree inputs, if (real_output_rtx[i]) emit_move_insn (real_output_rtx[i], output_rtx[i]); - crtl->has_asm_statement = 1; - free_temp_slots (); -} - - -static void -expand_asm_stmt (gasm *stmt) -{ - int noutputs; - tree outputs, tail, t; - tree *o; - size_t i, n; - const char *s; - tree str, out, in, cl, labels; - location_t locus = gimple_location (stmt); - basic_block fallthru_bb = NULL; - - /* Meh... convert the gimple asm operands into real tree lists. - Eventually we should make all routines work on the vectors instead - of relying on TREE_CHAIN. */ - out = NULL_TREE; - n = gimple_asm_noutputs (stmt); - if (n > 0) - { - t = out = gimple_asm_output_op (stmt, 0); - for (i = 1; i < n; i++) - t = TREE_CHAIN (t) = gimple_asm_output_op (stmt, i); - } - - in = NULL_TREE; - n = gimple_asm_ninputs (stmt); - if (n > 0) - { - t = in = gimple_asm_input_op (stmt, 0); - for (i = 1; i < n; i++) - t = TREE_CHAIN (t) = gimple_asm_input_op (stmt, i); - } - - cl = NULL_TREE; - n = gimple_asm_nclobbers (stmt); - if (n > 0) - { - t = cl = gimple_asm_clobber_op (stmt, 0); - for (i = 1; i < n; i++) - t = TREE_CHAIN (t) = gimple_asm_clobber_op (stmt, i); - } - - labels = NULL_TREE; - n = gimple_asm_nlabels (stmt); - if (n > 0) - { - edge fallthru = find_fallthru_edge (gimple_bb (stmt)->succs); - if (fallthru) - fallthru_bb = fallthru->dest; - t = labels = gimple_asm_label_op (stmt, 0); - for (i = 1; i < n; i++) - t = TREE_CHAIN (t) = gimple_asm_label_op (stmt, i); - } - - s = gimple_asm_string (stmt); - str = build_string (strlen (s), s); - - if (gimple_asm_input_p (stmt)) - { - expand_asm_loc (str, gimple_asm_volatile_p (stmt), locus); - return; - } - - outputs = out; - noutputs = gimple_asm_noutputs (stmt); - /* o[I] is the place that output number I should be written. */ - o = (tree *) alloca (noutputs * sizeof (tree)); - - /* Record the contents of OUTPUTS before it is modified. */ - for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) - o[i] = TREE_VALUE (tail); - - /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of - OUTPUTS some trees for where the values were actually stored. */ - expand_asm_operands (str, outputs, in, cl, labels, fallthru_bb, - gimple_asm_volatile_p (stmt), locus); - /* Copy all the intermediate outputs into the specified outputs. */ for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) { - if (o[i] != TREE_VALUE (tail)) + if (orig_outputs[i] != TREE_VALUE (tail)) { - expand_assignment (o[i], TREE_VALUE (tail), false); + expand_assignment (orig_outputs[i], TREE_VALUE (tail), false); free_temp_slots (); /* Restore the original value so that it's correct the next time we expand this function. */ - TREE_VALUE (tail) = o[i]; + TREE_VALUE (tail) = orig_outputs[i]; } } + + crtl->has_asm_statement = 1; + free_temp_slots (); } /* Emit code to jump to the address |