mips-dsp.md: New file.

* config/mips/mips-dsp.md: New file.
	* config/mips/mips-modes.def (V4QI, V2HI, CCDSP): New modes.
	* config/mips/mips.c (mips_function_type): Add types for DSP builtin
	functions.
	(mips_builtin_type): Add MIPS_BUILTIN_DIRECT_NO_TARGET and
	MIPS_BUILTIN_BPOSGE32.
	(mips_expand_builtin_direct): Add one parameter to indicate that
	builtin functions need to return a value.
	(mips_expand_builtin_bposge): New for expanding "bposge" builtin
	functions.
	(mips_regno_to_class): Add classes for 12 new DSP registers.
	(mips_subword): Change to check four HI registers.
	(mips_output_move): Output move to and from 6 new DSP accumulators.
	(override_options): Make sure -mdsp and -mips16 are not used together.
	Map 'A' to DSP_ACC_REGS and 'a' to ACC_REGS.  Enable DSP accumulators
	for machine modes.
	(mips_conditional_register_usage): Disable 6 new DSP accumulators
	when !TARGET_DSP.
	(print_operand): Add 'q' for printing DSP accumulators.
	(mips_cannot_change_mode_class): Check ACC_REGS.
	(mips_secondary_reload_class): Check ACC_REGS.
	(mips_vector_mode_supported_p): Enable V2HI and V4QI when TARGET_DSP.
	(mips_register_move_cost): Check ACC_REGS.
	(CODE_FOR_mips_addq_ph, CODE_FOR_mips_addu_qb, CODE_FOR_mips_subq_ph)
	(CODE_FOR_mips_subu_qb): New code-aliasing macros.
	(DIRECT_NO_TARGET_BUILTIN, BPOSGE_BUILTIN): New macros.
	(dsp_bdesc): New array.
	(bdesc_arrays): Add DSP builtin function table.
	(mips_prepare_builtin_arg): Check predicate again after
	copy_to_mode_reg.
	(mips_expand_builtin): Add one more parameter to
	mips_expand_builtin_direct. Expand MIPS_BUILTIN_DIRECT_NO_TARGET and
	MIPS_BUILTIN_BPOSGE32.
	(mips_init_builtins): Initialize new function types.
	(mips_expand_builtin_direct): Check if builtin functions need to
	return a value and pass operands properly.
	(mips_expand_builtin_bposge): New function.
	* config/mips/mips.h (TARGET_CPU_CPP_BUILTINS): Add __mips_dsp.
	(ASM_SPEC): Map -mdsp to -mdsp in GAS.
	(FIRST_PSEUDO_REGISTER): Increase to 188.
	(FIXED_REGISTERS, CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS):
	Update for 12 new DSP registers.
	(DSP_ACC_REG_FIRST, DSP_ACC_REG_LAST, DSP_ACC_REG_NUM, AC1HI_REGNUM)
	(AC1LO_REGNUM, AC2HI_REGNUM, AC2LO_REGNUM, AC3HI_REGNUM, AC3LO_REGNUM):
	(DSP_ACC_REG_P, ACC_REG_P, ACC_HI_REG_P): New macros.
	(reg_class): Add DSP_ACC_REGS and ACC_REGS.
	(REG_CLASS_NAMES): Add names for DSP_ACC_REGS and ACC_REGS.
	(REG_CLASS_CONTENTS): Update for DSP_ACC_REGS, ACC_REGS and ALL_REGS.
	(REG_ALLOC_ORDER): Update for 12 new DSP registers.
	(mips_char_to_class): Add 'A' for DSP_ACC_REGS and 'a' for ACC_REGS.
	(UIMM6_OPERAND, IMM10_OPERAND): New macros.
	(EXTRA_CONSTRAINT_Y): Add YA and YB extra constraints.
	(REGISTER_NAMES): Add names for 12 new DSP registers.
	* config/mips/mips.md: Include mips-dsp.md.
	(UNSPEC_ADDQ, UNSPEC_ADDQ_S, UNSPEC_SUBQ, UNSPEC_SUBQ_S, UNSPEC_ADDSC)
	(UNSPEC_ADDWC, UNSPEC_MODSUB, UNSPEC_RADDU_W_QB, UNSPEC_ABSQ_S)
	(UNSPEC_PRECRQ_QB_PH, UNSPEC_PRECRQ_PH_W, UNSPEC_PRECRQ_RS_PH_W)
	(UNSPEC_PRECRQU_S_QB_PH, UNSPEC_PRECEQ_W_PHL, UNSPEC_PRECEQ_W_PHR)
	(UNSPEC_PRECEQU_PH_QBL, UNSPEC_PRECEQU_PH_QBR, UNSPEC_PRECEQU_PH_QBLA)
	(UNSPEC_PRECEQU_PH_QBRA, UNSPEC_PRECEU_PH_QBL, UNSPEC_PRECEU_PH_QBR)
	(UNSPEC_PRECEU_PH_QBLA, UNSPEC_PRECEU_PH_QBRA, UNSPEC_SHLL)
	(UNSPEC_SHLL_S, UNSPEC_SHRL_QB, UNSPEC_SHRA_PH, UNSPEC_SHRA_R)
	(UNSPEC_MULEU_S_PH_QBL, UNSPEC_MULEU_S_PH_QBR, UNSPEC_MULQ_RS_PH)
	(UNSPEC_MULEQ_S_W_PHL, UNSPEC_MULEQ_S_W_PHR, UNSPEC_DPAU_H_QBL)
	(UNSPEC_DPAU_H_QBR, UNSPEC_DPSU_H_QBL, UNSPEC_DPSU_H_QBR)
	(UNSPEC_DPAQ_S_W_PH, UNSPEC_DPSQ_S_W_PH, UNSPEC_MULSAQ_S_W_PH)
	(UNSPEC_DPAQ_SA_L_W, UNSPEC_DPSQ_SA_L_W, UNSPEC_MAQ_S_W_PHL)
	(UNSPEC_MAQ_S_W_PHR, UNSPEC_MAQ_SA_W_PHL, UNSPEC_MAQ_SA_W_PHR)
	(UNSPEC_BITREV, UNSPEC_INSV, UNSPEC_REPL_QB, UNSPEC_REPL_PH)
	(UNSPEC_CMP_EQ, UNSPEC_CMP_LT, UNSPEC_CMP_LE, UNSPEC_CMPGU_EQ_QB)
	(UNSPEC_CMPGU_LT_QB, UNSPEC_CMPGU_LE_QB, UNSPEC_PICK, UNSPEC_PACKRL_PH)
	(UNSPEC_EXTR_W, UNSPEC_EXTR_R_W, UNSPEC_EXTR_RS_W, UNSPEC_EXTR_S_H)
	(UNSPEC_EXTP, UNSPEC_EXTPDP, UNSPEC_SHILO, UNSPEC_MTHLIP, UNSPEC_WRDSP)
	(UNSPEC_RDDSP): New constants.
	(*movdi_32bit): Change 'x' to 'a' for ACC_REGS.
	(*movsi_internal): Change 'x' to 'a' for ACC_REGS.  Add an
	A<-d alternative.
	* config/mips/mips.opt (-mdsp): New option.
	* config/mips/predicates.md (const_uimm6_operand, const_imm10_operand)
	(reg_imm10_operand): New predicates.
	* doc/extend.texi (MIPS DSP Built-in Functions): New section.
	* doc/invoke.texi (-mdsp): Document new option.

From-SVN: r102307
This commit is contained in:
Chao-ying Fu 2005-07-23 08:36:54 +00:00 committed by Richard Sandiford
parent 5887a1bb9c
commit 118ea79312
13 changed files with 3154 additions and 92 deletions

View file

@ -1,3 +1,88 @@
2005-07-23 Chao-ying Fu <fu@mips.com>
* config/mips/mips-dsp.md: New file.
* config/mips/mips-modes.def (V4QI, V2HI, CCDSP): New modes.
* config/mips/mips.c (mips_function_type): Add types for DSP builtin
functions.
(mips_builtin_type): Add MIPS_BUILTIN_DIRECT_NO_TARGET and
MIPS_BUILTIN_BPOSGE32.
(mips_expand_builtin_direct): Add one parameter to indicate that
builtin functions need to return a value.
(mips_expand_builtin_bposge): New for expanding "bposge" builtin
functions.
(mips_regno_to_class): Add classes for 12 new DSP registers.
(mips_subword): Change to check four HI registers.
(mips_output_move): Output move to and from 6 new DSP accumulators.
(override_options): Make sure -mdsp and -mips16 are not used together.
Map 'A' to DSP_ACC_REGS and 'a' to ACC_REGS. Enable DSP accumulators
for machine modes.
(mips_conditional_register_usage): Disable 6 new DSP accumulators
when !TARGET_DSP.
(print_operand): Add 'q' for printing DSP accumulators.
(mips_cannot_change_mode_class): Check ACC_REGS.
(mips_secondary_reload_class): Check ACC_REGS.
(mips_vector_mode_supported_p): Enable V2HI and V4QI when TARGET_DSP.
(mips_register_move_cost): Check ACC_REGS.
(CODE_FOR_mips_addq_ph, CODE_FOR_mips_addu_qb, CODE_FOR_mips_subq_ph)
(CODE_FOR_mips_subu_qb): New code-aliasing macros.
(DIRECT_NO_TARGET_BUILTIN, BPOSGE_BUILTIN): New macros.
(dsp_bdesc): New array.
(bdesc_arrays): Add DSP builtin function table.
(mips_prepare_builtin_arg): Check predicate again after
copy_to_mode_reg.
(mips_expand_builtin): Add one more parameter to
mips_expand_builtin_direct. Expand MIPS_BUILTIN_DIRECT_NO_TARGET and
MIPS_BUILTIN_BPOSGE32.
(mips_init_builtins): Initialize new function types.
(mips_expand_builtin_direct): Check if builtin functions need to
return a value and pass operands properly.
(mips_expand_builtin_bposge): New function.
* config/mips/mips.h (TARGET_CPU_CPP_BUILTINS): Add __mips_dsp.
(ASM_SPEC): Map -mdsp to -mdsp in GAS.
(FIRST_PSEUDO_REGISTER): Increase to 188.
(FIXED_REGISTERS, CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS):
Update for 12 new DSP registers.
(DSP_ACC_REG_FIRST, DSP_ACC_REG_LAST, DSP_ACC_REG_NUM, AC1HI_REGNUM)
(AC1LO_REGNUM, AC2HI_REGNUM, AC2LO_REGNUM, AC3HI_REGNUM, AC3LO_REGNUM):
(DSP_ACC_REG_P, ACC_REG_P, ACC_HI_REG_P): New macros.
(reg_class): Add DSP_ACC_REGS and ACC_REGS.
(REG_CLASS_NAMES): Add names for DSP_ACC_REGS and ACC_REGS.
(REG_CLASS_CONTENTS): Update for DSP_ACC_REGS, ACC_REGS and ALL_REGS.
(REG_ALLOC_ORDER): Update for 12 new DSP registers.
(mips_char_to_class): Add 'A' for DSP_ACC_REGS and 'a' for ACC_REGS.
(UIMM6_OPERAND, IMM10_OPERAND): New macros.
(EXTRA_CONSTRAINT_Y): Add YA and YB extra constraints.
(REGISTER_NAMES): Add names for 12 new DSP registers.
* config/mips/mips.md: Include mips-dsp.md.
(UNSPEC_ADDQ, UNSPEC_ADDQ_S, UNSPEC_SUBQ, UNSPEC_SUBQ_S, UNSPEC_ADDSC)
(UNSPEC_ADDWC, UNSPEC_MODSUB, UNSPEC_RADDU_W_QB, UNSPEC_ABSQ_S)
(UNSPEC_PRECRQ_QB_PH, UNSPEC_PRECRQ_PH_W, UNSPEC_PRECRQ_RS_PH_W)
(UNSPEC_PRECRQU_S_QB_PH, UNSPEC_PRECEQ_W_PHL, UNSPEC_PRECEQ_W_PHR)
(UNSPEC_PRECEQU_PH_QBL, UNSPEC_PRECEQU_PH_QBR, UNSPEC_PRECEQU_PH_QBLA)
(UNSPEC_PRECEQU_PH_QBRA, UNSPEC_PRECEU_PH_QBL, UNSPEC_PRECEU_PH_QBR)
(UNSPEC_PRECEU_PH_QBLA, UNSPEC_PRECEU_PH_QBRA, UNSPEC_SHLL)
(UNSPEC_SHLL_S, UNSPEC_SHRL_QB, UNSPEC_SHRA_PH, UNSPEC_SHRA_R)
(UNSPEC_MULEU_S_PH_QBL, UNSPEC_MULEU_S_PH_QBR, UNSPEC_MULQ_RS_PH)
(UNSPEC_MULEQ_S_W_PHL, UNSPEC_MULEQ_S_W_PHR, UNSPEC_DPAU_H_QBL)
(UNSPEC_DPAU_H_QBR, UNSPEC_DPSU_H_QBL, UNSPEC_DPSU_H_QBR)
(UNSPEC_DPAQ_S_W_PH, UNSPEC_DPSQ_S_W_PH, UNSPEC_MULSAQ_S_W_PH)
(UNSPEC_DPAQ_SA_L_W, UNSPEC_DPSQ_SA_L_W, UNSPEC_MAQ_S_W_PHL)
(UNSPEC_MAQ_S_W_PHR, UNSPEC_MAQ_SA_W_PHL, UNSPEC_MAQ_SA_W_PHR)
(UNSPEC_BITREV, UNSPEC_INSV, UNSPEC_REPL_QB, UNSPEC_REPL_PH)
(UNSPEC_CMP_EQ, UNSPEC_CMP_LT, UNSPEC_CMP_LE, UNSPEC_CMPGU_EQ_QB)
(UNSPEC_CMPGU_LT_QB, UNSPEC_CMPGU_LE_QB, UNSPEC_PICK, UNSPEC_PACKRL_PH)
(UNSPEC_EXTR_W, UNSPEC_EXTR_R_W, UNSPEC_EXTR_RS_W, UNSPEC_EXTR_S_H)
(UNSPEC_EXTP, UNSPEC_EXTPDP, UNSPEC_SHILO, UNSPEC_MTHLIP, UNSPEC_WRDSP)
(UNSPEC_RDDSP): New constants.
(*movdi_32bit): Change 'x' to 'a' for ACC_REGS.
(*movsi_internal): Change 'x' to 'a' for ACC_REGS. Add an
A<-d alternative.
* config/mips/mips.opt (-mdsp): New option.
* config/mips/predicates.md (const_uimm6_operand, const_imm10_operand)
(reg_imm10_operand): New predicates.
* doc/extend.texi (MIPS DSP Built-in Functions): New section.
* doc/invoke.texi (-mdsp): Document new option.
2005-07-22 DJ Delorie <dj@redhat.com>
* c-objc-common.c (c_cannot_inline_tree_fn): Add warning control

1058
gcc/config/mips/mips-dsp.md Normal file

File diff suppressed because it is too large Load diff

View file

@ -28,6 +28,7 @@ FLOAT_MODE (TF, 16, mips_quad_format);
/* Vector modes. */
VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */
VECTOR_MODES (INT, 4); /* V4QI V2HI */
/* Paired single comparison instructions use 2 or 4 CC. */
CC_MODE (CCV2);
@ -37,3 +38,6 @@ ADJUST_ALIGNMENT (CCV2, 8);
CC_MODE (CCV4);
ADJUST_BYTESIZE (CCV4, 16);
ADJUST_ALIGNMENT (CCV4, 16);
/* For MIPS DSP control registers. */
CC_MODE (CCDSP);

View file

@ -150,6 +150,35 @@ enum mips_function_type
MIPS_DF_FTYPE_DF,
MIPS_DF_FTYPE_DF_DF,
/* For MIPS DSP ASE */
MIPS_DI_FTYPE_DI_SI,
MIPS_DI_FTYPE_DI_SI_SI,
MIPS_DI_FTYPE_DI_V2HI_V2HI,
MIPS_DI_FTYPE_DI_V4QI_V4QI,
MIPS_SI_FTYPE_DI_SI,
MIPS_SI_FTYPE_PTR_SI,
MIPS_SI_FTYPE_SI,
MIPS_SI_FTYPE_SI_SI,
MIPS_SI_FTYPE_V2HI,
MIPS_SI_FTYPE_V2HI_V2HI,
MIPS_SI_FTYPE_V4QI,
MIPS_SI_FTYPE_V4QI_V4QI,
MIPS_SI_FTYPE_VOID,
MIPS_V2HI_FTYPE_SI,
MIPS_V2HI_FTYPE_SI_SI,
MIPS_V2HI_FTYPE_V2HI,
MIPS_V2HI_FTYPE_V2HI_SI,
MIPS_V2HI_FTYPE_V2HI_V2HI,
MIPS_V2HI_FTYPE_V4QI,
MIPS_V2HI_FTYPE_V4QI_V2HI,
MIPS_V4QI_FTYPE_SI,
MIPS_V4QI_FTYPE_V2HI_V2HI,
MIPS_V4QI_FTYPE_V4QI_SI,
MIPS_V4QI_FTYPE_V4QI_V4QI,
MIPS_VOID_FTYPE_SI_SI,
MIPS_VOID_FTYPE_V2HI_V2HI,
MIPS_VOID_FTYPE_V4QI_V4QI,
/* The last type. */
MIPS_MAX_FTYPE_MAX
};
@ -162,6 +191,10 @@ enum mips_builtin_type
operands 1 and above. */
MIPS_BUILTIN_DIRECT,
/* The builtin corresponds directly to an .md pattern. There is no return
value and the arguments are mapped to operands 0 and above. */
MIPS_BUILTIN_DIRECT_NO_TARGET,
/* The builtin corresponds to a comparison instruction followed by
a mips_cond_move_tf_ps pattern. The first two arguments are the
values to compare and the second two arguments are the vector
@ -185,7 +218,10 @@ enum mips_builtin_type
MIPS_BUILTIN_CMP_LOWER,
/* As above, but the instruction only sets a single $fcc register. */
MIPS_BUILTIN_CMP_SINGLE
MIPS_BUILTIN_CMP_SINGLE,
/* For generating bposge32 branch instructions in MIPS32 DSP ASE. */
MIPS_BUILTIN_BPOSGE32
};
/* Invokes MACRO (COND) for each c.cond.fmt condition. */
@ -362,13 +398,14 @@ static rtx mips_prepare_builtin_arg (enum insn_code, unsigned int, tree *);
static rtx mips_prepare_builtin_target (enum insn_code, unsigned int, rtx);
static rtx mips_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
static void mips_init_builtins (void);
static rtx mips_expand_builtin_direct (enum insn_code, rtx, tree);
static rtx mips_expand_builtin_direct (enum insn_code, rtx, tree, bool);
static rtx mips_expand_builtin_movtf (enum mips_builtin_type,
enum insn_code, enum mips_fp_condition,
rtx, tree);
static rtx mips_expand_builtin_compare (enum mips_builtin_type,
enum insn_code, enum mips_fp_condition,
rtx, tree);
static rtx mips_expand_builtin_bposge (enum mips_builtin_type, rtx);
/* Structure to be filled in by compute_frame_size with register
save masks, and offsets for the current function. */
@ -644,7 +681,10 @@ const enum reg_class mips_regno_to_class[] =
COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS
COP3_REGS, COP3_REGS, COP3_REGS, COP3_REGS,
DSP_ACC_REGS, DSP_ACC_REGS, DSP_ACC_REGS, DSP_ACC_REGS,
DSP_ACC_REGS, DSP_ACC_REGS, ALL_REGS, ALL_REGS,
ALL_REGS, ALL_REGS, ALL_REGS, ALL_REGS
};
/* Map register constraint character to register class. */
@ -2608,8 +2648,8 @@ mips_subword (rtx op, int high_p)
{
if (FP_REG_P (REGNO (op)))
return gen_rtx_REG (word_mode, high_p ? REGNO (op) + 1 : REGNO (op));
if (REGNO (op) == HI_REGNUM)
return gen_rtx_REG (word_mode, high_p ? HI_REGNUM : LO_REGNUM);
if (ACC_HI_REG_P (REGNO (op)))
return gen_rtx_REG (word_mode, high_p ? REGNO (op) : REGNO (op) + 1);
}
if (MEM_P (op))
@ -2723,6 +2763,14 @@ mips_output_move (rtx dest, rtx src)
if (MD_REG_P (REGNO (dest)))
return "mt%0\t%z1";
if (DSP_ACC_REG_P (REGNO (dest)))
{
static char retval[] = "mt__\t%z1,%q0";
retval[2] = reg_names[REGNO (dest)][4];
retval[3] = reg_names[REGNO (dest)][5];
return retval;
}
if (FP_REG_P (REGNO (dest)))
return (dbl_p ? "dmtc1\t%z1,%0" : "mtc1\t%z1,%0");
@ -2741,6 +2789,14 @@ mips_output_move (rtx dest, rtx src)
{
if (src_code == REG)
{
if (DSP_ACC_REG_P (REGNO (src)))
{
static char retval[] = "mf__\t%0,%q1";
retval[2] = reg_names[REGNO (src)][4];
retval[3] = reg_names[REGNO (src)][5];
return retval;
}
if (ST_REG_P (REGNO (src)) && ISA_HAS_8CC)
return "lui\t%0,0x3f80\n\tmovf\t%0,%.,%1";
@ -4722,6 +4778,9 @@ override_options (void)
if (TARGET_PAIRED_SINGLE_FLOAT && !ISA_MIPS64)
error ("-mips3d/-mpaired-single must be used with -mips64");
if (TARGET_MIPS16 && TARGET_DSP)
error ("-mips16 and -mdsp cannot be used together");
mips_print_operand_punct['?'] = 1;
mips_print_operand_punct['#'] = 1;
mips_print_operand_punct['/'] = 1;
@ -4761,6 +4820,8 @@ override_options (void)
mips_char_to_class['B'] = COP0_REGS;
mips_char_to_class['C'] = COP2_REGS;
mips_char_to_class['D'] = COP3_REGS;
mips_char_to_class['A'] = DSP_ACC_REGS;
mips_char_to_class['a'] = ACC_REGS;
/* Set up array to map GCC register number to debug register number.
Ignore the special purpose register numbers. */
@ -4826,10 +4887,10 @@ override_options (void)
/* Allow TFmode for CCmode reloads. */
|| (ISA_HAS_8CC && mode == TFmode));
else if (MD_REG_P (regno))
else if (ACC_REG_P (regno))
temp = (INTEGRAL_MODE_P (mode)
&& (size <= UNITS_PER_WORD
|| (regno == MD_REG_FIRST
|| (ACC_HI_REG_P (regno)
&& size == 2 * UNITS_PER_WORD)));
else if (ALL_COP_REG_P (regno))
@ -4978,6 +5039,13 @@ override_options (void)
void
mips_conditional_register_usage (void)
{
if (!TARGET_DSP)
{
int regno;
for (regno = DSP_ACC_REG_FIRST; regno <= DSP_ACC_REG_LAST; regno++)
fixed_regs[regno] = call_used_regs[regno] = 1;
}
if (!TARGET_HARD_FLOAT)
{
int regno;
@ -5122,6 +5190,7 @@ mips_debugger_offset (rtx addr, HOST_WIDE_INT offset)
'Y' for a CONST_INT X, print mips_fp_conditions[X]
'Z' print the operand and a comma for ISA_HAS_8CC, otherwise print nothing
'R' print the reloc associated with LO_SUM
'q' print DSP accumulator registers
The punctuation characters are:
@ -5372,6 +5441,22 @@ print_operand (FILE *file, rtx op, int letter)
}
}
else if (letter == 'q')
{
int regnum;
if (code != REG)
fatal_insn ("PRINT_OPERAND, invalid insn for %%q", op);
regnum = REGNO (op);
if (MD_REG_P (regnum))
fprintf (file, "$ac0");
else if (DSP_ACC_REG_P (regnum))
fprintf (file, "$ac%c", reg_names[regnum][3]);
else
fatal_insn ("PRINT_OPERAND, invalid insn for %%q", op);
}
else if (code == REG || code == SUBREG)
{
register int regnum;
@ -7316,8 +7401,10 @@ mips_cannot_change_mode_class (enum machine_mode from,
/* LO_REGNO == HI_REGNO + 1, so if a multi-word value is stored
in LO and HI, the high word always comes first. We therefore
can't allow values stored in HI to change between single-word
and multi-word modes. */
if (reg_classes_intersect_p (HI_REG, class))
and multi-word modes.
This rule applies to both the original HI/LO pair and the new
DSP accumulators. */
if (reg_classes_intersect_p (ACC_REGS, class))
return true;
}
}
@ -7398,8 +7485,10 @@ mips_secondary_reload_class (enum reg_class class,
}
/* Copying from HI or LO to anywhere other than a general register
requires a general register. */
if (class == HI_REG || class == LO_REG || class == MD_REGS)
requires a general register.
This rule applies to both the original HI/LO pair and the new
DSP accumulators. */
if (reg_class_subset_p (class, ACC_REGS))
{
if (TARGET_MIPS16 && in_p)
{
@ -7408,7 +7497,7 @@ mips_secondary_reload_class (enum reg_class class,
}
return gp_reg_p ? NO_REGS : gr_regs;
}
if (MD_REG_P (regno))
if (ACC_REG_P (regno))
{
if (TARGET_MIPS16 && ! in_p)
{
@ -7519,10 +7608,18 @@ mips_valid_pointer_mode (enum machine_mode mode)
static bool
mips_vector_mode_supported_p (enum machine_mode mode)
{
if (mode == V2SFmode && TARGET_PAIRED_SINGLE_FLOAT)
return true;
else
return false;
switch (mode)
{
case V2SFmode:
return TARGET_PAIRED_SINGLE_FLOAT;
case V2HImode:
case V4QImode:
return TARGET_DSP;
default:
return false;
}
}
/* If we can access small data directly (using gp-relative relocation
@ -8887,7 +8984,7 @@ mips_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
}
else if (to == FP_REGS)
return 4;
else if (to == HI_REG || to == LO_REG || to == MD_REGS)
else if (reg_class_subset_p (to, ACC_REGS))
{
if (TARGET_MIPS16)
return 12;
@ -8908,7 +9005,7 @@ mips_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
else if (to == ST_REGS)
return 8;
}
else if (from == HI_REG || from == LO_REG || from == MD_REGS)
else if (reg_class_subset_p (from, ACC_REGS))
{
if (GR_REG_CLASS_P (to))
{
@ -9910,6 +10007,116 @@ static const struct builtin_description sb1_bdesc[] =
DIRECT_BUILTIN (sqrt_ps, MIPS_V2SF_FTYPE_V2SF, MASK_PAIRED_SINGLE_FLOAT)
};
/* Builtin functions for DSP ASE. */
#define CODE_FOR_mips_addq_ph CODE_FOR_addv2hi3
#define CODE_FOR_mips_addu_qb CODE_FOR_addv4qi3
#define CODE_FOR_mips_subq_ph CODE_FOR_subv2hi3
#define CODE_FOR_mips_subu_qb CODE_FOR_subv4qi3
/* Define a MIPS_BUILTIN_DIRECT_NO_TARGET function for instruction
CODE_FOR_mips_<INSN>. FUNCTION_TYPE and TARGET_FLAGS are
builtin_description fields. */
#define DIRECT_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE, TARGET_FLAGS) \
{ CODE_FOR_mips_ ## INSN, 0, "__builtin_mips_" #INSN, \
MIPS_BUILTIN_DIRECT_NO_TARGET, FUNCTION_TYPE, TARGET_FLAGS }
/* Define __builtin_mips_bposge<VALUE>. <VALUE> is 32 for the MIPS32 DSP
branch instruction. TARGET_FLAGS is a builtin_description field. */
#define BPOSGE_BUILTIN(VALUE, TARGET_FLAGS) \
{ CODE_FOR_mips_bposge, 0, "__builtin_mips_bposge" #VALUE, \
MIPS_BUILTIN_BPOSGE ## VALUE, MIPS_SI_FTYPE_VOID, TARGET_FLAGS }
static const struct builtin_description dsp_bdesc[] =
{
DIRECT_BUILTIN (addq_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (addq_s_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (addq_s_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
DIRECT_BUILTIN (addu_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
DIRECT_BUILTIN (addu_s_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
DIRECT_BUILTIN (subq_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (subq_s_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (subq_s_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
DIRECT_BUILTIN (subu_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
DIRECT_BUILTIN (subu_s_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
DIRECT_BUILTIN (addsc, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
DIRECT_BUILTIN (addwc, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
DIRECT_BUILTIN (modsub, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
DIRECT_BUILTIN (raddu_w_qb, MIPS_SI_FTYPE_V4QI, MASK_DSP),
DIRECT_BUILTIN (absq_s_ph, MIPS_V2HI_FTYPE_V2HI, MASK_DSP),
DIRECT_BUILTIN (absq_s_w, MIPS_SI_FTYPE_SI, MASK_DSP),
DIRECT_BUILTIN (precrq_qb_ph, MIPS_V4QI_FTYPE_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (precrq_ph_w, MIPS_V2HI_FTYPE_SI_SI, MASK_DSP),
DIRECT_BUILTIN (precrq_rs_ph_w, MIPS_V2HI_FTYPE_SI_SI, MASK_DSP),
DIRECT_BUILTIN (precrqu_s_qb_ph, MIPS_V4QI_FTYPE_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (preceq_w_phl, MIPS_SI_FTYPE_V2HI, MASK_DSP),
DIRECT_BUILTIN (preceq_w_phr, MIPS_SI_FTYPE_V2HI, MASK_DSP),
DIRECT_BUILTIN (precequ_ph_qbl, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
DIRECT_BUILTIN (precequ_ph_qbr, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
DIRECT_BUILTIN (precequ_ph_qbla, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
DIRECT_BUILTIN (precequ_ph_qbra, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
DIRECT_BUILTIN (preceu_ph_qbl, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
DIRECT_BUILTIN (preceu_ph_qbr, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
DIRECT_BUILTIN (preceu_ph_qbla, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
DIRECT_BUILTIN (preceu_ph_qbra, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
DIRECT_BUILTIN (shll_qb, MIPS_V4QI_FTYPE_V4QI_SI, MASK_DSP),
DIRECT_BUILTIN (shll_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
DIRECT_BUILTIN (shll_s_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
DIRECT_BUILTIN (shll_s_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
DIRECT_BUILTIN (shrl_qb, MIPS_V4QI_FTYPE_V4QI_SI, MASK_DSP),
DIRECT_BUILTIN (shra_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
DIRECT_BUILTIN (shra_r_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
DIRECT_BUILTIN (shra_r_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
DIRECT_BUILTIN (muleu_s_ph_qbl, MIPS_V2HI_FTYPE_V4QI_V2HI, MASK_DSP),
DIRECT_BUILTIN (muleu_s_ph_qbr, MIPS_V2HI_FTYPE_V4QI_V2HI, MASK_DSP),
DIRECT_BUILTIN (mulq_rs_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (muleq_s_w_phl, MIPS_SI_FTYPE_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (muleq_s_w_phr, MIPS_SI_FTYPE_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (dpau_h_qbl, MIPS_DI_FTYPE_DI_V4QI_V4QI, MASK_DSP),
DIRECT_BUILTIN (dpau_h_qbr, MIPS_DI_FTYPE_DI_V4QI_V4QI, MASK_DSP),
DIRECT_BUILTIN (dpsu_h_qbl, MIPS_DI_FTYPE_DI_V4QI_V4QI, MASK_DSP),
DIRECT_BUILTIN (dpsu_h_qbr, MIPS_DI_FTYPE_DI_V4QI_V4QI, MASK_DSP),
DIRECT_BUILTIN (dpaq_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (dpsq_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (mulsaq_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (dpaq_sa_l_w, MIPS_DI_FTYPE_DI_SI_SI, MASK_DSP),
DIRECT_BUILTIN (dpsq_sa_l_w, MIPS_DI_FTYPE_DI_SI_SI, MASK_DSP),
DIRECT_BUILTIN (maq_s_w_phl, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (maq_s_w_phr, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (maq_sa_w_phl, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (maq_sa_w_phr, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (bitrev, MIPS_SI_FTYPE_SI, MASK_DSP),
DIRECT_BUILTIN (insv, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
DIRECT_BUILTIN (repl_qb, MIPS_V4QI_FTYPE_SI, MASK_DSP),
DIRECT_BUILTIN (repl_ph, MIPS_V2HI_FTYPE_SI, MASK_DSP),
DIRECT_NO_TARGET_BUILTIN (cmpu_eq_qb, MIPS_VOID_FTYPE_V4QI_V4QI, MASK_DSP),
DIRECT_NO_TARGET_BUILTIN (cmpu_lt_qb, MIPS_VOID_FTYPE_V4QI_V4QI, MASK_DSP),
DIRECT_NO_TARGET_BUILTIN (cmpu_le_qb, MIPS_VOID_FTYPE_V4QI_V4QI, MASK_DSP),
DIRECT_BUILTIN (cmpgu_eq_qb, MIPS_SI_FTYPE_V4QI_V4QI, MASK_DSP),
DIRECT_BUILTIN (cmpgu_lt_qb, MIPS_SI_FTYPE_V4QI_V4QI, MASK_DSP),
DIRECT_BUILTIN (cmpgu_le_qb, MIPS_SI_FTYPE_V4QI_V4QI, MASK_DSP),
DIRECT_NO_TARGET_BUILTIN (cmp_eq_ph, MIPS_VOID_FTYPE_V2HI_V2HI, MASK_DSP),
DIRECT_NO_TARGET_BUILTIN (cmp_lt_ph, MIPS_VOID_FTYPE_V2HI_V2HI, MASK_DSP),
DIRECT_NO_TARGET_BUILTIN (cmp_le_ph, MIPS_VOID_FTYPE_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (pick_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
DIRECT_BUILTIN (pick_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (packrl_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
DIRECT_BUILTIN (extr_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
DIRECT_BUILTIN (extr_r_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
DIRECT_BUILTIN (extr_rs_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
DIRECT_BUILTIN (extr_s_h, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
DIRECT_BUILTIN (extp, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
DIRECT_BUILTIN (extpdp, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
DIRECT_BUILTIN (shilo, MIPS_DI_FTYPE_DI_SI, MASK_DSP),
DIRECT_BUILTIN (mthlip, MIPS_DI_FTYPE_DI_SI, MASK_DSP),
DIRECT_NO_TARGET_BUILTIN (wrdsp, MIPS_VOID_FTYPE_SI_SI, MASK_DSP),
DIRECT_BUILTIN (rddsp, MIPS_SI_FTYPE_SI, MASK_DSP),
DIRECT_BUILTIN (lbux, MIPS_SI_FTYPE_PTR_SI, MASK_DSP),
DIRECT_BUILTIN (lhx, MIPS_SI_FTYPE_PTR_SI, MASK_DSP),
DIRECT_BUILTIN (lwx, MIPS_SI_FTYPE_PTR_SI, MASK_DSP),
BPOSGE_BUILTIN (32, MASK_DSP)
};
/* This helps provide a mapping from builtin function codes to bdesc
arrays. */
@ -9929,7 +10136,8 @@ struct bdesc_map
static const struct bdesc_map bdesc_arrays[] =
{
{ mips_bdesc, ARRAY_SIZE (mips_bdesc), PROCESSOR_MAX },
{ sb1_bdesc, ARRAY_SIZE (sb1_bdesc), PROCESSOR_SB1 }
{ sb1_bdesc, ARRAY_SIZE (sb1_bdesc), PROCESSOR_SB1 },
{ dsp_bdesc, ARRAY_SIZE (dsp_bdesc), PROCESSOR_MAX }
};
/* Take the head of argument list *ARGLIST and convert it into a form
@ -9946,7 +10154,15 @@ mips_prepare_builtin_arg (enum insn_code icode,
value = expand_expr (TREE_VALUE (*arglist), NULL_RTX, VOIDmode, 0);
mode = insn_data[icode].operand[op].mode;
if (!insn_data[icode].operand[op].predicate (value, mode))
value = copy_to_mode_reg (mode, value);
{
value = copy_to_mode_reg (mode, value);
/* Check the predicate again. */
if (!insn_data[icode].operand[op].predicate (value, mode))
{
error ("invalid argument to builtin function");
return const0_rtx;
}
}
*arglist = TREE_CHAIN (*arglist);
return value;
@ -10003,7 +10219,10 @@ mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
switch (type)
{
case MIPS_BUILTIN_DIRECT:
return mips_expand_builtin_direct (icode, target, arglist);
return mips_expand_builtin_direct (icode, target, arglist, true);
case MIPS_BUILTIN_DIRECT_NO_TARGET:
return mips_expand_builtin_direct (icode, target, arglist, false);
case MIPS_BUILTIN_MOVT:
case MIPS_BUILTIN_MOVF:
@ -10018,6 +10237,9 @@ mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
return mips_expand_builtin_compare (type, icode, bdesc[fcode].cond,
target, arglist);
case MIPS_BUILTIN_BPOSGE32:
return mips_expand_builtin_bposge (type, target);
default:
return 0;
}
@ -10032,70 +10254,214 @@ mips_init_builtins (void)
const struct bdesc_map *m;
tree types[(int) MIPS_MAX_FTYPE_MAX];
tree V2SF_type_node;
tree V2HI_type_node;
tree V4QI_type_node;
unsigned int offset;
/* We have only builtins for -mpaired-single and -mips3d. */
if (!TARGET_PAIRED_SINGLE_FLOAT)
/* We have only builtins for -mpaired-single, -mips3d and -mdsp. */
if (!TARGET_PAIRED_SINGLE_FLOAT && !TARGET_DSP)
return;
V2SF_type_node = build_vector_type_for_mode (float_type_node, V2SFmode);
if (TARGET_PAIRED_SINGLE_FLOAT)
{
V2SF_type_node = build_vector_type_for_mode (float_type_node, V2SFmode);
types[MIPS_V2SF_FTYPE_V2SF]
= build_function_type_list (V2SF_type_node, V2SF_type_node, NULL_TREE);
types[MIPS_V2SF_FTYPE_V2SF]
= build_function_type_list (V2SF_type_node, V2SF_type_node, NULL_TREE);
types[MIPS_V2SF_FTYPE_V2SF_V2SF]
= build_function_type_list (V2SF_type_node,
V2SF_type_node, V2SF_type_node, NULL_TREE);
types[MIPS_V2SF_FTYPE_V2SF_V2SF]
= build_function_type_list (V2SF_type_node,
V2SF_type_node, V2SF_type_node, NULL_TREE);
types[MIPS_V2SF_FTYPE_V2SF_V2SF_INT]
= build_function_type_list (V2SF_type_node,
V2SF_type_node, V2SF_type_node,
integer_type_node, NULL_TREE);
types[MIPS_V2SF_FTYPE_V2SF_V2SF_INT]
= build_function_type_list (V2SF_type_node,
V2SF_type_node, V2SF_type_node,
integer_type_node, NULL_TREE);
types[MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF]
= build_function_type_list (V2SF_type_node,
V2SF_type_node, V2SF_type_node,
V2SF_type_node, V2SF_type_node, NULL_TREE);
types[MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF]
= build_function_type_list (V2SF_type_node,
V2SF_type_node, V2SF_type_node,
V2SF_type_node, V2SF_type_node, NULL_TREE);
types[MIPS_V2SF_FTYPE_SF_SF]
= build_function_type_list (V2SF_type_node,
float_type_node, float_type_node, NULL_TREE);
types[MIPS_V2SF_FTYPE_SF_SF]
= build_function_type_list (V2SF_type_node,
float_type_node, float_type_node, NULL_TREE);
types[MIPS_INT_FTYPE_V2SF_V2SF]
= build_function_type_list (integer_type_node,
V2SF_type_node, V2SF_type_node, NULL_TREE);
types[MIPS_INT_FTYPE_V2SF_V2SF]
= build_function_type_list (integer_type_node,
V2SF_type_node, V2SF_type_node, NULL_TREE);
types[MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF]
= build_function_type_list (integer_type_node,
V2SF_type_node, V2SF_type_node,
V2SF_type_node, V2SF_type_node, NULL_TREE);
types[MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF]
= build_function_type_list (integer_type_node,
V2SF_type_node, V2SF_type_node,
V2SF_type_node, V2SF_type_node, NULL_TREE);
types[MIPS_INT_FTYPE_SF_SF]
= build_function_type_list (integer_type_node,
float_type_node, float_type_node, NULL_TREE);
types[MIPS_INT_FTYPE_SF_SF]
= build_function_type_list (integer_type_node,
float_type_node, float_type_node, NULL_TREE);
types[MIPS_INT_FTYPE_DF_DF]
= build_function_type_list (integer_type_node,
double_type_node, double_type_node, NULL_TREE);
types[MIPS_INT_FTYPE_DF_DF]
= build_function_type_list (integer_type_node,
double_type_node, double_type_node, NULL_TREE);
types[MIPS_SF_FTYPE_V2SF]
= build_function_type_list (float_type_node, V2SF_type_node, NULL_TREE);
types[MIPS_SF_FTYPE_V2SF]
= build_function_type_list (float_type_node, V2SF_type_node, NULL_TREE);
types[MIPS_SF_FTYPE_SF]
= build_function_type_list (float_type_node,
float_type_node, NULL_TREE);
types[MIPS_SF_FTYPE_SF]
= build_function_type_list (float_type_node,
float_type_node, NULL_TREE);
types[MIPS_SF_FTYPE_SF_SF]
= build_function_type_list (float_type_node,
float_type_node, float_type_node, NULL_TREE);
types[MIPS_SF_FTYPE_SF_SF]
= build_function_type_list (float_type_node,
float_type_node, float_type_node, NULL_TREE);
types[MIPS_DF_FTYPE_DF]
= build_function_type_list (double_type_node,
double_type_node, NULL_TREE);
types[MIPS_DF_FTYPE_DF]
= build_function_type_list (double_type_node,
double_type_node, NULL_TREE);
types[MIPS_DF_FTYPE_DF_DF]
= build_function_type_list (double_type_node,
double_type_node, double_type_node, NULL_TREE);
types[MIPS_DF_FTYPE_DF_DF]
= build_function_type_list (double_type_node,
double_type_node, double_type_node, NULL_TREE);
}
if (TARGET_DSP)
{
V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
V4QI_type_node = build_vector_type_for_mode (intQI_type_node, V4QImode);
types[MIPS_V2HI_FTYPE_V2HI_V2HI]
= build_function_type_list (V2HI_type_node,
V2HI_type_node, V2HI_type_node,
NULL_TREE);
types[MIPS_SI_FTYPE_SI_SI]
= build_function_type_list (intSI_type_node,
intSI_type_node, intSI_type_node,
NULL_TREE);
types[MIPS_V4QI_FTYPE_V4QI_V4QI]
= build_function_type_list (V4QI_type_node,
V4QI_type_node, V4QI_type_node,
NULL_TREE);
types[MIPS_SI_FTYPE_V4QI]
= build_function_type_list (intSI_type_node,
V4QI_type_node,
NULL_TREE);
types[MIPS_V2HI_FTYPE_V2HI]
= build_function_type_list (V2HI_type_node,
V2HI_type_node,
NULL_TREE);
types[MIPS_SI_FTYPE_SI]
= build_function_type_list (intSI_type_node,
intSI_type_node,
NULL_TREE);
types[MIPS_V4QI_FTYPE_V2HI_V2HI]
= build_function_type_list (V4QI_type_node,
V2HI_type_node, V2HI_type_node,
NULL_TREE);
types[MIPS_V2HI_FTYPE_SI_SI]
= build_function_type_list (V2HI_type_node,
intSI_type_node, intSI_type_node,
NULL_TREE);
types[MIPS_SI_FTYPE_V2HI]
= build_function_type_list (intSI_type_node,
V2HI_type_node,
NULL_TREE);
types[MIPS_V2HI_FTYPE_V4QI]
= build_function_type_list (V2HI_type_node,
V4QI_type_node,
NULL_TREE);
types[MIPS_V4QI_FTYPE_V4QI_SI]
= build_function_type_list (V4QI_type_node,
V4QI_type_node, intSI_type_node,
NULL_TREE);
types[MIPS_V2HI_FTYPE_V2HI_SI]
= build_function_type_list (V2HI_type_node,
V2HI_type_node, intSI_type_node,
NULL_TREE);
types[MIPS_V2HI_FTYPE_V4QI_V2HI]
= build_function_type_list (V2HI_type_node,
V4QI_type_node, V2HI_type_node,
NULL_TREE);
types[MIPS_SI_FTYPE_V2HI_V2HI]
= build_function_type_list (intSI_type_node,
V2HI_type_node, V2HI_type_node,
NULL_TREE);
types[MIPS_DI_FTYPE_DI_V4QI_V4QI]
= build_function_type_list (intDI_type_node,
intDI_type_node, V4QI_type_node, V4QI_type_node,
NULL_TREE);
types[MIPS_DI_FTYPE_DI_V2HI_V2HI]
= build_function_type_list (intDI_type_node,
intDI_type_node, V2HI_type_node, V2HI_type_node,
NULL_TREE);
types[MIPS_DI_FTYPE_DI_SI_SI]
= build_function_type_list (intDI_type_node,
intDI_type_node, intSI_type_node, intSI_type_node,
NULL_TREE);
types[MIPS_V4QI_FTYPE_SI]
= build_function_type_list (V4QI_type_node,
intSI_type_node,
NULL_TREE);
types[MIPS_V2HI_FTYPE_SI]
= build_function_type_list (V2HI_type_node,
intSI_type_node,
NULL_TREE);
types[MIPS_VOID_FTYPE_V4QI_V4QI]
= build_function_type_list (void_type_node,
V4QI_type_node, V4QI_type_node,
NULL_TREE);
types[MIPS_SI_FTYPE_V4QI_V4QI]
= build_function_type_list (intSI_type_node,
V4QI_type_node, V4QI_type_node,
NULL_TREE);
types[MIPS_VOID_FTYPE_V2HI_V2HI]
= build_function_type_list (void_type_node,
V2HI_type_node, V2HI_type_node,
NULL_TREE);
types[MIPS_SI_FTYPE_DI_SI]
= build_function_type_list (intSI_type_node,
intDI_type_node, intSI_type_node,
NULL_TREE);
types[MIPS_DI_FTYPE_DI_SI]
= build_function_type_list (intDI_type_node,
intDI_type_node, intSI_type_node,
NULL_TREE);
types[MIPS_VOID_FTYPE_SI_SI]
= build_function_type_list (void_type_node,
intSI_type_node, intSI_type_node,
NULL_TREE);
types[MIPS_SI_FTYPE_PTR_SI]
= build_function_type_list (intSI_type_node,
ptr_type_node, intSI_type_node,
NULL_TREE);
types[MIPS_SI_FTYPE_VOID]
= build_function_type (intSI_type_node, void_list_node);
}
/* Iterate through all of the bdesc arrays, initializing all of the
builtin functions. */
@ -10115,30 +10481,40 @@ mips_init_builtins (void)
/* Expand a MIPS_BUILTIN_DIRECT function. ICODE is the code of the
.md pattern and ARGLIST is the list of function arguments. TARGET,
if nonnull, suggests a good place to put the result. */
if nonnull, suggests a good place to put the result.
HAS_TARGET indicates the function must return something. */
static rtx
mips_expand_builtin_direct (enum insn_code icode, rtx target, tree arglist)
mips_expand_builtin_direct (enum insn_code icode, rtx target, tree arglist,
bool has_target)
{
rtx ops[MAX_RECOG_OPERANDS];
int i;
int i = 0;
target = mips_prepare_builtin_target (icode, 0, target);
for (i = 1; i < insn_data[icode].n_operands; i++)
if (has_target)
{
/* We save target to ops[0]. */
ops[0] = mips_prepare_builtin_target (icode, 0, target);
i = 1;
}
/* We need to test if arglist is not zero. Some instructions have extra
clobber registers. */
for (; i < insn_data[icode].n_operands && arglist != 0; i++)
ops[i] = mips_prepare_builtin_arg (icode, i, &arglist);
switch (insn_data[icode].n_operands)
switch (i)
{
case 2:
emit_insn (GEN_FCN (icode) (target, ops[1]));
emit_insn (GEN_FCN (icode) (ops[0], ops[1]));
break;
case 3:
emit_insn (GEN_FCN (icode) (target, ops[1], ops[2]));
emit_insn (GEN_FCN (icode) (ops[0], ops[1], ops[2]));
break;
case 4:
emit_insn (GEN_FCN (icode) (target, ops[1], ops[2], ops[3]));
emit_insn (GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3]));
break;
default:
@ -10268,5 +10644,59 @@ mips_expand_builtin_compare (enum mips_builtin_type builtin_type,
return target;
}
/* Expand a bposge builtin of type BUILTIN_TYPE. TARGET, if nonnull,
suggests a good place to put the boolean result.
The sequence we want is
li target, 0
bposge* label1
j label2
label1:
li target, 1
label2: */
static rtx
mips_expand_builtin_bposge (enum mips_builtin_type builtin_type, rtx target)
{
rtx label1, label2, if_then_else;
rtx cmp_result;
int cmp_value;
if (target == 0 || GET_MODE (target) != SImode)
target = gen_reg_rtx (SImode);
cmp_result = gen_rtx_REG (CCDSPmode, CCDSP_PO_REGNUM);
if (builtin_type == MIPS_BUILTIN_BPOSGE32)
cmp_value = 32;
else
gcc_assert (0);
/* Move 0 to target */
emit_move_insn (target, const0_rtx);
/* Generate two labels */
label1 = gen_label_rtx ();
label2 = gen_label_rtx ();
/* Generate if_then_else */
if_then_else
= gen_rtx_IF_THEN_ELSE (VOIDmode,
gen_rtx_fmt_ee (GE, CCDSPmode,
cmp_result, GEN_INT (cmp_value)),
gen_rtx_LABEL_REF (VOIDmode, label1), pc_rtx);
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, if_then_else));
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
gen_rtx_LABEL_REF (VOIDmode, label2)));
emit_barrier ();
emit_label (label1);
emit_move_insn (target, const1_rtx);
emit_label (label2);
return target;
}
#include "gt-mips.h"

View file

@ -316,6 +316,9 @@ extern const struct mips_rtx_cost_data *mips_cost;
if (TARGET_MIPS3D) \
builtin_define ("__mips3d"); \
\
if (TARGET_DSP) \
builtin_define ("__mips_dsp"); \
\
MIPS_CPP_SET_PROCESSOR ("_MIPS_ARCH", mips_arch_info); \
MIPS_CPP_SET_PROCESSOR ("_MIPS_TUNE", mips_tune_info); \
\
@ -807,6 +810,7 @@ extern const struct mips_rtx_cost_data *mips_cost;
%{mips32} %{mips32r2} %{mips64} \
%{mips16:%{!mno-mips16:-mips16}} %{mno-mips16:-no-mips16} \
%{mips3d:-mips3d} \
%{mdsp} \
%{mfix-vr4120} %{mfix-vr4130} \
%(subtarget_asm_optimizing_spec) \
%(subtarget_asm_debugging_spec) \
@ -1149,9 +1153,11 @@ extern const struct mips_rtx_cost_data *mips_cost;
- ARG_POINTER_REGNUM
- FRAME_POINTER_REGNUM
- FAKE_CALL_REGNO (see the comment above load_callsi for details)
- 3 dummy entries that were used at various times in the past. */
- 3 dummy entries that were used at various times in the past.
- 6 DSP accumulator registers (3 hi-lo pairs) for MIPS DSP ASE
- 6 DSP control registers */
#define FIRST_PSEUDO_REGISTER 176
#define FIRST_PSEUDO_REGISTER 188
/* By default, fix the kernel registers ($26 and $27), the global
pointer ($28) and the stack pointer ($29). This can change
@ -1178,7 +1184,9 @@ extern const struct mips_rtx_cost_data *mips_cost;
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
/* COP3 registers */ \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
/* 6 DSP accumulator registers & 6 control registers */ \
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 \
}
@ -1208,7 +1216,9 @@ extern const struct mips_rtx_cost_data *mips_cost;
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
/* COP3 registers */ \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
/* 6 DSP accumulator registers & 6 control registers */ \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
}
@ -1231,7 +1241,9 @@ extern const struct mips_rtx_cost_data *mips_cost;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
/* COP3 registers */ \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
/* 6 DSP accumulator registers & 6 control registers */ \
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 \
}
/* Internal macros to classify a register number as to whether it's a
@ -1273,9 +1285,19 @@ extern const struct mips_rtx_cost_data *mips_cost;
/* ALL_COP_REG_NUM assumes that COP0,2,and 3 are numbered consecutively. */
#define ALL_COP_REG_NUM (COP3_REG_LAST - COP0_REG_FIRST + 1)
#define DSP_ACC_REG_FIRST 176
#define DSP_ACC_REG_LAST 181
#define DSP_ACC_REG_NUM (DSP_ACC_REG_LAST - DSP_ACC_REG_FIRST + 1)
#define AT_REGNUM (GP_REG_FIRST + 1)
#define HI_REGNUM (MD_REG_FIRST + 0)
#define LO_REGNUM (MD_REG_FIRST + 1)
#define AC1HI_REGNUM (DSP_ACC_REG_FIRST + 0)
#define AC1LO_REGNUM (DSP_ACC_REG_FIRST + 1)
#define AC2HI_REGNUM (DSP_ACC_REG_FIRST + 2)
#define AC2LO_REGNUM (DSP_ACC_REG_FIRST + 3)
#define AC3HI_REGNUM (DSP_ACC_REG_FIRST + 4)
#define AC3LO_REGNUM (DSP_ACC_REG_FIRST + 5)
/* FPSW_REGNUM is the single condition code used if !ISA_HAS_8CC.
If ISA_HAS_8CC, it should not be used, and an arbitrary ST_REG
@ -1300,6 +1322,16 @@ extern const struct mips_rtx_cost_data *mips_cost;
((unsigned int) ((int) (REGNO) - COP3_REG_FIRST) < COP3_REG_NUM)
#define ALL_COP_REG_P(REGNO) \
((unsigned int) ((int) (REGNO) - COP0_REG_FIRST) < ALL_COP_REG_NUM)
/* Test if REGNO is one of the 6 new DSP accumulators. */
#define DSP_ACC_REG_P(REGNO) \
((unsigned int) ((int) (REGNO) - DSP_ACC_REG_FIRST) < DSP_ACC_REG_NUM)
/* Test if REGNO is hi, lo, or one of the 6 new DSP accumulators. */
#define ACC_REG_P(REGNO) \
(MD_REG_P (REGNO) || DSP_ACC_REG_P (REGNO))
/* Test if REGNO is HI or the first register of 3 new DSP accumulator pairs. */
#define ACC_HI_REG_P(REGNO) \
((REGNO) == HI_REGNUM || (REGNO) == AC1HI_REGNUM || (REGNO) == AC2HI_REGNUM \
|| (REGNO) == AC3HI_REGNUM)
#define FP_REG_RTX_P(X) (REG_P (X) && FP_REG_P (REGNO (X)))
@ -1442,6 +1474,8 @@ enum reg_class
ALL_COP_REGS,
ALL_COP_AND_GR_REGS,
ST_REGS, /* status registers (fp status) */
DSP_ACC_REGS, /* DSP accumulator registers */
ACC_REGS, /* Hi/Lo and DSP accumulator registers */
ALL_REGS, /* all registers */
LIM_REG_CLASSES /* max value + 1 */
};
@ -1482,6 +1516,8 @@ enum reg_class
"ALL_COP_REGS", \
"ALL_COP_AND_GR_REGS", \
"ST_REGS", \
"DSP_ACC_REGS", \
"ACC_REGS", \
"ALL_REGS" \
}
@ -1523,7 +1559,9 @@ enum reg_class
{ 0x00000000, 0x00000000, 0xffff0000, 0xffffffff, 0xffffffff, 0x0000ffff }, \
{ 0xffffffff, 0x00000000, 0xffff0000, 0xffffffff, 0xffffffff, 0x0000ffff }, \
{ 0x00000000, 0x00000000, 0x000007f8, 0x00000000, 0x00000000, 0x00000000 }, /* status registers */ \
{ 0xffffffff, 0xffffffff, 0xffff07ff, 0xffffffff, 0xffffffff, 0x0000ffff } /* all registers */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x003f0000 }, /* dsp accumulator registers */ \
{ 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x003f0000 }, /* hi/lo and dsp accumulator registers */ \
{ 0xffffffff, 0xffffffff, 0xffff07ff, 0xffffffff, 0xffffffff, 0x0fffffff } /* all registers */ \
}
@ -1584,7 +1622,8 @@ extern const enum reg_class mips_regno_to_class[];
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, \
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, \
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, \
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175 \
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, \
176,177,178,179,180,181,182,183,184,185,186,187 \
}
/* ORDER_REGS_FOR_LOCAL_ALLOC is a macro which permits reg_alloc_order
@ -1615,12 +1654,24 @@ extern const enum reg_class mips_regno_to_class[];
'B' Cop0 register
'C' Cop2 register
'D' Cop3 register
'A' DSP accumulator registers
'a' MD registers and DSP accumulator registers
'b' All registers */
extern enum reg_class mips_char_to_class[256];
#define REG_CLASS_FROM_LETTER(C) mips_char_to_class[(unsigned char)(C)]
/* True if VALUE is a unsigned 6-bit number. */
#define UIMM6_OPERAND(VALUE) \
(((VALUE) & ~(unsigned HOST_WIDE_INT) 0x3f) == 0)
/* True if VALUE is a signed 10-bit number. */
#define IMM10_OPERAND(VALUE) \
((unsigned HOST_WIDE_INT) (VALUE) + 0x200 < 0x400)
/* True if VALUE is a signed 16-bit number. */
#define SMALL_OPERAND(VALUE) \
@ -1718,11 +1769,17 @@ extern enum reg_class mips_char_to_class[256];
This is true for all non-mips16 references (although it can sometimes
be indirect if !TARGET_EXPLICIT_RELOCS). For mips16, it excludes
stack and constant-pool references.
`YG' is for 0 valued vector constants. */
`YG' is for 0 valued vector constants.
`YA' is for unsigned 6-bit constants.
`YB' is for signed 10-bit constants. */
#define EXTRA_CONSTRAINT_Y(OP,STR) \
(((STR)[1] == 'G') ? (GET_CODE (OP) == CONST_VECTOR \
&& (OP) == CONST0_RTX (GET_MODE (OP))) \
: ((STR)[1] == 'A') ? (GET_CODE (OP) == CONST_INT \
&& UIMM6_OPERAND (INTVAL (OP))) \
: ((STR)[1] == 'B') ? (GET_CODE (OP) == CONST_INT \
&& IMM10_OPERAND (INTVAL (OP))) \
: FALSE)
@ -2386,7 +2443,9 @@ typedef struct mips_args {
"$c3r0", "$c3r1", "$c3r2", "$c3r3", "$c3r4", "$c3r5", "$c3r6", "$c3r7", \
"$c3r8", "$c3r9", "$c3r10","$c3r11","$c3r12","$c3r13","$c3r14","$c3r15", \
"$c3r16","$c3r17","$c3r18","$c3r19","$c3r20","$c3r21","$c3r22","$c3r23", \
"$c3r24","$c3r25","$c3r26","$c3r27","$c3r28","$c3r29","$c3r30","$c3r31" }
"$c3r24","$c3r25","$c3r26","$c3r27","$c3r28","$c3r29","$c3r30","$c3r31", \
"$ac1hi","$ac1lo","$ac2hi","$ac2lo","$ac3hi","$ac3lo","$dsp_po","$dsp_sc", \
"$dsp_ca","$dsp_ou","$dsp_cc","$dsp_ef" }
/* List the "software" names for each register. Also list the numerical
names for $fp and $sp. */

View file

@ -72,6 +72,76 @@
(UNSPEC_RSQRT2 209)
(UNSPEC_RECIP1 210)
(UNSPEC_RECIP2 211)
;; MIPS DSP ASE Revision 0.98 3/24/2005
(UNSPEC_ADDQ 300)
(UNSPEC_ADDQ_S 301)
(UNSPEC_SUBQ 302)
(UNSPEC_SUBQ_S 303)
(UNSPEC_ADDSC 304)
(UNSPEC_ADDWC 305)
(UNSPEC_MODSUB 306)
(UNSPEC_RADDU_W_QB 307)
(UNSPEC_ABSQ_S 308)
(UNSPEC_PRECRQ_QB_PH 309)
(UNSPEC_PRECRQ_PH_W 310)
(UNSPEC_PRECRQ_RS_PH_W 311)
(UNSPEC_PRECRQU_S_QB_PH 312)
(UNSPEC_PRECEQ_W_PHL 313)
(UNSPEC_PRECEQ_W_PHR 314)
(UNSPEC_PRECEQU_PH_QBL 315)
(UNSPEC_PRECEQU_PH_QBR 316)
(UNSPEC_PRECEQU_PH_QBLA 317)
(UNSPEC_PRECEQU_PH_QBRA 318)
(UNSPEC_PRECEU_PH_QBL 319)
(UNSPEC_PRECEU_PH_QBR 320)
(UNSPEC_PRECEU_PH_QBLA 321)
(UNSPEC_PRECEU_PH_QBRA 322)
(UNSPEC_SHLL 323)
(UNSPEC_SHLL_S 324)
(UNSPEC_SHRL_QB 325)
(UNSPEC_SHRA_PH 326)
(UNSPEC_SHRA_R 327)
(UNSPEC_MULEU_S_PH_QBL 328)
(UNSPEC_MULEU_S_PH_QBR 329)
(UNSPEC_MULQ_RS_PH 330)
(UNSPEC_MULEQ_S_W_PHL 331)
(UNSPEC_MULEQ_S_W_PHR 332)
(UNSPEC_DPAU_H_QBL 333)
(UNSPEC_DPAU_H_QBR 334)
(UNSPEC_DPSU_H_QBL 335)
(UNSPEC_DPSU_H_QBR 336)
(UNSPEC_DPAQ_S_W_PH 337)
(UNSPEC_DPSQ_S_W_PH 338)
(UNSPEC_MULSAQ_S_W_PH 339)
(UNSPEC_DPAQ_SA_L_W 340)
(UNSPEC_DPSQ_SA_L_W 341)
(UNSPEC_MAQ_S_W_PHL 342)
(UNSPEC_MAQ_S_W_PHR 343)
(UNSPEC_MAQ_SA_W_PHL 344)
(UNSPEC_MAQ_SA_W_PHR 345)
(UNSPEC_BITREV 346)
(UNSPEC_INSV 347)
(UNSPEC_REPL_QB 348)
(UNSPEC_REPL_PH 349)
(UNSPEC_CMP_EQ 350)
(UNSPEC_CMP_LT 351)
(UNSPEC_CMP_LE 352)
(UNSPEC_CMPGU_EQ_QB 353)
(UNSPEC_CMPGU_LT_QB 354)
(UNSPEC_CMPGU_LE_QB 355)
(UNSPEC_PICK 356)
(UNSPEC_PACKRL_PH 357)
(UNSPEC_EXTR_W 358)
(UNSPEC_EXTR_R_W 359)
(UNSPEC_EXTR_RS_W 360)
(UNSPEC_EXTR_S_H 361)
(UNSPEC_EXTP 362)
(UNSPEC_EXTPDP 363)
(UNSPEC_SHILO 364)
(UNSPEC_MTHLIP 365)
(UNSPEC_WRDSP 366)
(UNSPEC_RDDSP 367)
]
)
@ -3124,8 +3194,8 @@
(set_attr "mode" "<MODE>")])
(define_insn "*movdi_32bit"
[(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*B*C*D,*B*C*D,*d,*m")
(match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*x,*d,*m,*B*C*D,*B*C*D"))]
[(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m")
(match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
"!TARGET_64BIT && !TARGET_MIPS16
&& (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))"
@ -3242,15 +3312,15 @@
;; in FP registers (off by default, use -mdebugh to enable).
(define_insn "*movsi_internal"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*B*C*D,*B*C*D,*d,*m")
(match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*d,*m,*B*C*D,*B*C*D"))]
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*m")
(match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*A,*d,*m,*B*C*D,*B*C*D"))]
"!TARGET_MIPS16
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
{ return mips_output_move (operands[0], operands[1]); }
[(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,xfer,load,xfer,store")
[(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,mfhilo,xfer,load,xfer,store")
(set_attr "mode" "SI")
(set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,*,4,*")])
(set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")])
(define_insn "*movsi_mips16"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m")
@ -5353,3 +5423,7 @@
; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
(include "mips-ps-3d.md")
; The MIPS DSP Instructions.
(include "mips-dsp.md")

View file

@ -55,6 +55,10 @@ mdouble-float
Target Report RejectNegative InverseMask(SINGLE_FLOAT, DOUBLE_FLOAT)
Allow hardware floating-point instructions to cover both 32-bit and 64-bit operations
mdsp
Target Report Mask(DSP)
Use MIPS-DSP instructions
mdebug
Target Var(TARGET_DEBUG_MODE) Undocumented

View file

@ -34,6 +34,18 @@
(ior (match_operand 0 "const_arith_operand")
(match_operand 0 "register_operand")))
(define_predicate "const_uimm6_operand"
(and (match_code "const_int")
(match_test "UIMM6_OPERAND (INTVAL (op))")))
(define_predicate "const_imm10_operand"
(and (match_code "const_int")
(match_test "IMM10_OPERAND (INTVAL (op))")))
(define_predicate "reg_imm10_operand"
(ior (match_operand 0 "const_imm10_operand")
(match_operand 0 "register_operand")))
(define_predicate "sle_operand"
(and (match_code "const_int")
(match_test "SMALL_OPERAND (INTVAL (op) + 1)")))

View file

@ -5777,6 +5777,7 @@ instructions, but allow the compiler to schedule those calls.
* Blackfin Built-in Functions::
* FR-V Built-in Functions::
* X86 Built-in Functions::
* MIPS DSP Built-in Functions::
* MIPS Paired-Single Support::
* PowerPC AltiVec Built-in Functions::
* SPARC VIS Built-in Functions::
@ -6676,6 +6677,208 @@ v2sf __builtin_ia32_pswapdsf (v2sf)
v2si __builtin_ia32_pswapdsi (v2si)
@end smallexample
@node MIPS DSP Built-in Functions
@subsection MIPS DSP Built-in Functions
The MIPS DSP Application-Specific Extension (ASE) includes new
instructions that are designed to improve the performance of DSP and
media applications. It provides instructions that operate on packed
8-bit integer data, Q15 fractional data and Q31 fractional data.
GCC supports MIPS DSP operations using both the generic
vector extensions (@pxref{Vector Extensions}) and a collection of
MIPS-specific built-in functions. Both kinds of support are
enabled by the @option{-mdsp} command-line option.
At present, GCC only provides support for operations on 32-bit
vectors. The vector type associated with 8-bit integer data is
usually called @code{v4i8} and the vector type associated with Q15 is
usually called @code{v2q15}. They can be defined in C as follows:
@smallexample
typedef char v4i8 __attribute__ ((vector_size(4)));
typedef short v2q15 __attribute__ ((vector_size(4)));
@end smallexample
@code{v4i8} and @code{v2q15} values are initialized in the same way as
aggregates. For example:
@smallexample
v4i8 a = @{1, 2, 3, 4@};
v4i8 b;
b = (v4i8) @{5, 6, 7, 8@};
v2q15 c = @{0x0fcb, 0x3a75@};
v2q15 d;
d = (v2q15) @{0.1234 * 0x1.0p15, 0.4567 * 0x1.0p15@};
@end smallexample
@emph{Note:} The CPU's endianness determines the order in which values
are packed. On little-endian targets, the first value is the least
significant and the last value is the most significant. The opposite
order applies to big-endian targets. For example, the code above will
set the lowest byte of @code{a} to @code{1} on little-endian targets
and @code{4} on big-endian targets.
@emph{Note:} Q15 and Q31 values must be initialized with their integer
representation. As shown in this example, the integer representation
of a Q15 value can be obtained by multiplying the fractional value by
@code{0x1.0p15}. The equivalent for Q31 values is to multiply by
@code{0x1.0p31}.
The table below lists the @code{v4i8} and @code{v2q15} operations for which
hardware support exists. @code{a} and @code{b} are @code{v4i8} values,
and @code{c} and @code{d} are @code{v2q15} values.
@multitable @columnfractions .50 .50
@item C code @tab MIPS instruction
@item @code{a + b} @tab @code{addu.qb}
@item @code{c + d} @tab @code{addq.ph}
@item @code{a - b} @tab @code{subu.qb}
@item @code{c - d} @tab @code{subq.ph}
@end multitable
It is easier to describe the DSP built-in functions if we first define
the following types:
@smallexample
typedef int q31;
typedef int i32;
typedef long long a64;
@end smallexample
@code{q31} and @code{i32} are actually the same as @code{int}, but we
use @code{q31} to indicate a Q31 fractional value and @code{i32} to
indicate a 32-bit integer value. Similarly, @code{a64} is the same as
@code{long long}, but we use @code{a64} to indicate values that will
be placed in one of the four DSP accumulators (@code{$ac0},
@code{$ac1}, @code{$ac2} or @code{$ac3}).
Also, some built-in functions prefer or require immediate numbers as
parameters, because the corresponding DSP instructions accept both immediate
numbers and register operands, or accept immediate numbers only. The
immediate parameters are listed as follows.
@smallexample
imm0_7: 0 to 7.
imm0_15: 0 to 15.
imm0_31: 0 to 31.
imm0_63: 0 to 63.
imm0_255: 0 to 255.
imm_n32_31: -32 to 31.
imm_n512_511: -512 to 511.
@end smallexample
The following built-in functions map directly to a particular MIPS DSP
instruction. Please refer to the architecture specification
for details on what each instruction does.
@smallexample
v2q15 __builtin_mips_addq_ph (v2q15, v2q15)
v2q15 __builtin_mips_addq_s_ph (v2q15, v2q15)
q31 __builtin_mips_addq_s_w (q31, q31)
v4i8 __builtin_mips_addu_qb (v4i8, v4i8)
v4i8 __builtin_mips_addu_s_qb (v4i8, v4i8)
v2q15 __builtin_mips_subq_ph (v2q15, v2q15)
v2q15 __builtin_mips_subq_s_ph (v2q15, v2q15)
q31 __builtin_mips_subq_s_w (q31, q31)
v4i8 __builtin_mips_subu_qb (v4i8, v4i8)
v4i8 __builtin_mips_subu_s_qb (v4i8, v4i8)
i32 __builtin_mips_addsc (i32, i32)
i32 __builtin_mips_addwc (i32, i32)
i32 __builtin_mips_modsub (i32, i32)
i32 __builtin_mips_raddu_w_qb (v4i8)
v2q15 __builtin_mips_absq_s_ph (v2q15)
q31 __builtin_mips_absq_s_w (q31)
v4i8 __builtin_mips_precrq_qb_ph (v2q15, v2q15)
v2q15 __builtin_mips_precrq_ph_w (q31, q31)
v2q15 __builtin_mips_precrq_rs_ph_w (q31, q31)
v4i8 __builtin_mips_precrqu_s_qb_ph (v2q15, v2q15)
q31 __builtin_mips_preceq_w_phl (v2q15)
q31 __builtin_mips_preceq_w_phr (v2q15)
v2q15 __builtin_mips_precequ_ph_qbl (v4i8)
v2q15 __builtin_mips_precequ_ph_qbr (v4i8)
v2q15 __builtin_mips_precequ_ph_qbla (v4i8)
v2q15 __builtin_mips_precequ_ph_qbra (v4i8)
v2q15 __builtin_mips_preceu_ph_qbl (v4i8)
v2q15 __builtin_mips_preceu_ph_qbr (v4i8)
v2q15 __builtin_mips_preceu_ph_qbla (v4i8)
v2q15 __builtin_mips_preceu_ph_qbra (v4i8)
v4i8 __builtin_mips_shll_qb (v4i8, imm0_7)
v4i8 __builtin_mips_shll_qb (v4i8, i32)
v2q15 __builtin_mips_shll_ph (v2q15, imm0_15)
v2q15 __builtin_mips_shll_ph (v2q15, i32)
v2q15 __builtin_mips_shll_s_ph (v2q15, imm0_15)
v2q15 __builtin_mips_shll_s_ph (v2q15, i32)
q31 __builtin_mips_shll_s_w (q31, imm0_31)
q31 __builtin_mips_shll_s_w (q31, i32)
v4i8 __builtin_mips_shrl_qb (v4i8, imm0_7)
v4i8 __builtin_mips_shrl_qb (v4i8, i32)
v2q15 __builtin_mips_shra_ph (v2q15, imm0_15)
v2q15 __builtin_mips_shra_ph (v2q15, i32)
v2q15 __builtin_mips_shra_r_ph (v2q15, imm0_15)
v2q15 __builtin_mips_shra_r_ph (v2q15, i32)
q31 __builtin_mips_shra_r_w (q31, imm0_31)
q31 __builtin_mips_shra_r_w (q31, i32)
v2q15 __builtin_mips_muleu_s_ph_qbl (v4i8, v2q15)
v2q15 __builtin_mips_muleu_s_ph_qbr (v4i8, v2q15)
v2q15 __builtin_mips_mulq_rs_ph (v2q15, v2q15)
q31 __builtin_mips_muleq_s_w_phl (v2q15, v2q15)
q31 __builtin_mips_muleq_s_w_phr (v2q15, v2q15)
a64 __builtin_mips_dpau_h_qbl (a64, v4i8, v4i8)
a64 __builtin_mips_dpau_h_qbr (a64, v4i8, v4i8)
a64 __builtin_mips_dpsu_h_qbl (a64, v4i8, v4i8)
a64 __builtin_mips_dpsu_h_qbr (a64, v4i8, v4i8)
a64 __builtin_mips_dpaq_s_w_ph (a64, v2q15, v2q15)
a64 __builtin_mips_dpaq_sa_l_w (a64, q31, q31)
a64 __builtin_mips_dpsq_s_w_ph (a64, v2q15, v2q15)
a64 __builtin_mips_dpsq_sa_l_w (a64, q31, q31)
a64 __builtin_mips_mulsaq_s_w_ph (a64, v2q15, v2q15)
a64 __builtin_mips_maq_s_w_phl (a64, v2q15, v2q15)
a64 __builtin_mips_maq_s_w_phr (a64, v2q15, v2q15)
a64 __builtin_mips_maq_sa_w_phl (a64, v2q15, v2q15)
a64 __builtin_mips_maq_sa_w_phr (a64, v2q15, v2q15)
i32 __builtin_mips_bitrev (i32)
i32 __builtin_mips_insv (i32, i32)
v4i8 __builtin_mips_repl_qb (imm0_255)
v4i8 __builtin_mips_repl_qb (i32)
v2q15 __builtin_mips_repl_ph (imm_n512_511)
v2q15 __builtin_mips_repl_ph (i32)
void __builtin_mips_cmpu_eq_qb (v4i8, v4i8)
void __builtin_mips_cmpu_lt_qb (v4i8, v4i8)
void __builtin_mips_cmpu_le_qb (v4i8, v4i8)
i32 __builtin_mips_cmpgu_eq_qb (v4i8, v4i8)
i32 __builtin_mips_cmpgu_lt_qb (v4i8, v4i8)
i32 __builtin_mips_cmpgu_le_qb (v4i8, v4i8)
void __builtin_mips_cmp_eq_ph (v2q15, v2q15)
void __builtin_mips_cmp_lt_ph (v2q15, v2q15)
void __builtin_mips_cmp_le_ph (v2q15, v2q15)
v4i8 __builtin_mips_pick_qb (v4i8, v4i8)
v2q15 __builtin_mips_pick_ph (v2q15, v2q15)
v2q15 __builtin_mips_packrl_ph (v2q15, v2q15)
i32 __builtin_mips_extr_w (a64, imm0_31)
i32 __builtin_mips_extr_w (a64, i32)
i32 __builtin_mips_extr_r_w (a64, imm0_31)
i32 __builtin_mips_extr_s_h (a64, i32)
i32 __builtin_mips_extr_rs_w (a64, imm0_31)
i32 __builtin_mips_extr_rs_w (a64, i32)
i32 __builtin_mips_extr_s_h (a64, imm0_31)
i32 __builtin_mips_extr_r_w (a64, i32)
i32 __builtin_mips_extp (a64, imm0_31)
i32 __builtin_mips_extp (a64, i32)
i32 __builtin_mips_extpdp (a64, imm0_31)
i32 __builtin_mips_extpdp (a64, i32)
a64 __builtin_mips_shilo (a64, imm_n32_31)
a64 __builtin_mips_shilo (a64, i32)
a64 __builtin_mips_mthlip (a64, i32)
void __builtin_mips_wrdsp (i32, imm0_63)
i32 __builtin_mips_rddsp (imm0_63)
i32 __builtin_mips_lbux (void *, i32)
i32 __builtin_mips_lhx (void *, i32)
i32 __builtin_mips_lwx (void *, i32)
i32 __builtin_mips_bposge32 (void)
@end smallexample
@node MIPS Paired-Single Support
@subsection MIPS Paired-Single Support

View file

@ -572,7 +572,7 @@ Objective-C and Objective-C++ Dialects}.
-mips16 -mno-mips16 -mabi=@var{abi} -mabicalls -mno-abicalls @gol
-mxgot -mno-xgot -mgp32 -mgp64 -mfp32 -mfp64 @gol
-mhard-float -msoft-float -msingle-float -mdouble-float @gol
-mpaired-single -mips3d @gol
-mdsp -mpaired-single -mips3d @gol
-mlong64 -mlong32 -msym32 -mno-sym32 @gol
-G@var{num} -membedded-data -mno-embedded-data @gol
-muninit-const-in-rodata -mno-uninit-const-in-rodata @gol
@ -10065,6 +10065,12 @@ operations.
Assume that the floating-point coprocessor supports double-precision
operations. This is the default.
@itemx -mdsp
@itemx -mno-dsp
@opindex mdsp
@opindex mno-dsp
Use (do not use) the MIPS DSP ASE. @xref{MIPS DSP Built-in Functions}.
@itemx -mpaired-single
@itemx -mno-paired-single
@opindex mpaired-single

View file

@ -1,3 +1,8 @@
2005-07-23 Chao-ying Fu <fu@mips.com>
* gcc.target/mips/mips32-dsp-type.c: New test.
* gcc.target/mips/mips32-dsp.c: New test.
2005-07-23 Oyvind Harboe <oyvind.harboe@zylin.com>
PR testsuite/21073

View file

@ -0,0 +1,30 @@
/* Test MIPS32 DSP instructions */
/* { dg-do compile } */
/* { dg-mips-options "-mips32 -mdsp" } */
/* { dg-final { scan-assembler "addq.ph" } } */
/* { dg-final { scan-assembler "addu.qb" } } */
/* { dg-final { scan-assembler "subq.ph" } } */
/* { dg-final { scan-assembler "subu.qb" } } */
typedef char v4qi __attribute__ ((vector_size(4)));
typedef short v2hi __attribute__ ((vector_size(4)));
v2hi add_v2hi (v2hi a, v2hi b)
{
return a + b;
}
v4qi add_v4qi (v4qi a, v4qi b)
{
return a + b;
}
v2hi sub_v2hi (v2hi a, v2hi b)
{
return a - b;
}
v4qi sub_v4qi (v4qi a, v4qi b)
{
return a - b;
}

File diff suppressed because it is too large Load diff