aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJ"orn Rennecke <joern.rennecke@superh.com>2002-07-17 15:15:04 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2002-07-17 16:15:04 +0100
commit0ac785173d96fc8d058ed817cf9286ddaf6d831a (patch)
treedb9bf553918d31a90a5fa97d75bef6b5cb9d0e87 /gcc
parentd955f6ea6f555019be4227cb1f48b691483cf275 (diff)
downloadgcc-0ac785173d96fc8d058ed817cf9286ddaf6d831a.zip
gcc-0ac785173d96fc8d058ed817cf9286ddaf6d831a.tar.gz
gcc-0ac785173d96fc8d058ed817cf9286ddaf6d831a.tar.bz2
sh-protos.h (binary_float_operator): Remove declaration.
* sh-protos.h (binary_float_operator): Remove declaration. (sh_expand_unop_v2sf, sh_expand_binop_v2sf): Declare. * sh.c (print_operand, case 'N'): Check against CONST0_RTX. (unary_float_operator, sh_expand_unop_v2sf): New functions. (sh_expand_binop_v2sf): Likewise. (zero_vec_operand): Delete. (SH_BLTIN_UDI): New builtin shared signature define. Renumbered all non-shared ones. (bdesc): Change all the mextr builtins to use SH_BLTIN_UDI. Enable nsb and byterev. * sh.h (CONDITIONAL_REGISTER_USAGE): Initialize DF_HI_REGS. (HARD_REGNO_MODE_OK): Allow TImode in fp regs. Allow V2SFmode in general regs. (enum reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add DF_HI_REGS. (SECONDARY_OUTPUT_RELOAD_CLASS): Likewise. Remove clause for immediate operands. (SECONDARY_INPUT_RELOAD_CLASS): Add clause for immediate operands. Add DF_HI_REGS. (CLASS_CANNOT_CHANGE_MODE, CLASS_CANNOT_CHANGE_MODE_P): Allow lowpart fp regs - only for big endian for now. (LEGITIMATE_CONSTANT_P): Don't allow non-zero float vectors when FPU is in use. (EXTRA_CONTRAINT_U): Check against CONST0_RTX. (LOAD_EXTEND_OP): NIL for SImode. (REGISTER_MOVE_COST): Add DF_HI_REGS. Const for moves between general and fp registers is 4. PREDICATE_CODES: Amend binary_float_operator entry. Remove zero_vec_operand. Add unary_float_operator. * sh.md (udivsi3_i4_media): Use truncate instead of paradoxical subreg SET_DEST. (truncdisi2, truncdihi2, movv2sf): Allow memory destinations. (truncdiqi2): Do sign extension. (movsi_media, movdi_media): Allow to use r63 to an fp register. (movdf_media, movsf_media): Likewise. (movv2sf_i, movv2sf_i+1): Don't use f{ld,st}.p or SUBREGS. Collapse to one define_insn_and_split. Allow immediate sources. (addv2sf3, subv2sf3, mulv2sf3, divv2sf3): New patterns. (movv4sf_i): Allow immediate sources. Use simplify_gen_subreg. (movv4sf): Allow immediate sources. (movsf_media_nofpu+1): Don't split moves to FP registers. (unary_sf_op, binary_sf_op, mshflo_w_x, concat_v2sf): New patterns. (movv8qi_i+3): Check against CONST0_RTX. (mextr1, mextr2. mextr3. mextr4, mextr5, mextr6, mextr7): Use DImode for input and output operands. Fix argument 3 to gen_mextr_rl. (mmul23_wl, mmul01_wl, mmulsum_wq_i): s/const_vector/parallel/ (msad_ubq_i, mshf4_b, mshf0_b, mshf4_l, mshf0_l, mshf4_w): Likewise. (mshf0_w, fipr, ftrv): Likewise. (mshfhi_l_di): Now insn_and_split. Can handle FP regs. From-SVN: r55528
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog51
-rw-r--r--gcc/config/sh/sh-protos.h3
-rw-r--r--gcc/config/sh/sh.c104
-rw-r--r--gcc/config/sh/sh.h62
-rw-r--r--gcc/config/sh/sh.md405
5 files changed, 447 insertions, 178 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 49ff07c..68e89f2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,54 @@
+Wed Jul 17 14:04:10 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh-protos.h (binary_float_operator): Remove declaration.
+ (sh_expand_unop_v2sf, sh_expand_binop_v2sf): Declare.
+ * sh.c (print_operand, case 'N'): Check against CONST0_RTX.
+ (unary_float_operator, sh_expand_unop_v2sf): New functions.
+ (sh_expand_binop_v2sf): Likewise.
+ (zero_vec_operand): Delete.
+ (SH_BLTIN_UDI): New builtin shared signature define. Renumbered
+ all non-shared ones.
+ (bdesc): Change all the mextr builtins to use SH_BLTIN_UDI.
+ Enable nsb and byterev.
+ * sh.h (CONDITIONAL_REGISTER_USAGE): Initialize DF_HI_REGS.
+ (HARD_REGNO_MODE_OK): Allow TImode in fp regs. Allow V2SFmode
+ in general regs.
+ (enum reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add DF_HI_REGS.
+ (SECONDARY_OUTPUT_RELOAD_CLASS): Likewise. Remove clause for
+ immediate operands.
+ (SECONDARY_INPUT_RELOAD_CLASS): Add clause for immediate operands.
+ Add DF_HI_REGS.
+ (CLASS_CANNOT_CHANGE_MODE, CLASS_CANNOT_CHANGE_MODE_P): Allow
+ lowpart fp regs - only for big endian for now.
+ (LEGITIMATE_CONSTANT_P): Don't allow non-zero float vectors
+ when FPU is in use.
+ (EXTRA_CONTRAINT_U): Check against CONST0_RTX.
+ (LOAD_EXTEND_OP): NIL for SImode.
+ (REGISTER_MOVE_COST): Add DF_HI_REGS. Const for moves between
+ general and fp registers is 4.
+ PREDICATE_CODES: Amend binary_float_operator entry.
+ Remove zero_vec_operand. Add unary_float_operator.
+ * sh.md (udivsi3_i4_media): Use truncate instead of paradoxical
+ subreg SET_DEST.
+ (truncdisi2, truncdihi2, movv2sf): Allow memory destinations.
+ (truncdiqi2): Do sign extension.
+ (movsi_media, movdi_media): Allow to use r63 to an fp register.
+ (movdf_media, movsf_media): Likewise.
+ (movv2sf_i, movv2sf_i+1): Don't use f{ld,st}.p or SUBREGS.
+ Collapse to one define_insn_and_split. Allow immediate sources.
+ (addv2sf3, subv2sf3, mulv2sf3, divv2sf3): New patterns.
+ (movv4sf_i): Allow immediate sources. Use simplify_gen_subreg.
+ (movv4sf): Allow immediate sources.
+ (movsf_media_nofpu+1): Don't split moves to FP registers.
+ (unary_sf_op, binary_sf_op, mshflo_w_x, concat_v2sf): New patterns.
+ (movv8qi_i+3): Check against CONST0_RTX.
+ (mextr1, mextr2. mextr3. mextr4, mextr5, mextr6, mextr7): Use DImode
+ for input and output operands. Fix argument 3 to gen_mextr_rl.
+ (mmul23_wl, mmul01_wl, mmulsum_wq_i): s/const_vector/parallel/
+ (msad_ubq_i, mshf4_b, mshf0_b, mshf4_l, mshf0_l, mshf4_w): Likewise.
+ (mshf0_w, fipr, ftrv): Likewise.
+ (mshfhi_l_di): Now insn_and_split. Can handle FP regs.
+
2002-07-17 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
* arm.h (ARM_NUM_INTS, ARM_NUM_REGS, ARM_NUM_REGS2): Renamed from
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index ba74158..432ab63 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -92,7 +92,6 @@ extern int fpscr_operand PARAMS ((rtx, enum machine_mode));
extern int fpul_operand PARAMS ((rtx, enum machine_mode));
extern int commutative_float_operator PARAMS ((rtx, enum machine_mode));
extern int noncommutative_float_operator PARAMS ((rtx, enum machine_mode));
-extern int binary_float_operator PARAMS ((rtx, enum machine_mode));
extern int reg_unused_after PARAMS ((rtx, rtx));
extern void expand_sf_unop PARAMS ((rtx (*)(rtx, rtx, rtx), rtx *));
extern void expand_sf_binop PARAMS ((rtx (*)(rtx, rtx, rtx, rtx), rtx *));
@@ -118,6 +117,8 @@ extern void output_file_start PARAMS ((FILE *));
extern int sh_media_register_for_return PARAMS ((void));
extern void sh_expand_prologue PARAMS ((void));
extern void sh_expand_epilogue PARAMS ((void));
+extern void sh_expand_unop_v2sf (enum rtx_code, rtx, rtx);
+extern void sh_expand_binop_v2sf (enum rtx_code, rtx, rtx, rtx);
extern int sh_need_epilogue PARAMS ((void));
extern int initial_elimination_offset PARAMS ((int, int));
extern int fldi_ok PARAMS ((void));
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 5687c0a..315cdec 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -449,8 +449,7 @@ print_operand (stream, x, code)
break;
case 'N':
- if (x == const0_rtx
- || (GET_CODE (x) == CONST_VECTOR && zero_vec_operand (x, VOIDmode)))
+ if (x == CONST0_RTX (GET_MODE (x)))
{
fprintf ((stream), "r63");
break;
@@ -6122,6 +6121,25 @@ noncommutative_float_operator (op, mode)
}
int
+unary_float_operator (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (GET_MODE (op) != mode)
+ return 0;
+ switch (GET_CODE (op))
+ {
+ case ABS:
+ case NEG:
+ case SQRT:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int
binary_float_operator (op, mode)
rtx op;
enum machine_mode mode;
@@ -6285,23 +6303,6 @@ inqhi_operand (op, mode)
return GET_CODE (op) == REG && FP_REGISTER_P (REGNO (op));
}
-/* Return nonzero if V is a zero vector matching MODE. */
-int
-zero_vec_operand (v, mode)
- rtx v;
- enum machine_mode mode;
-{
- int i;
-
- if (GET_CODE (v) != CONST_VECTOR
- || (GET_MODE (v) != mode && mode != VOIDmode))
- return 0;
- for (i = XVECLEN (v, 0) - 1; i >= 0; i--)
- if (XVECEXP (v, 0, i) != const0_rtx)
- return 0;
- return 1;
-}
-
int
sh_rep_vec (v, mode)
rtx v;
@@ -7156,19 +7157,21 @@ static const char signature_args[][4] =
{ 0, 8, 2 },
#define SH_BLTIN_STUA_Q 14
{ 0, 8, 1 },
-#define SH_BLTIN_NUM_SHARED_SIGNATURES 15
-#define SH_BLTIN_2 15
-#define SH_BLTIN_SU 15
+#define SH_BLTIN_UDI 15
+ { 0, 8, 1 },
+#define SH_BLTIN_NUM_SHARED_SIGNATURES 16
+#define SH_BLTIN_2 16
+#define SH_BLTIN_SU 16
{ 1, 2 },
-#define SH_BLTIN_3 16
-#define SH_BLTIN_SUS 16
+#define SH_BLTIN_3 17
+#define SH_BLTIN_SUS 17
{ 2, 2, 1 },
-#define SH_BLTIN_PSSV 17
+#define SH_BLTIN_PSSV 18
{ 0, 8, 2, 2 },
-#define SH_BLTIN_XXUU 18
-#define SH_BLTIN_UUUU 18
+#define SH_BLTIN_XXUU 19
+#define SH_BLTIN_UUUU 19
{ 1, 1, 1, 1 },
-#define SH_BLTIN_PV 19
+#define SH_BLTIN_PV 20
{ 0, 8 },
};
/* mcmv: operands considered unsigned. */
@@ -7200,13 +7203,13 @@ static const struct builtin_description bdesc[] =
{ CODE_FOR_mcnvs_lw, "__builtin_sh_media_MCNVS_LW", SH_BLTIN_3 },
{ CODE_FOR_mcnvs_wb, "__builtin_sh_media_MCNVS_WB", SH_BLTIN_V4HI2V8QI },
{ CODE_FOR_mcnvs_wub, "__builtin_sh_media_MCNVS_WUB", SH_BLTIN_V4HI2V8QI },
- { CODE_FOR_mextr1, "__builtin_sh_media_MEXTR1", SH_BLTIN_V8QI3 },
- { CODE_FOR_mextr2, "__builtin_sh_media_MEXTR2", SH_BLTIN_V8QI3 },
- { CODE_FOR_mextr3, "__builtin_sh_media_MEXTR3", SH_BLTIN_V8QI3 },
- { CODE_FOR_mextr4, "__builtin_sh_media_MEXTR4", SH_BLTIN_V8QI3 },
- { CODE_FOR_mextr5, "__builtin_sh_media_MEXTR5", SH_BLTIN_V8QI3 },
- { CODE_FOR_mextr6, "__builtin_sh_media_MEXTR6", SH_BLTIN_V8QI3 },
- { CODE_FOR_mextr7, "__builtin_sh_media_MEXTR7", SH_BLTIN_V8QI3 },
+ { CODE_FOR_mextr1, "__builtin_sh_media_MEXTR1", SH_BLTIN_UDI },
+ { CODE_FOR_mextr2, "__builtin_sh_media_MEXTR2", SH_BLTIN_UDI },
+ { CODE_FOR_mextr3, "__builtin_sh_media_MEXTR3", SH_BLTIN_UDI },
+ { CODE_FOR_mextr4, "__builtin_sh_media_MEXTR4", SH_BLTIN_UDI },
+ { CODE_FOR_mextr5, "__builtin_sh_media_MEXTR5", SH_BLTIN_UDI },
+ { CODE_FOR_mextr6, "__builtin_sh_media_MEXTR6", SH_BLTIN_UDI },
+ { CODE_FOR_mextr7, "__builtin_sh_media_MEXTR7", SH_BLTIN_UDI },
{ CODE_FOR_mmacfx_wl, "__builtin_sh_media_MMACFX_WL", SH_BLTIN_MAC_HISI },
{ CODE_FOR_mmacnfx_wl,"__builtin_sh_media_MMACNFX_WL", SH_BLTIN_MAC_HISI },
{ CODE_FOR_mulv2si3, "__builtin_mulv2si3", SH_BLTIN_V2SI3, },
@@ -7261,8 +7264,10 @@ static const struct builtin_description bdesc[] =
{ CODE_FOR_sthi_q64, "__builtin_sh_media_STHI_Q", SH_BLTIN_STUA_Q },
{ CODE_FOR_stlo_l64, "__builtin_sh_media_STLO_L", SH_BLTIN_STUA_L },
{ CODE_FOR_stlo_q64, "__builtin_sh_media_STLO_Q", SH_BLTIN_STUA_Q },
+#endif
{ CODE_FOR_nsb, "__builtin_sh_media_NSB", SH_BLTIN_SU },
{ CODE_FOR_byterev, "__builtin_sh_media_BYTEREV", SH_BLTIN_2 },
+#if 0
{ CODE_FOR_prefetch32,"__builtin_sh_media_PREFO", SH_BLTIN_PSSV },
{ CODE_FOR_prefetch64,"__builtin_sh_media_PREFO", SH_BLTIN_PSSV }
#endif
@@ -7408,4 +7413,33 @@ sh_expand_builtin (exp, target, subtarget, mode, ignore)
emit_insn (pat);
return target;
}
+
+void
+sh_expand_unop_v2sf (code, op0, op1)
+ enum rtx_code code;
+ rtx op0, op1;
+{
+ rtx sel0 = const0_rtx;
+ rtx sel1 = const1_rtx;
+ rtx (*fn) (rtx, rtx, rtx, rtx, rtx) = gen_unary_sf_op;
+ rtx op = gen_rtx_fmt_e (code, SFmode, op1);
+
+ emit_insn ((*fn) (op0, op1, op, sel0, sel0));
+ emit_insn ((*fn) (op0, op1, op, sel1, sel1));
+}
+
+void
+sh_expand_binop_v2sf (code, op0, op1, op2)
+ enum rtx_code code;
+ rtx op0, op1, op2;
+{
+ rtx sel0 = const0_rtx;
+ rtx sel1 = const1_rtx;
+ rtx (*fn) (rtx, rtx, rtx, rtx, rtx, rtx, rtx) = gen_binary_sf_op;
+ rtx op = gen_rtx_fmt_ee (code, SFmode, op1, op2);
+
+ emit_insn ((*fn) (op0, op1, op2, op, sel0, sel0, sel0));
+ emit_insn ((*fn) (op0, op1, op2, op, sel1, sel1, sel1));
+}
+
#include "gt-sh.h"
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 9d15fcf..c37b10c 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -106,6 +106,9 @@ do { \
call_used_regs[MACH_REG] = 0; \
call_used_regs[MACL_REG] = 0; \
} \
+ for (regno = FIRST_FP_REG + (TARGET_LITTLE_ENDIAN != 0); \
+ regno <= LAST_FP_REG; regno += 2) \
+ SET_HARD_REG_BIT (reg_class_contents[DF_HI_REGS], regno); \
if (TARGET_SHMEDIA) \
{ \
for (regno = FIRST_TARGET_REG; regno <= LAST_TARGET_REG; regno ++)\
@@ -893,13 +896,16 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
would require a tertiary reload when reloading from / to memory,
and a secondary reload to reload from / to general regs; that
seems to be a loosing proposition. */
+/* We want to allow TImode FP regs so that when V4SFmode is loaded as TImode,
+ it won't be ferried through GP registers first. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
(SPECIAL_REGISTER_P (REGNO) ? (MODE) == SImode \
: (REGNO) == FPUL_REG ? (MODE) == SImode || (MODE) == SFmode \
: FP_REGISTER_P (REGNO) && (MODE) == SFmode \
? 1 \
: (MODE) == V2SFmode \
- ? (FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 2 == 0) \
+ ? ((FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 2 == 0) \
+ || (TARGET_SHMEDIA && GENERAL_REGISTER_P (REGNO))) \
: (MODE) == V4SFmode \
? (FP_REGISTER_P (REGNO) && ((REGNO) - FIRST_FP_REG) % 4 == 0) \
: (MODE) == V16SFmode \
@@ -912,7 +918,7 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
|| ((TARGET_SH3E || TARGET_SHMEDIA) && (MODE) == SCmode) \
|| (((TARGET_SH4 && (MODE) == DFmode) || (MODE) == DCmode \
|| (TARGET_SHMEDIA && ((MODE) == DFmode || (MODE) == DImode \
- || (MODE) == V2SFmode))) \
+ || (MODE) == V2SFmode || (MODE) == TImode))) \
&& (((REGNO) - FIRST_FP_REG) & 1) == 0)) \
: XD_REGISTER_P (REGNO) \
? (MODE) == DFmode \
@@ -1106,6 +1112,7 @@ enum reg_class
GENERAL_REGS,
FP0_REGS,
FP_REGS,
+ DF_HI_REGS,
DF_REGS,
FPSCR_REGS,
GENERAL_FP_REGS,
@@ -1129,6 +1136,7 @@ enum reg_class
"GENERAL_REGS", \
"FP0_REGS", \
"FP_REGS", \
+ "DF_HI_REGS", \
"DF_REGS", \
"FPSCR_REGS", \
"GENERAL_FP_REGS", \
@@ -1162,6 +1170,8 @@ enum reg_class
{ 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000 }, \
/* FP_REGS: */ \
{ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000 }, \
+/* DF_HI_REGS: Initialized in CONDITIONAL_REGISTER_USAGE. */ \
+ { 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x0000ff00 }, \
/* DF_REGS: */ \
{ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x0000ff00 }, \
/* FPSCR_REGS: */ \
@@ -1286,7 +1296,7 @@ extern const enum reg_class reg_class_from_letter[];
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,X) \
((((((CLASS) == FP_REGS || (CLASS) == FP0_REGS \
- || (CLASS) == DF_REGS) \
+ || (CLASS) == DF_REGS || (CLASS) == DF_HI_REGS) \
&& (GET_CODE (X) == REG && GENERAL_OR_AP_REGISTER_P (REGNO (X)))) \
|| (((CLASS) == GENERAL_REGS || (CLASS) == R0_REGS) \
&& GET_CODE (X) == REG \
@@ -1301,9 +1311,6 @@ extern const enum reg_class reg_class_from_letter[];
|| REGNO (X) == T_REG \
|| system_reg_operand (X, VOIDmode))))) \
? GENERAL_REGS \
- : (((CLASS) == FP_REGS || (CLASS) == DF_REGS) && TARGET_SHMEDIA \
- && immediate_operand ((X), (MODE))) \
- ? GENERAL_REGS \
: ((CLASS) == TARGET_REGS \
|| (TARGET_SHMEDIA && (CLASS) == SIBCALL_REGS)) \
? ((target_operand ((X), (MODE)) \
@@ -1312,10 +1319,14 @@ extern const enum reg_class reg_class_from_letter[];
: (((CLASS) == MAC_REGS || (CLASS) == PR_REGS) \
&& GET_CODE (X) == REG && ! GENERAL_REGISTER_P (REGNO (X)) \
&& (CLASS) != REGNO_REG_CLASS (REGNO (X))) \
+ ? GENERAL_REGS \
+ : ((CLASS) != GENERAL_REGS && GET_CODE (X) == REG \
+ && TARGET_REGISTER_P (REGNO (X))) \
? GENERAL_REGS : NO_REGS)
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS,MODE,X) \
- ((((CLASS) == FP_REGS || (CLASS) == FP0_REGS || (CLASS) == DF_REGS) \
+ ((((CLASS) == FP_REGS || (CLASS) == FP0_REGS || (CLASS) == DF_REGS \
+ || (CLASS) == DF_HI_REGS) \
&& ! TARGET_SHMEDIA \
&& immediate_operand ((X), (MODE)) \
&& ! ((fp_zero_operand (X) || fp_one_operand (X)) \
@@ -1334,6 +1345,12 @@ extern const enum reg_class reg_class_from_letter[];
&& ((GET_CODE (X) == REG && REGNO (X) >= FIRST_PSEUDO_REGISTER) \
|| (GET_CODE (X) == MEM && GET_CODE (XEXP ((X), 0)) == PLUS)))\
? GENERAL_REGS \
+ : (((CLASS) == FP_REGS || (CLASS) == DF_REGS || (CLASS) == DF_HI_REGS)\
+ && TARGET_SHMEDIA \
+ && immediate_operand ((X), (MODE)) \
+ && (X) != CONST0_RTX (GET_MODE (X)) \
+ && GET_MODE (X) != V4SFmode) \
+ ? GENERAL_REGS \
: SECONDARY_OUTPUT_RELOAD_CLASS((CLASS),(MODE),(X)))
/* Return the maximum number of consecutive registers
@@ -1345,13 +1362,17 @@ extern const enum reg_class reg_class_from_letter[];
/* If defined, gives a class of registers that cannot be used as the
operand of a SUBREG that changes the mode of the object illegally. */
+/* ??? We need to renumber the internal numbers for the frnn registers
+ when in little endian in order to allow mode size changes. */
-#define CLASS_CANNOT_CHANGE_MODE DF_REGS
+#define CLASS_CANNOT_CHANGE_MODE (TARGET_LITTLE_ENDIAN ? DF_REGS : DF_HI_REGS)
/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ && ((TARGET_LITTLE_ENDIAN && GET_MODE_SIZE (TO) < 8) \
+ || GET_MODE_SIZE (FROM) < 8))
/* Stack layout; function entry, exit and calling. */
@@ -2192,7 +2213,8 @@ while (0)
#define LEGITIMATE_CONSTANT_P(X) \
(TARGET_SHMEDIA \
- ? (GET_MODE (X) != DFmode \
+ ? ((GET_MODE (X) != DFmode \
+ && GET_MODE_CLASS (GET_MODE (X)) != MODE_VECTOR_FLOAT) \
|| (X) == CONST0_RTX (GET_MODE (X)) \
|| ! TARGET_SHMEDIA_FPU \
|| TARGET_SHMEDIA64) \
@@ -2316,10 +2338,7 @@ while (0)
/* A zero in any shape or form. */
#define EXTRA_CONSTRAINT_U(OP) \
- ((OP) == const0_rtx \
- || (GET_CODE (OP) == SUBREG && VECTOR_MODE_SUPPORTED_P(GET_MODE (OP)) \
- && SUBREG_REG (OP) == const0_rtx && SUBREG_BYTE (OP) == 0) \
- || GET_CODE (OP) == CONST_VECTOR && zero_vec_operand ((OP), VOIDmode))
+ ((OP) == CONST0_RTX (GET_MODE (OP)))
/* Any vector constant we can handle. */
#define EXTRA_CONSTRAINT_W(OP) \
@@ -2642,7 +2661,9 @@ while (0)
will either zero-extend or sign-extend. The value of this macro should
be the code that says which one of the two operations is implicitly
done, NIL if none. */
-#define LOAD_EXTEND_OP(MODE) SIGN_EXTEND
+/* FP registers can load SImode values, but don't implicitly sign-extend
+ them to DImode. */
+#define LOAD_EXTEND_OP(MODE) ((MODE) != SImode ? SIGN_EXTEND : NIL)
/* Define if loading short immediate values into registers sign extends. */
#define SHORT_IMMEDIATES_SIGN_EXTEND
@@ -2821,12 +2842,13 @@ while (0)
register information here is not used for SFmode. */
#define REGISTER_MOVE_COST(MODE, SRCCLASS, DSTCLASS) \
(((((DSTCLASS) == T_REGS) || ((DSTCLASS) == PR_REGS)) ? 10 \
- : ((((DSTCLASS) == FP0_REGS || (DSTCLASS) == FP_REGS || (DSTCLASS) == DF_REGS) \
+ : ((((DSTCLASS) == FP0_REGS || (DSTCLASS) == FP_REGS \
+ || (DSTCLASS) == DF_REGS || (DSTCLASS) == DF_HI_REGS) \
&& ((SRCCLASS) == GENERAL_REGS || (SRCCLASS) == R0_REGS)) \
|| (((DSTCLASS) == GENERAL_REGS || (DSTCLASS) == R0_REGS) \
&& ((SRCCLASS) == FP0_REGS || (SRCCLASS) == FP_REGS \
- || (SRCCLASS) == DF_REGS))) \
- ? (TARGET_SHMEDIA ? 2 \
+ || (SRCCLASS) == DF_REGS || (SRCCLASS) == DF_HI_REGS))) \
+ ? (TARGET_SHMEDIA ? 4 \
: TARGET_FMOVD ? 8 : 12) \
: (((DSTCLASS) == FPUL_REGS \
&& ((SRCCLASS) == GENERAL_REGS || (SRCCLASS) == R0_REGS)) \
@@ -3231,7 +3253,7 @@ extern int rtx_equal_function_value_matters;
{"arith_reg_dest", {SUBREG, REG}}, \
{"arith_reg_operand", {SUBREG, REG}}, \
{"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_VECTOR}}, \
- {"binary_float_operator", {PLUS, MULT}}, \
+ {"binary_float_operator", {PLUS, MINUS, MULT, DIV}}, \
{"commutative_float_operator", {PLUS, MULT}}, \
{"equality_comparison_operator", {EQ,NE}}, \
{"extend_reg_operand", {SUBREG, REG, TRUNCATE}}, \
@@ -3256,7 +3278,7 @@ extern int rtx_equal_function_value_matters;
{"sh_1el_vec", {CONST_VECTOR, PARALLEL}}, \
{"sh_rep_vec", {CONST_VECTOR, PARALLEL}}, \
{"symbol_ref_operand", {SYMBOL_REF}}, \
- {"zero_vec_operand", {CONST_VECTOR}},
+ {"unary_float_operator", {ABS, NEG, SQRT}}, \
/* Define this macro if it is advisable to hold scalars in registers
in a wider mode than that declared by the program. In such cases,
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 82c1fdc..c3ac6e1 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -1413,8 +1413,8 @@
(set (match_dup 6) (float:DF (match_dup 4)))
(set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
(set (match_dup 8) (fix:DI (match_dup 7)))
- (set (subreg:DI (match_operand:SI 0 "register_operand" "=r") 0)
- (sign_extend:DI (match_dup 9)))]
+ (set (match_operand:SI 0 "register_operand" "")
+ (truncate:SI (match_dup 8)))]
"TARGET_SHMEDIA_FPU"
"
{
@@ -1424,7 +1424,6 @@
operands[6] = gen_reg_rtx (DFmode);
operands[7] = gen_reg_rtx (DFmode);
operands[8] = gen_reg_rtx (DImode);
- operands[9] = gen_lowpart_common (SImode, operands[8]);
}")
(define_insn "udivsi3_i4"
@@ -3361,7 +3360,7 @@
patterns, but unary operators are ignored when matching constraints,
so we need separate patterns. */
(define_insn "truncdisi2"
- [(set (match_operand:SI 0 "register_operand" "=r,m,m,f,r,f")
+ [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
(truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
"TARGET_SHMEDIA"
"@
@@ -3375,7 +3374,7 @@
(define_insn "truncdihi2"
- [(set (match_operand:HI 0 "register_operand" "=?r,m")
+ [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
(truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
"TARGET_SHMEDIA"
"@
@@ -3384,12 +3383,17 @@
[(set_attr "type" "arith_media,store_media")
(set_attr "length" "8,4")])
+; N.B. we want sign-extension here because
+; - we need to be consistent with LOAD_EXTEND_OP and movqi
+; - only sign extension allows us to do signed compares transparently.
+; unsigned compares don't care about the kind of extension as long as
+; it's consistent.
(define_insn "truncdiqi2"
[(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
(truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
"TARGET_SHMEDIA"
"@
- andi %1, 255, %0
+ ori %1, -256, %0
st%M0.b %m0, %1"
[(set_attr "type" "arith_media,store")])
@@ -3558,7 +3562,7 @@
(define_insn "*movsi_media"
[(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
- (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,m,f,r,f,f,r,*b,T"))]
+ (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,m,f,rU,f,f,r,*b,T"))]
"TARGET_SHMEDIA_FPU
&& (register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
@@ -3570,7 +3574,7 @@
st%M0.l %m0, %1
fld%M1.s %m1, %0
fst%M0.s %m0, %1
- fmov.ls %1, %0
+ fmov.ls %N1, %0
fmov.sl %1, %0
fmov.s %1, %0
ptabs %1, %0
@@ -3856,7 +3860,7 @@
(define_insn "*movdi_media"
[(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
- (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,m,f,r,f,f,r,*b,T"))]
+ (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,m,f,rU,f,f,r,*b,T"))]
"TARGET_SHMEDIA_FPU
&& (register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode))"
@@ -3868,7 +3872,7 @@
st%M0.q %m0, %1
fld%M1.d %m1, %0
fst%M0.d %m0, %1
- fmov.qd %1, %0
+ fmov.qd %N1, %0
fmov.dq %1, %0
fmov.d %1, %0
ptabs %1, %0
@@ -4162,13 +4166,13 @@
(define_insn "movdf_media"
[(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
- (match_operand:DF 1 "general_movsrc_operand" "f,r,f,r,F,m,f,m,r"))]
+ (match_operand:DF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
"TARGET_SHMEDIA_FPU
&& (register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode))"
"@
fmov.d %1, %0
- fmov.qd %1, %0
+ fmov.qd %N1, %0
fmov.dq %1, %0
add %1, r63, %0
#
@@ -4689,29 +4693,35 @@
}
}")
-(define_insn "movv2sf_i"
- [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
- (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
- "TARGET_SHMEDIA_FPU
- && (fp_arith_reg_operand (operands[0], V2SFmode)
- || fp_arith_reg_operand (operands[1], V2SFmode))"
- "@
- #
- fld%M1.p %m1, %0
- fst%M0.p %m0, %1"
- [(set_attr "type" "*,fload_media,fstore_media")])
-
-(define_split
- [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f")
- (match_operand:V2SF 1 "nonimmediate_operand" "f"))]
- "TARGET_SHMEDIA_FPU && reload_completed
- && fp_arith_reg_operand (operands[0], V2SFmode)
- && fp_arith_reg_operand (operands[1], V2SFmode)"
- [(set (subreg:DF (match_dup 0) 0) (subreg:DF (match_dup 1) 0))])
+;;This is incompatible with the way gcc uses subregs.
+;;(define_insn "movv2sf_i"
+;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
+;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
+;; "TARGET_SHMEDIA_FPU
+;; && (fp_arith_reg_operand (operands[0], V2SFmode)
+;; || fp_arith_reg_operand (operands[1], V2SFmode))"
+;; "@
+;; #
+;; fld%M1.p %m1, %0
+;; fst%M0.p %m0, %1"
+;; [(set_attr "type" "*,fload_media,fstore_media")])
+
+(define_insn_and_split "movv2sf_i"
+ [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
+ (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfU?"))]
+ "TARGET_SHMEDIA_FPU"
+ "#"
+ "TARGET_SHMEDIA_FPU && reload_completed"
+ [(set (match_dup 0) (match_dup 1))]
+ "
+{
+ operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
+ operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
+}")
(define_expand "movv2sf"
- [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
- (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
+ [(set (match_operand:V2SF 0 "general_movdst_operand" "")
+ (match_operand:V2SF 1 "nonimmediate_operand" ""))]
"TARGET_SHMEDIA_FPU"
"
{
@@ -4719,9 +4729,53 @@
DONE;
}")
+(define_expand "addv2sf3"
+ [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
+ (match_operand:V2SF 1 "fp_arith_reg_operand" "")
+ (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
+ "TARGET_SHMEDIA_FPU"
+ "
+{
+ sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
+ DONE;
+}")
+
+(define_expand "subv2sf3"
+ [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
+ (match_operand:V2SF 1 "fp_arith_reg_operand" "")
+ (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
+ "TARGET_SHMEDIA_FPU"
+ "
+{
+ sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
+ DONE;
+}")
+
+(define_expand "mulv2sf3"
+ [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
+ (match_operand:V2SF 1 "fp_arith_reg_operand" "")
+ (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
+ "TARGET_SHMEDIA_FPU"
+ "
+{
+ sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
+ DONE;
+}")
+
+(define_expand "divv2sf3"
+ [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
+ (match_operand:V2SF 1 "fp_arith_reg_operand" "")
+ (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
+ "TARGET_SHMEDIA_FPU"
+ "
+{
+ sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
+ DONE;
+}")
+
(define_insn_and_split "*movv4sf_i"
[(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
- (match_operand:V4SF 1 "nonimmediate_operand" "f,m,f"))]
+ (match_operand:V4SF 1 "general_operand" "fU,m,f"))]
"TARGET_SHMEDIA_FPU"
"#"
"&& reload_completed"
@@ -4739,20 +4793,14 @@
plus_constant (XEXP (operands[0], 0),
i * GET_MODE_SIZE (V2SFmode)));
else
- {
- x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
- alter_subreg (&x);
- }
+ x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
if (GET_CODE (operands[1]) == MEM)
y = gen_rtx_MEM (V2SFmode,
plus_constant (XEXP (operands[1], 0),
i * GET_MODE_SIZE (V2SFmode)));
else
- {
- y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
- alter_subreg (&y);
- }
+ y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
emit_insn (gen_movv2sf_i (x, y));
}
@@ -4762,8 +4810,8 @@
[(set_attr "length" "8")])
(define_expand "movv4sf"
- [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
- (match_operand:V4SF 1 "nonimmediate_operand" "f,m,f"))]
+ [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
+ (match_operand:V4SF 1 "general_operand" ""))]
"TARGET_SHMEDIA_FPU"
"
{
@@ -4825,13 +4873,13 @@
(define_insn "movsf_media"
[(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
- (match_operand:SF 1 "general_movsrc_operand" "f,r,f,r,F,m,f,m,r"))]
+ (match_operand:SF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
"TARGET_SHMEDIA_FPU
&& (register_operand (operands[0], SFmode)
|| register_operand (operands[1], SFmode))"
"@
fmov.s %1, %0
- fmov.ls %1, %0
+ fmov.ls %N1, %0
fmov.sl %1, %0
add.l %1, r63, %0
#
@@ -4857,7 +4905,8 @@
(define_split
[(set (match_operand:SF 0 "arith_reg_operand" "")
(match_operand:SF 1 "immediate_operand" ""))]
- "TARGET_SHMEDIA && reload_completed"
+ "TARGET_SHMEDIA && reload_completed
+ && ! FP_REGISTER_P (true_regnum (operands[0]))"
[(set (match_dup 3) (match_dup 2))]
"
{
@@ -8041,6 +8090,72 @@
"fadd.s %1, %2, %0"
[(set_attr "type" "fparith_media")])
+(define_insn_and_split "unary_sf_op"
+ [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
+ (vec_select:V2SF
+ (vec_concat:V2SF
+ (vec_select:SF
+ (match_dup 0)
+ (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
+ (match_operator:SF 2 "unary_float_operator"
+ [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
+ (parallel [(match_operand 4
+ "const_int_operand" "n")]))]))
+ (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
+ "TARGET_SHMEDIA_FPU"
+ "#"
+ "TARGET_SHMEDIA_FPU && reload_completed"
+ [(set (match_dup 5) (match_dup 6))]
+ "
+{
+ int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
+ rtx op1 = gen_rtx_REG (SFmode,
+ (true_regnum (operands[1])
+ + (INTVAL (operands[4]) ^ endian)));
+
+ operands[7] = gen_rtx_REG (SFmode,
+ (true_regnum (operands[0])
+ + (INTVAL (operands[3]) ^ endian)));
+ operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
+}"
+ [(set_attr "type" "fparith_media")])
+
+(define_insn_and_split "binary_sf_op"
+ [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
+ (vec_select:V2SF
+ (vec_concat:V2SF
+ (vec_select:SF
+ (match_dup 0)
+ (parallel [(not:BI (match_operand 4 "const_int_operand" "n"))]))
+ (match_operator:SF 3 "binary_float_operator"
+ [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
+ (parallel [(match_operand 5
+ "const_int_operand" "n")]))
+ (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
+ (parallel [(match_operand 6
+ "const_int_operand" "n")]))]))
+ (parallel [(not:BI (match_dup 4)) (match_dup 4)])))]
+ "TARGET_SHMEDIA_FPU"
+ "#"
+ "TARGET_SHMEDIA_FPU && reload_completed"
+ [(set (match_dup 7) (match_dup 8))]
+ "
+{
+ int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
+ rtx op1 = gen_rtx_REG (SFmode,
+ (true_regnum (operands[1])
+ + (INTVAL (operands[5]) ^ endian)));
+ rtx op2 = gen_rtx_REG (SFmode,
+ (true_regnum (operands[2])
+ + (INTVAL (operands[6]) ^ endian)));
+
+ operands[7] = gen_rtx_REG (SFmode,
+ (true_regnum (operands[0])
+ + (INTVAL (operands[4]) ^ endian)));
+ operands[8] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
+}"
+ [(set_attr "type" "fparith_media")])
+
(define_insn "addsf3_i"
[(set (match_operand:SF 0 "arith_reg_operand" "=f")
(plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
@@ -9228,7 +9343,7 @@
"TARGET_SHMEDIA && reload_completed
&& GET_MODE (operands[0]) == GET_MODE (operands[1])
&& VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
- && ! zero_vec_operand (operands[1], VOIDmode)"
+ && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
[(set (match_dup 0) (match_dup 1))]
"
{
@@ -9482,85 +9597,85 @@
; mextrN can be modelled with vec_select / vec_concat, but the selection
; vector then varies depending on endianness.
(define_expand "mextr1"
- [(match_operand:V8QI 0 "arith_reg_dest" "")
- (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
- (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ [(match_operand:DI 0 "arith_reg_dest" "")
+ (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
"TARGET_SHMEDIA"
"
{
- emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
+ emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
GEN_INT (1 * 8), GEN_INT (7 * 8)));
DONE;
}")
(define_expand "mextr2"
- [(match_operand:V8QI 0 "arith_reg_dest" "")
- (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
- (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ [(match_operand:DI 0 "arith_reg_dest" "")
+ (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
"TARGET_SHMEDIA"
"
{
- emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
+ emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
GEN_INT (2 * 8), GEN_INT (6 * 8)));
DONE;
}")
(define_expand "mextr3"
- [(match_operand:V8QI 0 "arith_reg_dest" "")
- (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
- (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ [(match_operand:DI 0 "arith_reg_dest" "")
+ (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
"TARGET_SHMEDIA"
"
{
- emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
+ emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
GEN_INT (3 * 8), GEN_INT (5 * 8)));
DONE;
}")
(define_expand "mextr4"
- [(match_operand:V8QI 0 "arith_reg_dest" "")
- (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
- (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ [(match_operand:DI 0 "arith_reg_dest" "")
+ (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
"TARGET_SHMEDIA"
"
{
- emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
+ emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
GEN_INT (4 * 8), GEN_INT (4 * 8)));
DONE;
}")
(define_expand "mextr5"
- [(match_operand:V8QI 0 "arith_reg_dest" "")
- (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
- (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ [(match_operand:DI 0 "arith_reg_dest" "")
+ (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
"TARGET_SHMEDIA"
"
{
- emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
+ emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
GEN_INT (5 * 8), GEN_INT (3 * 8)));
DONE;
}")
(define_expand "mextr6"
- [(match_operand:V8QI 0 "arith_reg_dest" "")
- (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
- (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ [(match_operand:DI 0 "arith_reg_dest" "")
+ (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
"TARGET_SHMEDIA"
"
{
- emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
+ emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
GEN_INT (6 * 8), GEN_INT (2 * 8)));
DONE;
}")
(define_expand "mextr7"
- [(match_operand:V8QI 0 "arith_reg_dest" "")
- (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
- (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
+ [(match_operand:DI 0 "arith_reg_dest" "")
+ (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+ (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
"TARGET_SHMEDIA"
"
{
- emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
+ emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
GEN_INT (7 * 8), GEN_INT (1 * 8)));
DONE;
}")
@@ -9705,7 +9820,7 @@
(mult:V4SI
(sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
(sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
- (const_vector [(const_int 2) (const_int 3)])))]
+ (parallel [(const_int 2) (const_int 3)])))]
"TARGET_SHMEDIA"
"* return (TARGET_LITTLE_ENDIAN
? \"mmulhi.wl %1, %2, %0\"
@@ -9718,7 +9833,7 @@
(mult:V4SI
(sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
(sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
- (const_vector [(const_int 0) (const_int 1)])))]
+ (parallel [(const_int 0) (const_int 1)])))]
"TARGET_SHMEDIA"
"* return (TARGET_LITTLE_ENDIAN
? \"mmullo.wl %1, %2, %0\"
@@ -9747,17 +9862,17 @@
(mult:V4DI
(sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
(sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
- (const_vector [(const_int 0)]))
+ (parallel [(const_int 0)]))
(vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
(sign_extend:V4DI (match_dup 3)))
- (const_vector [(const_int 1)])))
+ (parallel [(const_int 1)])))
(plus:DI
(vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
(sign_extend:V4DI (match_dup 3)))
- (const_vector [(const_int 2)]))
+ (parallel [(const_int 2)]))
(vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
(sign_extend:V4DI (match_dup 3)))
- (const_vector [(const_int 3)]))))))]
+ (parallel [(const_int 3)]))))))]
"TARGET_SHMEDIA"
"mmulsum.wq %2, %3, %0"
[(set_attr "type" "mac_media")])
@@ -9838,32 +9953,32 @@
(match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
(zero_extend:V8DI
(match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
- (const_vector [(const_int 0)]))))
+ (parallel [(const_int 0)]))))
(abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
(zero_extend:V8DI (match_dup 3)))
- (const_vector [(const_int 1)]))))
+ (parallel [(const_int 1)]))))
(plus:DI
(abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
(zero_extend:V8DI (match_dup 3)))
- (const_vector [(const_int 2)])))
+ (parallel [(const_int 2)])))
(abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
(zero_extend:V8DI (match_dup 3)))
- (const_vector [(const_int 3)])))))
+ (parallel [(const_int 3)])))))
(plus:DI
(plus:DI
(abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
(zero_extend:V8DI (match_dup 3)))
- (const_vector [(const_int 4)])))
+ (parallel [(const_int 4)])))
(abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
(zero_extend:V8DI (match_dup 3)))
- (const_vector [(const_int 5)]))))
+ (parallel [(const_int 5)]))))
(plus:DI
(abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
(zero_extend:V8DI (match_dup 3)))
- (const_vector [(const_int 6)])))
+ (parallel [(const_int 6)])))
(abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
(zero_extend:V8DI (match_dup 3)))
- (const_vector [(const_int 7)])))))))]
+ (parallel [(const_int 7)])))))))]
"TARGET_SHMEDIA"
"msad.ubq %N2, %N3, %0"
[(set_attr "type" "mac_media")])
@@ -9945,8 +10060,8 @@
(vec_select:V8QI
(vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
(match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
- (const_vector [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
- (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
+ (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
+ (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
"TARGET_SHMEDIA"
"* return (TARGET_LITTLE_ENDIAN
? \"mshfhi.b %N1, %N2, %0\"
@@ -9959,8 +10074,8 @@
(vec_select:V8QI
(vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
(match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
- (const_vector [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
- (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
+ (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
+ (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
"TARGET_SHMEDIA"
"* return (TARGET_LITTLE_ENDIAN
? \"mshflo.b %N1, %N2, %0\"
@@ -9996,7 +10111,7 @@
(vec_select:V2SI
(vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
(match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
- (const_vector [(const_int 1) (const_int 3)])))]
+ (parallel [(const_int 1) (const_int 3)])))]
"TARGET_SHMEDIA"
"* return (TARGET_LITTLE_ENDIAN
? \"mshfhi.l %N1, %N2, %0\"
@@ -10008,7 +10123,7 @@
(vec_select:V2SI
(vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
(match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
- (const_vector [(const_int 0) (const_int 2)])))]
+ (parallel [(const_int 0) (const_int 2)])))]
"TARGET_SHMEDIA"
"* return (TARGET_LITTLE_ENDIAN
? \"mshflo.l %N1, %N2, %0\"
@@ -10044,7 +10159,7 @@
(vec_select:V4HI
(vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
(match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
- (const_vector [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
+ (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
"TARGET_SHMEDIA"
"* return (TARGET_LITTLE_ENDIAN
? \"mshfhi.w %N1, %N2, %0\"
@@ -10056,22 +10171,45 @@
(vec_select:V4HI
(vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
(match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
- (const_vector [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
+ (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
"TARGET_SHMEDIA"
"* return (TARGET_LITTLE_ENDIAN
? \"mshflo.w %N1, %N2, %0\"
: \"mshfhi.w %N1, %N2, %0\");"
[(set_attr "type" "arith_media")])
+(define_insn "mshflo_w_x"
+ [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
+ (vec_select:V4HI
+ (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rU")
+ (match_operand:V2HI 2 "extend_reg_or_0_operand" "rU"))
+ (parallel [(const_int 0) (const_int 2) (const_int 1) (const_int 3)])))]
+ "TARGET_SHMEDIA"
+ "mshflo.w %N1, %N2, %0"
+ [(set_attr "type" "arith_media")])
+
/* These are useful to expand ANDs and as combiner patterns. */
-(define_insn "mshfhi_l_di"
- [(set (match_operand:DI 0 "arith_reg_dest" "=r")
- (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
+(define_insn_and_split "mshfhi_l_di"
+ [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
+ (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU,f")
(const_int 32))
- (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
+ (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU,?f")
(const_int -4294967296))))]
"TARGET_SHMEDIA"
- "mshfhi.l %N1, %N2, %0"
+ "@
+ mshfhi.l %N1, %N2, %0
+ #"
+ "TARGET_SHMEDIA && reload_completed
+ && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
+ [(set (match_dup 3) (match_dup 4))
+ (set (match_dup 5) (match_dup 6))]
+ "
+{
+ operands[3] = gen_lowpart (SImode, operands[0]);
+ operands[4] = gen_highpart (SImode, operands[1]);
+ operands[5] = gen_highpart (SImode, operands[0]);
+ operands[6] = gen_highpart (SImode, operands[2]);
+}"
[(set_attr "type" "arith_media")])
(define_insn "*mshfhi_l_di_rev"
@@ -10127,7 +10265,8 @@
(define_insn "*mshflo_l_di_x"
[(set (match_operand:DI 0 "arith_reg_dest" "=r")
- (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand" "rU"))
+ (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
+ "rU"))
(ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
(const_int 32))))]
@@ -10135,6 +10274,28 @@
"mshflo.l %N1, %N2, %0"
[(set_attr "type" "arith_media")])
+(define_insn_and_split "concat_v2sf"
+ [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
+;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,0,f")
+ (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,f,f")
+ (match_operand:SF 2 "register_operand" "rU,f,f")))]
+
+ "TARGET_SHMEDIA"
+ "@
+ mshflo.l %N1, %N2, %0
+ #
+ #"
+ "TARGET_SHMEDIA && reload_completed
+ && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 4) (match_dup 2))]
+ "
+{
+ operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
+ operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
+}"
+ [(set_attr "type" "arith_media")])
+
(define_insn "*mshflo_l_di_x_rev"
[(set (match_operand:DI 0 "arith_reg_dest" "=r")
(ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
@@ -10241,13 +10402,13 @@
"fp_arith_reg_operand" "f")
(match_operand:V4SF 2
"fp_arith_reg_operand" "f"))
- (const_vector [(const_int 0)]))
+ (parallel [(const_int 0)]))
(vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
- (const_vector [(const_int 1)])))
+ (parallel [(const_int 1)])))
(plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
- (const_vector [(const_int 2)]))
+ (parallel [(const_int 2)]))
(vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
- (const_vector [(const_int 3)])))))]
+ (parallel [(const_int 3)])))))]
"TARGET_SHMEDIA"
"fipr %1, %2, %0"
[(set_attr "type" "fparith_media")])
@@ -10266,31 +10427,31 @@
(plus:V4SF
(mult:V4SF
(vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
- (const_vector [(const_int 0) (const_int 5)
- (const_int 10) (const_int 15)]))
+ (parallel [(const_int 0) (const_int 5)
+ (const_int 10) (const_int 15)]))
(match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
(mult:V4SF
(vec_select:V4SF (match_dup 1)
- (const_vector [(const_int 4) (const_int 9)
- (const_int 14) (const_int 3)]))
+ (parallel [(const_int 4) (const_int 9)
+ (const_int 14) (const_int 3)]))
(vec_select:V4SF (match_dup 2)
- (const_vector [(const_int 1) (const_int 2)
- (const_int 3) (const_int 0)]))))
+ (parallel [(const_int 1) (const_int 2)
+ (const_int 3) (const_int 0)]))))
(plus:V4SF
(mult:V4SF
(vec_select:V4SF (match_dup 1)
- (const_vector [(const_int 8) (const_int 13)
- (const_int 2) (const_int 7)]))
+ (parallel [(const_int 8) (const_int 13)
+ (const_int 2) (const_int 7)]))
(vec_select:V4SF (match_dup 2)
- (const_vector [(const_int 2) (const_int 3)
- (const_int 0) (const_int 1)])))
+ (parallel [(const_int 2) (const_int 3)
+ (const_int 0) (const_int 1)])))
(mult:V4SF
(vec_select:V4SF (match_dup 1)
- (const_vector [(const_int 12) (const_int 1)
- (const_int 6) (const_int 11)]))
+ (parallel [(const_int 12) (const_int 1)
+ (const_int 6) (const_int 11)]))
(vec_select:V4SF (match_dup 2)
- (const_vector [(const_int 3) (const_int 0)
- (const_int 1) (const_int 2)]))))))]
+ (parallel [(const_int 3) (const_int 0)
+ (const_int 1) (const_int 2)]))))))]
"TARGET_SHMEDIA"
"ftrv %1, %2, %0"
[(set_attr "type" "fparith_media")])