diff options
author | Nathan Sidwell <nathan@acm.org> | 2015-12-04 14:02:27 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2015-12-04 14:02:27 +0000 |
commit | dc3d2aebdccab3d85cfc7e2f75834817f4e440f6 (patch) | |
tree | 0588ca2ad3d840316d88e2c875880cbf9c62939c /gcc | |
parent | 96d977a8f3ecfaedf634d86179af47fff7233f1e (diff) | |
download | gcc-dc3d2aebdccab3d85cfc7e2f75834817f4e440f6.zip gcc-dc3d2aebdccab3d85cfc7e2f75834817f4e440f6.tar.gz gcc-dc3d2aebdccab3d85cfc7e2f75834817f4e440f6.tar.bz2 |
nvptx.c (write_one_arg): Deal with prologue emission too.
* config/nvptx/nvptx.c (write_one_arg): Deal with prologue
emission too. Change 'no_arg_types' to 'prototyped'.
(write_fn_proto): Use write_one_arg for stdarg, static chain &
main.
(nvptx_declare_function_name): Use write_one_arg for prologue copies.
From-SVN: r231267
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/nvptx/nvptx.c | 175 |
2 files changed, 88 insertions, 95 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c1eacbc..74c8080 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-12-04 Nathan Sidwell <nathan@acm.org> + + * config/nvptx/nvptx.c (write_one_arg): Deal with prologue + emission too. Change 'no_arg_types' to 'prototyped'. + (write_fn_proto): Use write_one_arg for stdarg, static chain & + main. + (nvptx_declare_function_name): Use write_one_arg for prologue copies. + 2015-12-04 Richard Biener <rguenther@suse.de> * tree-ssa-sccvn.c (sccvn_dom_walker): Add unreachable_dom diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c index a036f30..0f272cf 100644 --- a/gcc/config/nvptx/nvptx.c +++ b/gcc/config/nvptx/nvptx.c @@ -389,38 +389,67 @@ arg_promotion (machine_mode mode) return mode; } -/* Write the declaration of a function arg of TYPE to S. I is the index - of the argument, MODE its mode. NO_ARG_TYPES is true if this is for - a decl with zero TYPE_ARG_TYPES, i.e. an old-style C decl. */ +/* Process function parameter TYPE, either emitting in a prototype + argument, or as a copy a in a function prologue. ARGNO is the + index of this argument in the PTX function. FOR_REG is negative, + if we're emitting the PTX prototype. It is zero if we're copying + to an argument register and it is greater than zero if we're + copying to a specific hard register. PROTOTYPED is true, if this + is a prototyped function, rather than an old-style C declaration. + + The behaviour here must match the regular GCC function parameter + marshalling machinery. */ static int -write_one_arg (std::stringstream &s, const char *sep, int i, - tree type, machine_mode mode, bool no_arg_types) +write_one_arg (std::stringstream &s, int for_reg, int argno, + tree type, bool prototyped) { + machine_mode mode = TYPE_MODE (type); + if (!PASS_IN_REG_P (mode, type)) mode = Pmode; machine_mode split = maybe_split_mode (mode); if (split != VOIDmode) { - i = write_one_arg (s, sep, i, TREE_TYPE (type), split, false); - sep = ", "; mode = split; + argno = write_one_arg (s, for_reg, argno, + TREE_TYPE (type), prototyped); } - if (no_arg_types && !AGGREGATE_TYPE_P (type)) + if (!prototyped && !AGGREGATE_TYPE_P (type)) { if (mode == SFmode) mode = DFmode; mode = arg_promotion (mode); } - s << sep; - s << ".param" << nvptx_ptx_type_from_mode (mode, false) << " %in_ar" - << i << (mode == QImode || mode == HImode ? "[1]" : ""); - if (mode == BLKmode) - s << "[" << int_size_in_bytes (type) << "]"; - return i + 1; + if (for_reg < 0) + { + /* Writing PTX prototype. */ + s << (argno ? ", " : " ("); + s << ".param" << nvptx_ptx_type_from_mode (mode, false) + << " %in_ar" << argno; + if (mode == QImode || mode == HImode) + s << "[1]"; + } + else + { + mode = arg_promotion (mode); + s << "\t.reg" << nvptx_ptx_type_from_mode (mode, false) << " "; + if (for_reg) + s << reg_names[for_reg]; + else + s << "%ar" << argno; + s << ";\n"; + s << "\tld.param" << nvptx_ptx_type_from_mode (mode, false) << " "; + if (for_reg) + s << reg_names[for_reg]; + else + s << "%ar" << argno; + s<< ", [%in_ar" << argno << "];\n"; + } + return argno + 1; } /* Look for attributes in ATTRS that would indicate we must write a function @@ -507,16 +536,11 @@ write_fn_proto (std::stringstream &s, bool is_defn, s << name; - const char *sep = " ("; - int i = 0; + int argno = 0; /* Emit argument list. */ if (return_in_mem) - { - s << sep << ".param.u" << GET_MODE_BITSIZE (Pmode) << " %in_ar0"; - sep = ", "; - i++; - } + argno = write_one_arg (s, -1, argno, ptr_type_node, true); /* We get: NULL in TYPE_ARG_TYPES, for old-style functions @@ -524,46 +548,34 @@ write_fn_proto (std::stringstream &s, bool is_defn, declaration. So we have to pick the best one we have. */ tree args = TYPE_ARG_TYPES (fntype); - bool null_type_args = !args; - if (null_type_args) - args = DECL_ARGUMENTS (decl); + bool prototyped = true; + if (!args) + { + args = DECL_ARGUMENTS (decl); + prototyped = false; + } for (; args; args = TREE_CHAIN (args)) { - tree type = null_type_args ? TREE_TYPE (args) : TREE_VALUE (args); - machine_mode mode = TYPE_MODE (type); + tree type = prototyped ? TREE_VALUE (args) : TREE_TYPE (args); - if (mode == VOIDmode) - break; - i = write_one_arg (s, sep, i, type, mode, null_type_args); - sep = ", "; + if (type != void_type_node) + argno = write_one_arg (s, -1, argno, type, prototyped); } if (stdarg_p (fntype)) - { - s << sep << ".param.u" << GET_MODE_BITSIZE (Pmode) << " %in_argp"; - i++; - sep = ", "; - } + argno = write_one_arg (s, -1, argno, ptr_type_node, true); if (DECL_STATIC_CHAIN (decl)) - { - s << sep << ".reg.u" << GET_MODE_BITSIZE (Pmode) - << reg_names [STATIC_CHAIN_REGNUM]; - i++; - sep = ", "; - } + argno = write_one_arg (s, -1, argno, ptr_type_node, true); - if (!i && strcmp (name, "main") == 0) + if (!argno && strcmp (name, "main") == 0) { - s << sep - << ".param.u32 %argc, .param.u" << GET_MODE_BITSIZE (Pmode) - << " %argv"; - i++; - sep = ", "; + argno = write_one_arg (s, -1, argno, integer_type_node, true); + argno = write_one_arg (s, -1, argno, ptr_type_node, true); } - if (i) + if (argno) s << ")"; s << (is_defn ? "\n" : ";\n"); @@ -705,63 +717,43 @@ nvptx_declare_function_name (FILE *file, const char *name, const_tree decl) { tree fntype = TREE_TYPE (decl); tree result_type = TREE_TYPE (fntype); - int argno = 0; + int argno = 0; + /* We construct the initial part of the function into a string + stream, in order to share the prototype writing code. */ std::stringstream s; write_fn_proto (s, true, name, decl); - fprintf (file, "%s", s.str().c_str()); - fprintf (file, "{\n"); + s << "{\n"; bool return_in_mem = (TYPE_MODE (result_type) != VOIDmode && !RETURN_IN_REG_P (TYPE_MODE (result_type))); if (return_in_mem) - { - fprintf (file, "\t.reg.u%d %%ar%d;\n", GET_MODE_BITSIZE (Pmode), argno); - fprintf (file, "\tld.param.u%d %%ar%d, [%%in_ar%d];\n", - GET_MODE_BITSIZE (Pmode), argno, argno); - argno++; - } - + argno = write_one_arg (s, 0, argno, ptr_type_node, true); + /* Declare and initialize incoming arguments. */ - tree args = DECL_ARGUMENTS (decl); - bool prototyped = false; - if (TYPE_ARG_TYPES (fntype)) + tree args = TYPE_ARG_TYPES (fntype); + bool prototyped = true; + if (!args) { - args = TYPE_ARG_TYPES (fntype); - prototyped = true; + args = DECL_ARGUMENTS (decl); + prototyped = false; } for (; args != NULL_TREE; args = TREE_CHAIN (args)) { tree type = prototyped ? TREE_VALUE (args) : TREE_TYPE (args); - machine_mode mode = TYPE_MODE (type); - int count = 1; - if (mode == VOIDmode) - break; + if (type != void_type_node) + argno = write_one_arg (s, 0, argno, type, prototyped); + } - if (!PASS_IN_REG_P (mode, type)) - mode = Pmode; + if (stdarg_p (fntype)) + argno = write_one_arg (s, ARG_POINTER_REGNUM, argno, ptr_type_node, true); - machine_mode split = maybe_split_mode (mode); - if (split != VOIDmode) - { - count = 2; - mode = split; - } - else if (!prototyped && !AGGREGATE_TYPE_P (type) && mode == SFmode) - mode = DFmode; + if (DECL_STATIC_CHAIN (decl)) + argno = write_one_arg (s, STATIC_CHAIN_REGNUM, argno, ptr_type_node, true); - mode = arg_promotion (mode); - while (count--) - { - fprintf (file, "\t.reg%s %%ar%d;\n", - nvptx_ptx_type_from_mode (mode, false), argno); - fprintf (file, "\tld.param%s %%ar%d, [%%in_ar%d];\n", - nvptx_ptx_type_from_mode (mode, false), argno, argno); - argno++; - } - } + fprintf (file, "%s", s.str().c_str()); /* C++11 ABI causes us to return a reference to the passed in pointer for return_in_mem. */ @@ -773,16 +765,9 @@ nvptx_declare_function_name (FILE *file, const char *name, const_tree decl) nvptx_ptx_type_from_mode (mode, false)); } - if (stdarg_p (fntype)) - { - fprintf (file, "\t.reg.u%d %%argp;\n", GET_MODE_BITSIZE (Pmode)); - fprintf (file, "\tld.param.u%d %%argp, [%%in_argp];\n", - GET_MODE_BITSIZE (Pmode)); - } - fprintf (file, "\t.reg.u%d %s;\n", GET_MODE_BITSIZE (Pmode), reg_names[OUTGOING_STATIC_CHAIN_REGNUM]); - + /* Declare the pseudos we have as ptx registers. */ int maxregs = max_reg_num (); for (int i = LAST_VIRTUAL_REGISTER + 1; i < maxregs; i++) |