Commit 639d0302 by Georg-Johann Lay Committed by Georg-Johann Lay

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
parent 8310dca7
2012-02-28 Georg-Johann Lay <avr@gjlay.de>
* 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 <avr@gjlay.de>
PR target/52148
* config/avr/avr.md (movmem_<mode>): Replace match_operand that
match only one single hard register with respective hard reg rtx.
......
......@@ -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<n> 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));
}
}
......@@ -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
......
/* 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
<http://www.gnu.org/licenses/>. */
/* 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)
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment