From 639d0302e66e9be17e7979a7c7be71080abcd5b5 Mon Sep 17 00:00:00 2001 From: Georg-Johann Lay Date: Tue, 28 Feb 2012 08:57:39 +0000 Subject: [PATCH] builtins.def: New file. * 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. From-SVN: r184616 --- gcc/ChangeLog | 16 ++++ gcc/config/avr/avr-c.c | 35 ++++---- gcc/config/avr/avr.c | 155 +++++++++++++++--------------------- gcc/config/avr/builtins.def | 50 ++++++++++++ gcc/config/avr/t-avr | 2 + 5 files changed, 151 insertions(+), 107 deletions(-) create mode 100644 gcc/config/avr/builtins.def diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 232754873bf..a89a8ff6943 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2012-02-28 Georg-Johann Lay + + * 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. + 2012-02-28 Georg-Johann Lay PR target/52148 diff --git a/gcc/config/avr/avr-c.c b/gcc/config/avr/avr-c.c index 64f5f801626..598a340e07e 100644 --- a/gcc/config/avr/avr-c.c +++ b/gcc/config/avr/avr-c.c @@ -71,9 +71,19 @@ avr_toupper (char *up, const char *lo) /* Worker function for TARGET_CPU_CPP_BUILTINS. */ +static const char *const avr_builtin_name[] = + { +#define DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, CODE) NAME, +#include "builtins.def" +#undef DEF_BUILTIN + NULL + }; + void avr_cpu_cpp_builtins (struct cpp_reader *pfile) { + int i; + builtin_define_std ("AVR"); if (avr_current_arch->macro) @@ -140,8 +150,6 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) if (!strcmp (lang_hooks.name, "GNU C")) { - int i; - for (i = 0; avr_addrspace[i].name; i++) if (!ADDR_SPACE_GENERIC_P (i) /* Only supply __FLASH macro if the address space is reasonable @@ -161,20 +169,11 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) easily query if or if not a specific builtin is available. */ - cpp_define (pfile, "__BUILTIN_AVR_NOP"); - cpp_define (pfile, "__BUILTIN_AVR_SEI"); - cpp_define (pfile, "__BUILTIN_AVR_CLI"); - cpp_define (pfile, "__BUILTIN_AVR_WDR"); - cpp_define (pfile, "__BUILTIN_AVR_SLEEP"); - cpp_define (pfile, "__BUILTIN_AVR_SWAP"); - cpp_define (pfile, "__BUILTIN_AVR_INSERT_BITS"); - cpp_define (pfile, "__BUILTIN_AVR_DELAY_CYCLES"); - - cpp_define (pfile, "__BUILTIN_AVR_FMUL"); - cpp_define (pfile, "__BUILTIN_AVR_FMULS"); - cpp_define (pfile, "__BUILTIN_AVR_FMULSU"); - - cpp_define (pfile, "__INT24_MAX__=8388607L"); - cpp_define (pfile, "__INT24_MIN__=(-__INT24_MAX__-1)"); - cpp_define (pfile, "__UINT24_MAX__=16777215UL"); + for (i = 0; avr_builtin_name[i]; i++) + { + const char *name = avr_builtin_name[i]; + char *Name = (char*) alloca (1 + strlen (name)); + + cpp_define (pfile, avr_toupper (Name, name)); + } } 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 diff --git a/gcc/config/avr/builtins.def b/gcc/config/avr/builtins.def new file mode 100644 index 00000000000..4aa0f1159f9 --- /dev/null +++ b/gcc/config/avr/builtins.def @@ -0,0 +1,50 @@ +/* Copyright (C) 2012 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* This file contains the definitions and documentation for the + builtins defined in the AVR part of the GNU compiler. + Befor including this file, define a macro + + DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, ICODE) + + NAME: The name as visible by the user as a C string. + ID: An integer to identify the built-in. + N_ARGS: Number of input arguments. If special treatment is needed, + set to -1 and handle it by hand, see avr.c:avr_expand_builtin(). + TYPE: A tree node describing the prototype of the built-in. + ICODE: Insn code number for the insn attached to the built-in. + If special treatment is needed to expand the built-in, set to -1. +*/ + +/* Mapped to respective instruction. */ +DEF_BUILTIN ("__builtin_avr_nop", -1, AVR_BUILTIN_NOP, void_ftype_void, -1) +DEF_BUILTIN ("__builtin_avr_sei", 0, AVR_BUILTIN_SEI, void_ftype_void, CODE_FOR_enable_interrupt) +DEF_BUILTIN ("__builtin_avr_cli", 0, AVR_BUILTIN_CLI, void_ftype_void, CODE_FOR_disable_interrupt) +DEF_BUILTIN ("__builtin_avr_wdr", 0, AVR_BUILTIN_WDR, void_ftype_void, CODE_FOR_wdr) +DEF_BUILTIN ("__builtin_avr_sleep", 0, AVR_BUILTIN_SLEEP, void_ftype_void, CODE_FOR_sleep) + +/* Mapped to respective instruction but might alse be folded away + or emit as libgcc call if ISA does not provide the instruction. */ +DEF_BUILTIN ("__builtin_avr_swap", 1, AVR_BUILTIN_SWAP, uchar_ftype_uchar, CODE_FOR_rotlqi3_4) +DEF_BUILTIN ("__builtin_avr_fmul", 2, AVR_BUILTIN_FMUL, uint_ftype_uchar_uchar, CODE_FOR_fmul) +DEF_BUILTIN ("__builtin_avr_fmuls", 2, AVR_BUILTIN_FMULS, int_ftype_char_char, CODE_FOR_fmuls) +DEF_BUILTIN ("__builtin_avr_fmulsu", 2, AVR_BUILTIN_FMULSU, int_ftype_char_uchar, CODE_FOR_fmulsu) + +/* More complex stuff that cannot be mapped 1:1 to an instruction. */ +DEF_BUILTIN ("__builtin_avr_delay_cycles", -1, AVR_BUILTIN_DELAY_CYCLES, void_ftype_ulong, -1) +DEF_BUILTIN ("__builtin_avr_insert_bits", 3, AVR_BUILTIN_INSERT_BITS, uchar_ftype_ulong_uchar_uchar, CODE_FOR_insert_bits) diff --git a/gcc/config/avr/t-avr b/gcc/config/avr/t-avr index 732ca005688..e6b4adee182 100644 --- a/gcc/config/avr/t-avr +++ b/gcc/config/avr/t-avr @@ -34,6 +34,8 @@ avr-log.o: $(srcdir)/config/avr/avr-log.c \ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(INPUT_H) $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< +avr.o avr-c.o: $(srcdir)/config/avr/builtins.def + # Files and Variables auto-generated from avr-mcus.def AVR_MCUS = $(srcdir)/config/avr/avr-mcus.def -- 2.30.2