Commit 8a119a7d by Michael Hayes Committed by Michael Hayes

c4x.h (MD_INIT_BUILTINS, [...]): Define.

	* config/c4x/c4x.h (MD_INIT_BUILTINS, MD_EXPAND_BUILTIN): Define.

	* config/c4x/c4x-protos.h (c4x_init_builtins): New prototype.
	(c4x_expand_builtin): Likewise.

	* config/c4x/c4x.c (c4x_init_builtins): New function.
	(c4x_expand_builtin): Likewise.

	* config/c4x/c4x.md (floatunsqihf2): New pattern.
	(*floatqihf2_set, *fixhfqi_set, fix_trunchfqi2): Likewise.
	(fixuns_trunchfqi2, toieee, frieee, *ldhf_conditional): Likewise.
	(*ldhf_conditional_noov, movhfcc, trap, cond_trap_cc): Likewise.
	(*toieee_movqf_clobber, *frieee_movqf_clobber): Likewise.

Co-Authored-By: Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>

From-SVN: r38315
parent 66f77154
2000-12-17 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
* config/c4x/c4x.h (MD_INIT_BUILTINS, MD_EXPAND_BUILTIN): Define.
* config/c4x/c4x-protos.h (c4x_init_builtins): New prototype.
(c4x_expand_builtin): Likewise.
* config/c4x/c4x.c (c4x_init_builtins): New function.
(c4x_expand_builtin): Likewise.
* config/c4x/c4x.md (floatunsqihf2): New pattern.
(*floatqihf2_set, *fixhfqi_set, fix_trunchfqi2): Likewise.
(fixuns_trunchfqi2, toieee, frieee, *ldhf_conditional): Likewise.
(*ldhf_conditional_noov, movhfcc, trap, cond_trap_cc): Likewise.
(*toieee_movqf_clobber, *frieee_movqf_clobber): Likewise.
2000-12-17 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
* libgcc2.h: Use Wtype for SItype and DWtype for DItype in prototypes.
* libgcc2.c (__absvsi2): Use Wtype and DWtype.
......
......@@ -62,6 +62,7 @@ extern struct rtx_def *c4x_function_arg PARAMS ((CUMULATIVE_ARGS *,
extern void c4x_encode_section_info PARAMS ((tree));
extern int c4x_valid_type_attribute_p PARAMS ((tree, tree, tree, tree));
#endif /* TREE_CODE */
......@@ -71,6 +72,9 @@ extern void c4x_init_cumulative_args PARAMS ((CUMULATIVE_ARGS *c, tree, rtx));
extern void c4x_va_start PARAMS ((int, tree, rtx));
extern struct rtx_def *c4x_va_arg PARAMS ((tree, tree));
extern rtx c4x_expand_builtin PARAMS((tree, rtx, rtx,
enum machine_mode, int));
#endif /* TREE_CODE and RTX_CODE*/
......@@ -271,6 +275,8 @@ extern int valid_parallel_operands_5 PARAMS ((rtx *, enum machine_mode));
extern int valid_parallel_operands_6 PARAMS ((rtx *, enum machine_mode));
extern void c4x_init_builtins PARAMS((void));
extern rtx smulhi3_libfunc;
extern rtx umulhi3_libfunc;
extern rtx fix_truncqfhi2_libfunc;
......
......@@ -315,6 +315,7 @@ c4x_output_ascii (stream, ptr, len)
char sbuf[C4X_ASCII_LIMIT + 1];
int s, l, special, first, onlys;
first = 0;
if (len)
{
fprintf (stream, "\t.byte\t");
......@@ -4855,3 +4856,181 @@ c4x_adjust_cost (insn, link, dep_insn, cost)
else
abort ();
}
void
c4x_init_builtins ()
{
tree endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
builtin_function ("abs",
build_function_type
(integer_type_node,
tree_cons (NULL_TREE, integer_type_node, endlink)),
C4X_BUILTIN_ABS, BUILT_IN_MD, NULL_PTR);
builtin_function ("fabs",
build_function_type
(double_type_node,
tree_cons (NULL_TREE, double_type_node, endlink)),
C4X_BUILTIN_FABS, BUILT_IN_MD, NULL_PTR);
builtin_function ("labs",
build_function_type
(long_integer_type_node,
tree_cons (NULL_TREE, long_integer_type_node, endlink)),
C4X_BUILTIN_LABS, BUILT_IN_MD, NULL_PTR);
builtin_function ("fast_ftoi",
build_function_type
(integer_type_node,
tree_cons (NULL_TREE, double_type_node, endlink)),
C4X_BUILTIN_FIX, BUILT_IN_MD, NULL_PTR);
builtin_function ("ansi_ftoi",
build_function_type
(integer_type_node,
tree_cons (NULL_TREE, double_type_node, endlink)),
C4X_BUILTIN_FIX_ANSI, BUILT_IN_MD, NULL_PTR);
if (TARGET_C3X)
builtin_function ("fast_imult",
build_function_type
(integer_type_node,
tree_cons (NULL_TREE, integer_type_node,
tree_cons (NULL_TREE,
integer_type_node, endlink))),
C4X_BUILTIN_MPYI, BUILT_IN_MD, NULL_PTR);
else
{
builtin_function ("toieee",
build_function_type
(double_type_node,
tree_cons (NULL_TREE, double_type_node, endlink)),
C4X_BUILTIN_TOIEEE, BUILT_IN_MD, NULL_PTR);
builtin_function ("frieee",
build_function_type
(double_type_node,
tree_cons (NULL_TREE, double_type_node, endlink)),
C4X_BUILTIN_FRIEEE, BUILT_IN_MD, NULL_PTR);
builtin_function ("fast_invf",
build_function_type
(double_type_node,
tree_cons (NULL_TREE, double_type_node, endlink)),
C4X_BUILTIN_RCPF, BUILT_IN_MD, NULL_PTR);
}
}
rtx
c4x_expand_builtin (exp, target, subtarget, mode, ignore)
tree exp;
rtx target;
rtx subtarget ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
int ignore ATTRIBUTE_UNUSED;
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
tree arglist = TREE_OPERAND (exp, 1);
tree arg0, arg1;
rtx r0, r1;
switch (fcode)
{
case C4X_BUILTIN_ABS:
arg0 = TREE_VALUE (arglist);
r0 = expand_expr (arg0, NULL_RTX, QImode, 0);
r0 = protect_from_queue (r0, 0);
if (! target || ! register_operand (target, QImode))
target = gen_reg_rtx (QImode);
emit_insn (gen_absqi2 (target, r0));
return target;
case C4X_BUILTIN_FABS:
arg0 = TREE_VALUE (arglist);
r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
r0 = protect_from_queue (r0, 0);
if (! target || ! register_operand (target, QFmode))
target = gen_reg_rtx (QFmode);
emit_insn (gen_absqf2 (target, r0));
return target;
case C4X_BUILTIN_LABS:
arg0 = TREE_VALUE (arglist);
r0 = expand_expr (arg0, NULL_RTX, QImode, 0);
r0 = protect_from_queue (r0, 0);
if (! target || ! register_operand (target, QImode))
target = gen_reg_rtx (QImode);
emit_insn (gen_absqi2 (target, r0));
return target;
case C4X_BUILTIN_FIX:
arg0 = TREE_VALUE (arglist);
r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
r0 = protect_from_queue (r0, 0);
if (! target || ! register_operand (target, QImode))
target = gen_reg_rtx (QImode);
emit_insn (gen_fixqfqi_clobber (target, r0));
return target;
case C4X_BUILTIN_FIX_ANSI:
arg0 = TREE_VALUE (arglist);
r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
r0 = protect_from_queue (r0, 0);
if (! target || ! register_operand (target, QImode))
target = gen_reg_rtx (QImode);
emit_insn (gen_fix_truncqfqi2 (target, r0));
return target;
case C4X_BUILTIN_MPYI:
if (! TARGET_C3X)
break;
arg0 = TREE_VALUE (arglist);
arg1 = TREE_VALUE (TREE_CHAIN (arglist));
r0 = expand_expr (arg0, NULL_RTX, QImode, 0);
r1 = expand_expr (arg1, NULL_RTX, QImode, 0);
r0 = protect_from_queue (r0, 0);
r1 = protect_from_queue (r1, 0);
if (! target || ! register_operand (target, QImode))
target = gen_reg_rtx (QImode);
emit_insn (gen_mulqi3_24_clobber (target, r0, r1));
return target;
case C4X_BUILTIN_TOIEEE:
if (TARGET_C3X)
break;
arg0 = TREE_VALUE (arglist);
r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
r0 = protect_from_queue (r0, 0);
if (! target || ! register_operand (target, QFmode))
target = gen_reg_rtx (QFmode);
emit_insn (gen_toieee (target, r0));
return target;
case C4X_BUILTIN_FRIEEE:
if (TARGET_C3X)
break;
arg0 = TREE_VALUE (arglist);
if (TREE_CODE (arg0) == VAR_DECL || TREE_CODE (arg0) == PARM_DECL)
put_var_into_stack (arg0);
r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
r0 = protect_from_queue (r0, 0);
if (register_operand (r0, QFmode))
{
r1 = assign_stack_local (QFmode, GET_MODE_SIZE (QFmode), 0);
emit_move_insn (r1, r0);
r0 = r1;
}
if (! target || ! register_operand (target, QFmode))
target = gen_reg_rtx (QFmode);
emit_insn (gen_frieee (target, r0));
return target;
case C4X_BUILTIN_RCPF:
if (TARGET_C3X)
break;
arg0 = TREE_VALUE (arglist);
r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
r0 = protect_from_queue (r0, 0);
if (! target || ! register_operand (target, QFmode))
target = gen_reg_rtx (QFmode);
emit_insn (gen_rcpfqf_clobber (target, r0));
return target;
}
return NULL_RTX;
}
......@@ -2609,7 +2609,7 @@ do { fprintf (asm_out_file, "\t.sdef\t"); \
/* MOVE_RATIO is the number of move instructions that is better than a
block move. */
#define MOVE_RATIO 2 /* Default value. */
#define MOVE_RATIO 3
#define BSS_SECTION_ASM_OP "\t.bss"
......@@ -2642,7 +2642,10 @@ do { fprintf (asm_out_file, "\t.sdef\t"); \
if (final_sequence != NULL_RTX) \
{ \
int count; \
int laj = GET_CODE (XVECEXP (final_sequence, 0, 0)) == CALL_INSN; \
rtx insn = XVECEXP (final_sequence, 0, 0); \
int laj = GET_CODE (insn) == CALL_INSN \
|| (GET_CODE (insn) == INSN \
&& GET_CODE (PATTERN (insn)) == TRAP_IF);\
\
count = dbr_sequence_length(); \
while (count < (laj ? 2 : 3)) \
......@@ -2692,3 +2695,27 @@ if (final_sequence != NULL_RTX) \
{"parallel_operand", {SUBREG, REG, MEM}}, \
{"symbolic_address_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \
{"mem_operand", {MEM}},
/* Define the intrinsic functions for the c3x/c4x. */
enum c4x_builtins
{
/* intrinsic name */
C4X_BUILTIN_ABS, /* abs */
C4X_BUILTIN_FABS, /* fabs */
C4X_BUILTIN_LABS, /* labs */
C4X_BUILTIN_FIX, /* fast_ftoi */
C4X_BUILTIN_FIX_ANSI, /* ansi_ftoi */
C4X_BUILTIN_MPYI, /* fast_imult (only C3x) */
C4X_BUILTIN_TOIEEE, /* toieee (only C4x) */
C4X_BUILTIN_FRIEEE, /* frieee (only C4x) */
C4X_BUILTIN_RCPF /* fast_invf (only C4x) */
};
#define MD_INIT_BUILTINS do { \
c4x_init_builtins (); \
} while (0)
#define MD_EXPAND_BUILTIN(EXP, TARGET, SUBTARGET, MODE, IGNORE) \
c4x_expand_builtin ((EXP), (TARGET), (SUBTARGET), (MODE), (IGNORE))
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