aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/avr/avr.c
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2012-06-15 15:56:02 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2012-06-15 15:56:02 +0000
commiteb6bb559981118ed95c4340fa32baf346a89b53e (patch)
tree8b3689be333feeb214860e30c6e932683f8201b1 /gcc/config/avr/avr.c
parentf8395d62c12586d9f50dd3486e7fe269b54927c2 (diff)
downloadgcc-eb6bb559981118ed95c4340fa32baf346a89b53e.zip
gcc-eb6bb559981118ed95c4340fa32baf346a89b53e.tar.gz
gcc-eb6bb559981118ed95c4340fa32baf346a89b53e.tar.bz2
avr.c (avr_default_expand_builtin): New function.
* config/avr/avr.c (avr_default_expand_builtin): New function. (avr_expand_builtin): Use it. (avr_expand_unop_builtin): Remove. (avr_expand_binop_builtin): Remove. (avr_expand_triop_builtin): Remove. From-SVN: r188670
Diffstat (limited to 'gcc/config/avr/avr.c')
-rw-r--r--gcc/config/avr/avr.c204
1 files changed, 45 insertions, 159 deletions
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index cd1a4af..70384c4 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -10329,8 +10329,8 @@ avr_init_builtin_int24 (void)
tree int24_type = make_signed_type (GET_MODE_BITSIZE (PSImode));
tree uint24_type = make_unsigned_type (GET_MODE_BITSIZE (PSImode));
- (*lang_hooks.types.register_builtin_type) (int24_type, "__int24");
- (*lang_hooks.types.register_builtin_type) (uint24_type, "__uint24");
+ lang_hooks.types.register_builtin_type (int24_type, "__int24");
+ lang_hooks.types.register_builtin_type (uint24_type, "__uint24");
}
@@ -10397,170 +10397,64 @@ avr_init_builtins (void)
}
-/* Subroutine of avr_expand_builtin to take care of unop insns. */
+/* Subroutine of avr_expand_builtin to expand vanilla builtins
+ with non-void result and 1 ... 3 arguments. */
static rtx
-avr_expand_unop_builtin (enum insn_code icode, tree exp,
- rtx target)
+avr_default_expand_builtin (enum insn_code icode, tree exp, rtx target)
{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
- enum machine_mode op0mode = GET_MODE (op0);
+ rtx pat, xop[3];
+ int n, n_args = call_expr_nargs (exp);
enum machine_mode tmode = insn_data[icode].operand[0].mode;
- enum machine_mode mode0 = insn_data[icode].operand[1].mode;
- if (! target
+ gcc_assert (n_args >= 1 && n_args <= 3);
+
+ if (target == NULL_RTX
|| GET_MODE (target) != tmode
- || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ || !insn_data[icode].operand[0].predicate (target, tmode))
{
target = gen_reg_rtx (tmode);
}
- if (op0mode == SImode && mode0 == HImode)
+ for (n = 0; n < n_args; n++)
{
- op0mode = HImode;
- op0 = gen_lowpart (HImode, op0);
- }
-
- gcc_assert (op0mode == mode0 || op0mode == VOIDmode);
+ tree arg = CALL_EXPR_ARG (exp, n);
+ rtx op = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ enum machine_mode opmode = GET_MODE (op);
+ enum machine_mode mode = insn_data[icode].operand[n+1].mode;
- if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
+ if ((opmode == SImode || opmode == VOIDmode) && mode == HImode)
+ {
+ opmode = HImode;
+ op = gen_lowpart (HImode, op);
+ }
- pat = GEN_FCN (icode) (target, op0);
- if (! pat)
- return 0;
-
- emit_insn (pat);
+ /* In case the insn wants input operands in modes different from
+ the result, abort. */
- return target;
-}
-
+ gcc_assert (opmode == mode || opmode == VOIDmode);
-/* Subroutine of avr_expand_builtin to take care of binop insns. */
-
-static rtx
-avr_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- tree arg1 = CALL_EXPR_ARG (exp, 1);
- rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
- rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
- enum machine_mode op0mode = GET_MODE (op0);
- enum machine_mode op1mode = GET_MODE (op1);
- enum machine_mode tmode = insn_data[icode].operand[0].mode;
- enum machine_mode mode0 = insn_data[icode].operand[1].mode;
- enum machine_mode mode1 = insn_data[icode].operand[2].mode;
+ if (!insn_data[icode].operand[n+1].predicate (op, mode))
+ op = copy_to_mode_reg (mode, op);
- if (! target
- || GET_MODE (target) != tmode
- || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
- {
- target = gen_reg_rtx (tmode);
+ xop[n] = op;
}
- if ((op0mode == SImode || op0mode == VOIDmode) && mode0 == HImode)
+ switch (n_args)
{
- op0mode = HImode;
- op0 = gen_lowpart (HImode, op0);
- }
-
- if ((op1mode == SImode || op1mode == VOIDmode) && mode1 == HImode)
- {
- op1mode = HImode;
- op1 = gen_lowpart (HImode, op1);
- }
-
- /* In case the insn wants input operands in modes different from
- the result, abort. */
-
- gcc_assert ((op0mode == mode0 || op0mode == VOIDmode)
- && (op1mode == mode1 || op1mode == VOIDmode));
-
- if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
-
- if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
- op1 = copy_to_mode_reg (mode1, op1);
+ case 1: pat = GEN_FCN (icode) (target, xop[0]); break;
+ case 2: pat = GEN_FCN (icode) (target, xop[0], xop[1]); break;
+ case 3: pat = GEN_FCN (icode) (target, xop[0], xop[1], xop[2]); break;
- pat = GEN_FCN (icode) (target, op0, op1);
-
- if (! pat)
- return 0;
-
- emit_insn (pat);
- return target;
-}
-
-/* Subroutine of avr_expand_builtin to take care of 3-operand insns. */
-
-static rtx
-avr_expand_triop_builtin (enum insn_code icode, tree exp, rtx target)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- tree arg1 = CALL_EXPR_ARG (exp, 1);
- tree arg2 = CALL_EXPR_ARG (exp, 2);
- rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
- rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
- rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, EXPAND_NORMAL);
- enum machine_mode op0mode = GET_MODE (op0);
- enum machine_mode op1mode = GET_MODE (op1);
- enum machine_mode op2mode = GET_MODE (op2);
- enum machine_mode tmode = insn_data[icode].operand[0].mode;
- enum machine_mode mode0 = insn_data[icode].operand[1].mode;
- enum machine_mode mode1 = insn_data[icode].operand[2].mode;
- enum machine_mode mode2 = insn_data[icode].operand[3].mode;
-
- if (! target
- || GET_MODE (target) != tmode
- || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
- {
- target = gen_reg_rtx (tmode);
- }
-
- if ((op0mode == SImode || op0mode == VOIDmode) && mode0 == HImode)
- {
- op0mode = HImode;
- op0 = gen_lowpart (HImode, op0);
- }
-
- if ((op1mode == SImode || op1mode == VOIDmode) && mode1 == HImode)
- {
- op1mode = HImode;
- op1 = gen_lowpart (HImode, op1);
- }
-
- if ((op2mode == SImode || op2mode == VOIDmode) && mode2 == HImode)
- {
- op2mode = HImode;
- op2 = gen_lowpart (HImode, op2);
+ default:
+ gcc_unreachable();
}
- /* In case the insn wants input operands in modes different from
- the result, abort. */
-
- gcc_assert ((op0mode == mode0 || op0mode == VOIDmode)
- && (op1mode == mode1 || op1mode == VOIDmode)
- && (op2mode == mode2 || op2mode == VOIDmode));
-
- if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
-
- if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
- op1 = copy_to_mode_reg (mode1, op1);
-
- if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
- op2 = copy_to_mode_reg (mode2, op2);
-
- pat = GEN_FCN (icode) (target, op0, op1, op2);
-
- if (! pat)
- return 0;
+ if (pat == NULL_RTX)
+ return NULL_RTX;
emit_insn (pat);
+
return target;
}
@@ -10579,7 +10473,7 @@ avr_expand_builtin (tree exp, rtx target,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- const char* bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
+ 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;
@@ -10603,7 +10497,7 @@ avr_expand_builtin (tree exp, rtx target,
else
avr_expand_delay_cycles (op0);
- return 0;
+ return NULL_RTX;
}
case AVR_BUILTIN_INSERT_BITS:
@@ -10621,24 +10515,16 @@ avr_expand_builtin (tree exp, rtx target,
}
/* No special treatment needed: vanilla expand. */
-
- switch (d->n_args)
+
+ gcc_assert (d->n_args == call_expr_nargs (exp));
+
+ if (d->n_args == 0)
{
- 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);
+ return NULL_RTX;
}
-
- gcc_unreachable ();
+
+ return avr_default_expand_builtin (d->icode, exp, target);
}