diff options
Diffstat (limited to 'gcc/config/avr/avr.c')
-rw-r--r-- | gcc/config/avr/avr.c | 111 |
1 files changed, 64 insertions, 47 deletions
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 341fe9b2f85..c25f8983a79 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -963,7 +963,7 @@ avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set) { /* Don't error so that insane code from newlib still compiles and does not break building newlib. As PR51345 is implemented - now, there are multilib variants with -mtiny-stack. + now, there are multilib variants with -msp8. If user wants sanity checks he can use -Wstack-usage= or similar options. @@ -2774,7 +2774,7 @@ output_movhi (rtx insn, rtx xop[], int *plen) } else if (test_hard_reg_class (STACK_REG, src)) { - return AVR_HAVE_8BIT_SP + return !AVR_HAVE_SPH ? avr_asm_len ("in %A0,__SP_L__" CR_TAB "clr %B0", xop, plen, -2) @@ -7341,7 +7341,7 @@ avr_file_start (void) /* Print I/O addresses of some SFRs used with IN and OUT. */ - if (!AVR_HAVE_8BIT_SP) + if (AVR_HAVE_SPH) fprintf (asm_out_file, "__SP_H__ = 0x%02x\n", avr_addr.sp_h - sfr_offset); fprintf (asm_out_file, "__SP_L__ = 0x%02x\n", avr_addr.sp_l - sfr_offset); @@ -10285,6 +10285,42 @@ enum avr_builtin_id AVR_BUILTIN_COUNT }; +struct GTY(()) avr_builtin_description +{ + enum insn_code icode; + const char *name; + int n_args; + tree fndecl; +}; + + +/* Notice that avr_bdesc[] and avr_builtin_id are initialized in such a way + that a built-in's ID can be used to access the built-in by means of + avr_bdesc[ID] */ + +static GTY(()) struct avr_builtin_description +avr_bdesc[AVR_BUILTIN_COUNT] = + { + +#define DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, ICODE) \ + { ICODE, NAME, N_ARGS, NULL_TREE }, +#include "builtins.def" +#undef DEF_BUILTIN + }; + + +/* Implement `TARGET_BUILTIN_DECL'. */ + +static tree +avr_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED) +{ + if (id < AVR_BUILTIN_COUNT) + return avr_bdesc[id].fndecl; + + return error_mark_node; +} + + static void avr_init_builtin_int24 (void) { @@ -10295,6 +10331,7 @@ avr_init_builtin_int24 (void) (*lang_hooks.types.register_builtin_type) (uint24_type, "__uint24"); } + /* Implement `TARGET_INIT_BUILTINS' */ /* Set up all builtin functions for this target. */ @@ -10348,7 +10385,9 @@ avr_init_builtins (void) NULL); #define DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, CODE) \ - add_builtin_function (NAME, TYPE, ID, BUILT_IN_MD, NULL, NULL_TREE); + gcc_assert (ID < AVR_BUILTIN_COUNT); \ + avr_bdesc[ID].fndecl \ + = add_builtin_function (NAME, TYPE, ID, BUILT_IN_MD, NULL, NULL_TREE); #include "builtins.def" #undef DEF_BUILTIN @@ -10356,27 +10395,6 @@ avr_init_builtins (void) } -struct avr_builtin_description -{ - enum insn_code icode; - const char *name; - enum avr_builtin_id id; - int n_args; -}; - -static const struct avr_builtin_description -avr_bdesc[] = - { - -#define DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, ICODE) \ - { ICODE, NAME, ID, N_ARGS }, -#include "builtins.def" -#undef DEF_BUILTIN - - { CODE_FOR_nothing, NULL, 0, -1 } - }; - - /* Subroutine of avr_expand_builtin to take care of unop insns. */ static rtx @@ -10545,6 +10563,7 @@ avr_expand_triop_builtin (enum insn_code icode, tree exp, rtx target) } +/* Implement `TARGET_EXPAND_BUILTIN'. */ /* Expand an expression EXP that calls a built-in function, with result going to TARGET if that's convenient (and in mode MODE if that's convenient). @@ -10557,13 +10576,15 @@ avr_expand_builtin (tree exp, rtx target, enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED) { - size_t i; tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); const char* bname = IDENTIFIER_POINTER (DECL_NAME (fndecl)); unsigned int id = DECL_FUNCTION_CODE (fndecl); + const struct avr_builtin_description *d = &avr_bdesc[id]; tree arg0; rtx op0; + gcc_assert (id < AVR_BUILTIN_COUNT); + switch (id) { case AVR_BUILTIN_NOP: @@ -10597,29 +10618,22 @@ avr_expand_builtin (tree exp, rtx target, } } - for (i = 0; avr_bdesc[i].name; i++) + /* No special treatment needed: vanilla expand. */ + + switch (d->n_args) { - const struct avr_builtin_description *d = &avr_bdesc[i]; + case 0: + emit_insn ((GEN_FCN (d->icode)) (target)); + return 0; - if (d->id == id) - switch (d->n_args) - { - case 0: - emit_insn ((GEN_FCN (d->icode)) (target)); - return 0; - - case 1: - return avr_expand_unop_builtin (d->icode, exp, target); - - case 2: - return avr_expand_binop_builtin (d->icode, exp, target); - - case 3: - return avr_expand_triop_builtin (d->icode, exp, target); - - default: - gcc_unreachable(); - } + case 1: + return avr_expand_unop_builtin (d->icode, exp, target); + + case 2: + return avr_expand_binop_builtin (d->icode, exp, target); + + case 3: + return avr_expand_triop_builtin (d->icode, exp, target); } gcc_unreachable (); @@ -10878,6 +10892,9 @@ avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg, #undef TARGET_INIT_BUILTINS #define TARGET_INIT_BUILTINS avr_init_builtins +#undef TARGET_BUILTIN_DECL +#define TARGET_BUILTIN_DECL avr_builtin_decl + #undef TARGET_EXPAND_BUILTIN #define TARGET_EXPAND_BUILTIN avr_expand_builtin |