diff options
author | J"orn Rennecke <joern.rennecke@superh.com> | 2002-07-17 15:15:04 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 2002-07-17 16:15:04 +0100 |
commit | 0ac785173d96fc8d058ed817cf9286ddaf6d831a (patch) | |
tree | db9bf553918d31a90a5fa97d75bef6b5cb9d0e87 /gcc | |
parent | d955f6ea6f555019be4227cb1f48b691483cf275 (diff) | |
download | gcc-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/ChangeLog | 51 | ||||
-rw-r--r-- | gcc/config/sh/sh-protos.h | 3 | ||||
-rw-r--r-- | gcc/config/sh/sh.c | 104 | ||||
-rw-r--r-- | gcc/config/sh/sh.h | 62 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 405 |
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")]) |