summaryrefslogtreecommitdiff
path: root/gcc/config/avr/avr.c
diff options
context:
space:
mode:
authorgjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>2012-02-28 08:57:39 +0000
committergjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>2012-02-28 08:57:39 +0000
commitc19a2f5f9924818ebb74f5c54745aa0f24abfe58 (patch)
tree825810f4862db52ee58d2ce059b5c409b59da8bb /gcc/config/avr/avr.c
parentf1222c71bcfdaeb7a951ea129f0f6dc12fb3133c (diff)
downloadgcc-c19a2f5f9924818ebb74f5c54745aa0f24abfe58.tar.gz
* config/avr/builtins.def: New file.
* config/avr/t-avr (avr.o, avr-c.o): Depend on it. * config/avr/avr.c (enum avr_builtin_id): Use it. (avr_init_builtins): Use it. And use avr_bdesc. (bdesc_1arg): Remove. (bdesc_2arg): Remove. (bdesc_3arg): Remove. (struct avr_builtin_description): Add field n_args. (avr_bdesc): New static variable using builtins.def. (avr_expand_builtin): Use it. Don't call avr_expand_delay_cycles if op0 is not CONST_INT. (avr_fold_builtin): Fold AVR_BUILTIN_SWAP. Don't fold AVR_BUILTIN_INSERT_BITS if arg0 is not INTEGER_CST. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@184616 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/avr/avr.c')
-rw-r--r--gcc/config/avr/avr.c155
1 files changed, 66 insertions, 89 deletions
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 4779aabfc79..de556352079 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -10528,17 +10528,12 @@ avr_out_insert_bits (rtx *op, int *plen)
enum avr_builtin_id
{
- AVR_BUILTIN_NOP,
- AVR_BUILTIN_SEI,
- AVR_BUILTIN_CLI,
- AVR_BUILTIN_WDR,
- AVR_BUILTIN_SLEEP,
- AVR_BUILTIN_SWAP,
- AVR_BUILTIN_INSERT_BITS,
- AVR_BUILTIN_FMUL,
- AVR_BUILTIN_FMULS,
- AVR_BUILTIN_FMULSU,
- AVR_BUILTIN_DELAY_CYCLES
+
+#define DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, CODE) ID,
+#include "builtins.def"
+#undef DEF_BUILTIN
+
+ AVR_BUILTIN_COUNT
};
static void
@@ -10551,14 +10546,6 @@ avr_init_builtin_int24 (void)
(*lang_hooks.types.register_builtin_type) (uint24_type, "__uint24");
}
-#define DEF_BUILTIN(NAME, TYPE, CODE) \
- do \
- { \
- add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
- NULL, NULL_TREE); \
- } while (0)
-
-
/* Implement `TARGET_INIT_BUILTINS' */
/* Set up all builtin functions for this target. */
@@ -10598,58 +10585,36 @@ avr_init_builtins (void)
unsigned_char_type_node,
NULL_TREE);
- DEF_BUILTIN ("__builtin_avr_nop", void_ftype_void, AVR_BUILTIN_NOP);
- DEF_BUILTIN ("__builtin_avr_sei", void_ftype_void, AVR_BUILTIN_SEI);
- DEF_BUILTIN ("__builtin_avr_cli", void_ftype_void, AVR_BUILTIN_CLI);
- DEF_BUILTIN ("__builtin_avr_wdr", void_ftype_void, AVR_BUILTIN_WDR);
- DEF_BUILTIN ("__builtin_avr_sleep", void_ftype_void, AVR_BUILTIN_SLEEP);
- DEF_BUILTIN ("__builtin_avr_swap", uchar_ftype_uchar, AVR_BUILTIN_SWAP);
- DEF_BUILTIN ("__builtin_avr_delay_cycles", void_ftype_ulong,
- AVR_BUILTIN_DELAY_CYCLES);
-
- DEF_BUILTIN ("__builtin_avr_fmul", uint_ftype_uchar_uchar,
- AVR_BUILTIN_FMUL);
- DEF_BUILTIN ("__builtin_avr_fmuls", int_ftype_char_char,
- AVR_BUILTIN_FMULS);
- DEF_BUILTIN ("__builtin_avr_fmulsu", int_ftype_char_uchar,
- AVR_BUILTIN_FMULSU);
-
- DEF_BUILTIN ("__builtin_avr_insert_bits", uchar_ftype_ulong_uchar_uchar,
- AVR_BUILTIN_INSERT_BITS);
-
+#define DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, CODE) \
+ add_builtin_function (NAME, TYPE, ID, BUILT_IN_MD, NULL, NULL_TREE);
+#include "builtins.def"
+#undef DEF_BUILTIN
+
avr_init_builtin_int24 ();
}
-#undef DEF_BUILTIN
struct avr_builtin_description
{
- const enum insn_code icode;
- const char *const name;
- const enum avr_builtin_id id;
+ enum insn_code icode;
+ const char *name;
+ enum avr_builtin_id id;
+ int n_args;
};
static const struct avr_builtin_description
-bdesc_1arg[] =
+avr_bdesc[] =
{
- { CODE_FOR_rotlqi3_4, "__builtin_avr_swap", AVR_BUILTIN_SWAP }
- };
-static const struct avr_builtin_description
-bdesc_2arg[] =
- {
- { CODE_FOR_fmul, "__builtin_avr_fmul", AVR_BUILTIN_FMUL },
- { CODE_FOR_fmuls, "__builtin_avr_fmuls", AVR_BUILTIN_FMULS },
- { CODE_FOR_fmulsu, "__builtin_avr_fmulsu", AVR_BUILTIN_FMULSU }
- };
+#define DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, ICODE) \
+ { ICODE, NAME, ID, N_ARGS },
+#include "builtins.def"
+#undef DEF_BUILTIN
-static const struct avr_builtin_description
-bdesc_3arg[] =
- {
- { CODE_FOR_insert_bits, "__builtin_avr_insert_bits",
- AVR_BUILTIN_INSERT_BITS }
+ { CODE_FOR_nothing, NULL, 0, -1 }
};
+
/* Subroutine of avr_expand_builtin to take care of unop insns. */
static rtx
@@ -10831,7 +10796,6 @@ avr_expand_builtin (tree exp, rtx target,
int ignore ATTRIBUTE_UNUSED)
{
size_t i;
- const struct avr_builtin_description *d;
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
const char* bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
unsigned int id = DECL_FUNCTION_CODE (fndecl);
@@ -10844,31 +10808,16 @@ avr_expand_builtin (tree exp, rtx target,
emit_insn (gen_nopv (GEN_INT(1)));
return 0;
- case AVR_BUILTIN_SEI:
- emit_insn (gen_enable_interrupt ());
- return 0;
-
- case AVR_BUILTIN_CLI:
- emit_insn (gen_disable_interrupt ());
- return 0;
-
- case AVR_BUILTIN_WDR:
- emit_insn (gen_wdr ());
- return 0;
-
- case AVR_BUILTIN_SLEEP:
- emit_insn (gen_sleep ());
- return 0;
-
case AVR_BUILTIN_DELAY_CYCLES:
{
arg0 = CALL_EXPR_ARG (exp, 0);
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
- if (! CONST_INT_P (op0))
+ if (!CONST_INT_P (op0))
error ("%s expects a compile time integer constant", bname);
+ else
+ avr_expand_delay_cycles (op0);
- avr_expand_delay_cycles (op0);
return 0;
}
@@ -10886,18 +10835,31 @@ avr_expand_builtin (tree exp, rtx target,
}
}
- for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
- if (d->id == id)
- return avr_expand_unop_builtin (d->icode, exp, target);
-
- for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
- if (d->id == id)
- return avr_expand_binop_builtin (d->icode, exp, target);
-
- for (i = 0, d = bdesc_3arg; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
- if (d->id == id)
- return avr_expand_triop_builtin (d->icode, exp, target);
-
+ for (i = 0; avr_bdesc[i].name; i++)
+ {
+ const struct avr_builtin_description *d = &avr_bdesc[i];
+
+ 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();
+ }
+ }
+
gcc_unreachable ();
}
@@ -10919,17 +10881,32 @@ avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
default:
break;
+ case AVR_BUILTIN_SWAP:
+ {
+ return fold_build2 (LROTATE_EXPR, val_type, arg[0],
+ build_int_cst (val_type, 4));
+ }
+
case AVR_BUILTIN_INSERT_BITS:
{
tree tbits = arg[1];
tree tval = arg[2];
tree tmap;
tree map_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
- double_int map = tree_to_double_int (arg[0]);
+ double_int map;
bool changed = false;
unsigned i;
avr_map_op_t best_g;
+
+ if (TREE_CODE (arg[0]) != INTEGER_CST)
+ {
+ /* No constant as first argument: Don't fold this and run into
+ error in avr_expand_builtin. */
+
+ break;
+ }
+ map = tree_to_double_int (arg[0]);
tmap = double_int_to_tree (map_type, map);
if (TREE_CODE (tval) != INTEGER_CST