diff options
author | Trevor Smigiel <Trevor_Smigiel@playstation.sony.com> | 2007-02-21 23:28:46 +0000 |
---|---|---|
committer | Trevor Smigiel <tsmigiel@gcc.gnu.org> | 2007-02-21 23:28:46 +0000 |
commit | 73701e27366b20395ad5c3e296983b20ae0235b1 (patch) | |
tree | 8e9c6dc9eb86af757f25cdc1cdc8310d88ab4222 /gcc | |
parent | c0bca7e18124cf5b3097f1422d12c5f9f01e3344 (diff) | |
download | gcc-73701e27366b20395ad5c3e296983b20ae0235b1.zip gcc-73701e27366b20395ad5c3e296983b20ae0235b1.tar.gz gcc-73701e27366b20395ad5c3e296983b20ae0235b1.tar.bz2 |
Change the defaults of some parameters and options.
2007-02-21 Trevor Smigiel <trevor_smigiel@playstation.sony.com>
Change the defaults of some parameters and options.
* config/spu/spu-protos.h (spu_optimization_options): Declare.
* config/spu/spu.c (spu_optimization_options): Add.
(spu_override_options): Change params in spu_optimization_options.
* config/spu/spu.h (OPTIMIZATION_OPTIONS): Define.
Register 127 is only 16 byte aligned when used as a frame pointer.
* config/spu/spu-protos.h (spu_init_expanders): Declare.
* config/spu/spu.c (spu_expand_prologue): Set REGNO_POINTER_ALIGN for
HARD_FRAME_POINTER_REGNUM.
(spu_legitimate_address): Use regno_aligned_for_reload.
(regno_aligned_for_load): HARD_FRAME_POINTER_REGNUM is only 16 byte
aligned when frame_pointer_needed is true.
(spu_init_expanders): New. Set alignment of HARD_FRAME_POINTER_REGNUM
to 8 bits.
* config/spu/spu.h (INIT_EXPANDERS): Define.
Make sure shift and rotate instructions have valid immediate operands.
* config/spu/predicates.md (spu_shift_operand): Remove.
* config/spu/spu.c (print_operand): Add [efghEFGH] modifiers.
* config/spu/constraints.md (W, O): Extend range.
* config/spu/spu.md (umask, nmask): Define.
(ashl<mode>3, ashldi3, ashlti3_imm, shlqbybi_ti, shlqbi_ti, shlqby_ti,
lshr<mode>3, rotm_<mode>, lshr<mode>3_imm, rotqmbybi_<mode>,
rotqmbi_<mode>, rotqmby_<mode>, ashr<mode>3, rotma_<mode>,
rotl<mode>3, rotlti3, rotqbybi_ti, rotqby_ti, rotqbi_ti): Use
spu_nonmem_operand instead of spu_shift_operands. Use new modifiers.
(lshr<mode>3_reg): Fix rtl description.
Make sure mulhisi immediate operands are valid.
* config/spu/predicates.md (imm_K_operand): Add.
* config/spu/spu.md (mulhisi3_imm, umulhisi3_imm): Use imm_K_operand.
Generate constants using fsmbi and andi.
* config/spu/spu.c (enum immediate_class): Add IC_FSMBI2.
(print_operand, spu_split_immediate, classify_immediate,
fsmbi_const_p): Handle IC_FSMBI2.
Correctly handle a CONST_VECTOR containing symbols.
* config/spu/spu.c (print_operand): Handle HIGH correctly.
(spu_split_immediate): Split CONST_VECTORs with -mlarge-mem.
(immediate_load_p): Allow symbols that use 2 instructions to create.
(classify_immediate, spu_builtin_splats): Don't accept a CONST_VECTOR
with symbols when flag_pic is set.
(const_vector_immediate_p): New.
(logical_immediate_p, iohl_immediate_p, arith_immediate_p): Don't
accept a CONST_VECTOR with symbols.
(spu_legitimate_constant_p): Use const_vector_immediate_p. Don't
accept a CONST_VECTOR with symbols when flag_pic is set. Handle HIGH
correctly.
* config/spu/spu.md (high, low): Delete.
(low_<mode>): Define.
Remove INTRmode and INTR_REGNUM, which didn't work.
* config/spu/spu.c (spu_conditional_register_usage): Remove reference
of INTR_REGNUM.
* config/spu/spu-builtins.md (spu_idisable, spu_ienable, set_intr,
set_intr_pic, set_intr_cc, set_intr_cc_pic, set_intr_return, unnamed
peephole2 pattern): Don't use INTR or 131.
(movintrcc): Delete.
* config/spu/spu.h (FIRST_PSEUDO_REGISTER, FIXED_REGISTERS,
CALL_USED_REGISTERS, REGISTER_NAMES, INTR_REGNUM): Remove INTR_REGNUM.
* config/spu/spu.md (UNSPEC_IDISABLE, UNSPEC_IENABLE): Remove.
(UNSPEC_SET_INTR): Add.
* config/spu/spu-modes.def (INTR): Remove.
More accurate warnings about run-time relocations.
* config/spu/spu.c (reloc_diagnostic): Test in_section.
Correctly warn about immediate arguments to specific intrinsics.
* config/spu/spu.c (spu_check_builtin_parm): Handle CONST_VECTORs.
(spu_expand_builtin_1): Call spu_check_builtin_parm before checking
the instruction predicate.
Fix tree check errors with latest update.
* config/spu/spu.c (expand_builtin_args, spu_expand_builtin_1): Use
CALL_EXPR_ARG.
(spu_expand_builtin): Use CALL_EXPR_FN.
Add missing specific intrinsics.
* config/spu/spu-builtins.def: Add si_bisled, si_bisledd and
si_bislede.
* config/spu/spu_internals.h: Ditto.
Fix incorrect operand modifiers.
* config/spu/spu-builtins.md (spu_mpy, spu_mpyu): Remove use of %H.
* config/spu/spu.md (xor<mode>3): Change %S to %J.
Optimize one case of zero_extend of a vec_select.
* config/spu/spu.md (_vec_extractv8hi_ze): Add.
Accept any immediate for hbr.
* config/spu/spu.md (hbr): Change s constraints to i.
From-SVN: r122210
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 96 | ||||
-rw-r--r-- | gcc/config/spu/constraints.md | 4 | ||||
-rw-r--r-- | gcc/config/spu/predicates.md | 12 | ||||
-rw-r--r-- | gcc/config/spu/spu-builtins.def | 3 | ||||
-rw-r--r-- | gcc/config/spu/spu-builtins.md | 68 | ||||
-rw-r--r-- | gcc/config/spu/spu-modes.def | 4 | ||||
-rw-r--r-- | gcc/config/spu/spu-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/spu/spu.c | 268 | ||||
-rw-r--r-- | gcc/config/spu/spu.h | 16 | ||||
-rw-r--r-- | gcc/config/spu/spu.md | 109 | ||||
-rw-r--r-- | gcc/config/spu/spu_internals.h | 3 |
11 files changed, 404 insertions, 181 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 37f33bb..f85cc79 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,99 @@ +2007-02-21 Trevor Smigiel <trevor_smigiel@playstation.sony.com> + + Change the defaults of some parameters and options. + * config/spu/spu-protos.h (spu_optimization_options): Declare. + * config/spu/spu.c (spu_optimization_options): Add. + (spu_override_options): Change params in spu_optimization_options. + * config/spu/spu.h (OPTIMIZATION_OPTIONS): Define. + + Register 127 is only 16 byte aligned when used as a frame pointer. + * config/spu/spu-protos.h (spu_init_expanders): Declare. + * config/spu/spu.c (spu_expand_prologue): Set REGNO_POINTER_ALIGN for + HARD_FRAME_POINTER_REGNUM. + (spu_legitimate_address): Use regno_aligned_for_reload. + (regno_aligned_for_load): HARD_FRAME_POINTER_REGNUM is only 16 byte + aligned when frame_pointer_needed is true. + (spu_init_expanders): New. Set alignment of HARD_FRAME_POINTER_REGNUM + to 8 bits. + * config/spu/spu.h (INIT_EXPANDERS): Define. + + Make sure shift and rotate instructions have valid immediate operands. + * config/spu/predicates.md (spu_shift_operand): Remove. + * config/spu/spu.c (print_operand): Add [efghEFGH] modifiers. + * config/spu/constraints.md (W, O): Extend range. + * config/spu/spu.md (umask, nmask): Define. + (ashl<mode>3, ashldi3, ashlti3_imm, shlqbybi_ti, shlqbi_ti, shlqby_ti, + lshr<mode>3, rotm_<mode>, lshr<mode>3_imm, rotqmbybi_<mode>, + rotqmbi_<mode>, rotqmby_<mode>, ashr<mode>3, rotma_<mode>, + rotl<mode>3, rotlti3, rotqbybi_ti, rotqby_ti, rotqbi_ti): Use + spu_nonmem_operand instead of spu_shift_operands. Use new modifiers. + (lshr<mode>3_reg): Fix rtl description. + + Make sure mulhisi immediate operands are valid. + * config/spu/predicates.md (imm_K_operand): Add. + * config/spu/spu.md (mulhisi3_imm, umulhisi3_imm): Use imm_K_operand. + + Generate constants using fsmbi and andi. + * config/spu/spu.c (enum immediate_class): Add IC_FSMBI2. + (print_operand, spu_split_immediate, classify_immediate, + fsmbi_const_p): Handle IC_FSMBI2. + + Correctly handle a CONST_VECTOR containing symbols. + * config/spu/spu.c (print_operand): Handle HIGH correctly. + (spu_split_immediate): Split CONST_VECTORs with -mlarge-mem. + (immediate_load_p): Allow symbols that use 2 instructions to create. + (classify_immediate, spu_builtin_splats): Don't accept a CONST_VECTOR + with symbols when flag_pic is set. + (const_vector_immediate_p): New. + (logical_immediate_p, iohl_immediate_p, arith_immediate_p): Don't + accept a CONST_VECTOR with symbols. + (spu_legitimate_constant_p): Use const_vector_immediate_p. Don't + accept a CONST_VECTOR with symbols when flag_pic is set. Handle HIGH + correctly. + * config/spu/spu.md (high, low): Delete. + (low_<mode>): Define. + + Remove INTRmode and INTR_REGNUM, which didn't work. + * config/spu/spu.c (spu_conditional_register_usage): Remove reference + of INTR_REGNUM. + * config/spu/spu-builtins.md (spu_idisable, spu_ienable, set_intr, + set_intr_pic, set_intr_cc, set_intr_cc_pic, set_intr_return, unnamed + peephole2 pattern): Don't use INTR or 131. + (movintrcc): Delete. + * config/spu/spu.h (FIRST_PSEUDO_REGISTER, FIXED_REGISTERS, + CALL_USED_REGISTERS, REGISTER_NAMES, INTR_REGNUM): Remove INTR_REGNUM. + * config/spu/spu.md (UNSPEC_IDISABLE, UNSPEC_IENABLE): Remove. + (UNSPEC_SET_INTR): Add. + * config/spu/spu-modes.def (INTR): Remove. + + More accurate warnings about run-time relocations. + * config/spu/spu.c (reloc_diagnostic): Test in_section. + + Correctly warn about immediate arguments to specific intrinsics. + * config/spu/spu.c (spu_check_builtin_parm): Handle CONST_VECTORs. + (spu_expand_builtin_1): Call spu_check_builtin_parm before checking + the instruction predicate. + + Fix tree check errors with latest update. + * config/spu/spu.c (expand_builtin_args, spu_expand_builtin_1): Use + CALL_EXPR_ARG. + (spu_expand_builtin): Use CALL_EXPR_FN. + + Add missing specific intrinsics. + * config/spu/spu-builtins.def: Add si_bisled, si_bisledd and + si_bislede. + * config/spu/spu_internals.h: Ditto. + + Fix incorrect operand modifiers. + * config/spu/spu-builtins.md (spu_mpy, spu_mpyu): Remove use of %H. + * config/spu/spu.md (xor<mode>3): Change %S to %J. + + Optimize one case of zero_extend of a vec_select. + * config/spu/spu.md (_vec_extractv8hi_ze): Add. + + Accept any immediate for hbr. + * config/spu/spu.md (hbr): Change s constraints to i. + 2007-02-21 Paul Brook <paul@codesourcery.com> * config/arm/arm.c (thumb2_final_prescan_insn): Don't incrememnt diff --git a/gcc/config/spu/constraints.md b/gcc/config/spu/constraints.md index abc319b..1006b07 100644 --- a/gcc/config/spu/constraints.md +++ b/gcc/config/spu/constraints.md @@ -53,7 +53,7 @@ (define_constraint "W" "An immediate for shift and rotate instructions. const_int is treated as a 32-bit value." (and (match_code "const_int,const_double,const_vector") - (match_test "arith_immediate_p (op, SImode, -0x40, 0x3f)"))) + (match_test "arith_immediate_p (op, SImode, -0x80000000ll, 0x7fffffffll)"))) (define_constraint "Y" "An immediate for and/xor/or instructions. const_int is sign extended as a 128 bit." @@ -131,7 +131,7 @@ (define_constraint "O" "An unsigned 7-bit constant whose 3 least significant bits are 0." (and (match_code "const_int") - (match_test "ival >= 0 && ival <= 0x7f && (ival & 7) == 0"))) + (match_test "(ival & 7) == 0"))) (define_constraint "P" "An unsigned 3-bit constant for 16-byte rotates and shifts" diff --git a/gcc/config/spu/predicates.md b/gcc/config/spu/predicates.md index 9d343e6..8b31e65 100644 --- a/gcc/config/spu/predicates.md +++ b/gcc/config/spu/predicates.md @@ -85,15 +85,9 @@ return 0; }) -(define_predicate "spu_shift_operand" - (match_code "reg,subreg,const_int,const_vector") - { - if (spu_reg_operand (op, mode)) - return 1; - if (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_VECTOR) - return arith_immediate_p (op, mode, -0x40, 0x3f); - return 0; - }) +(define_predicate "imm_K_operand" + (and (match_code "const_int") + (match_test "arith_immediate_p (op, mode, -0x200, 0x1ff)"))) ;; Return 1 if OP is a comparison operation that is valid for a branch insn. ;; We only check the opcode against the mode of the register value here. diff --git a/gcc/config/spu/spu-builtins.def b/gcc/config/spu/spu-builtins.def index c8b7851..6ae382f 100644 --- a/gcc/config/spu/spu-builtins.def +++ b/gcc/config/spu/spu-builtins.def @@ -163,6 +163,9 @@ DEF_BUILTIN (SI_CLGTH, CODE_FOR_clgt_v8hi, "si_clgth", B_INSN, DEF_BUILTIN (SI_CLGTHI, CODE_FOR_clgt_v8hi, "si_clgthi", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) DEF_BUILTIN (SI_CLGT, CODE_FOR_clgt_v4si, "si_clgt", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) DEF_BUILTIN (SI_CLGTI, CODE_FOR_clgt_v4si, "si_clgti", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_S10)) +DEF_BUILTIN (SI_BISLED, CODE_FOR_spu_bisled, "si_bisled", B_BISLED, _A3(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_PTR)) +DEF_BUILTIN (SI_BISLEDD, CODE_FOR_spu_bisledd, "si_bisledd", B_BISLED, _A3(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_PTR)) +DEF_BUILTIN (SI_BISLEDE, CODE_FOR_spu_bislede, "si_bislede", B_BISLED, _A3(SPU_BTI_VOID, SPU_BTI_QUADWORD, SPU_BTI_PTR)) DEF_BUILTIN (SI_FA, CODE_FOR_addv4sf3, "si_fa", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) DEF_BUILTIN (SI_DFA, CODE_FOR_addv2df3, "si_dfa", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) DEF_BUILTIN (SI_FS, CODE_FOR_subv4sf3, "si_fs", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD)) diff --git a/gcc/config/spu/spu-builtins.md b/gcc/config/spu/spu-builtins.md index 9b9a21b..5cd3b54 100644 --- a/gcc/config/spu/spu-builtins.md +++ b/gcc/config/spu/spu-builtins.md @@ -213,7 +213,7 @@ "" "@ mpy\t%0,%1,%2 - mpyi\t%0,%1,%H2" + mpyi\t%0,%1,%2" [(set_attr "type" "fp7")]) (define_insn "spu_mpyu" @@ -230,7 +230,7 @@ "" "@ mpyu\t%0,%1,%2 - mpyui\t%0,%1,%H2" + mpyui\t%0,%1,%2" [(set_attr "type" "fp7")]) (define_insn "spu_mpya" @@ -607,12 +607,9 @@ [(set_attr "type" "br")]) ;; interrupt disable/enable -;; Register 131 is used exclusively for enabling/disabling interrupts. -;; It is marked as a global reg and the instructions clobber mem, so it will -;; not be incorrectly optimized. (define_expand "spu_idisable" [(parallel - [(set (reg:INTR 131) (const_int 0)) + [(unspec_volatile [(const_int 0)] UNSPEC_SET_INTR) (clobber (match_dup:SI 0)) (clobber (mem:BLK (scratch)))])] "" @@ -620,14 +617,14 @@ (define_expand "spu_ienable" [(parallel - [(set (reg:INTR 131) (const_int 1)) + [(unspec_volatile [(const_int 1)] UNSPEC_SET_INTR) (clobber (match_dup:SI 0)) (clobber (mem:BLK (scratch)))])] "" "operands[0] = gen_reg_rtx (SImode);") (define_insn "set_intr" - [(set (reg:INTR 131) (match_operand 1 "const_int_operand" "i")) + [(unspec_volatile [(match_operand 1 "const_int_operand" "i")] UNSPEC_SET_INTR) (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) (clobber (mem:BLK (scratch)))] "! flag_pic" @@ -636,7 +633,7 @@ (set_attr "type" "multi0")]) (define_insn "set_intr_pic" - [(set (reg:INTR 131) (match_operand 1 "const_int_operand" "i")) + [(unspec_volatile [(match_operand 1 "const_int_operand" "i")] UNSPEC_SET_INTR) (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) (clobber (mem:BLK (scratch)))] "flag_pic" @@ -644,53 +641,32 @@ [(set_attr "length" "12") (set_attr "type" "multi1")]) -(define_expand "movintrcc" - [(parallel - [(set (match_operand:INTR 0 "spu_reg_operand" "") - (if_then_else:INTR (match_operand 1 "branch_comparison_operator" "") - (match_operand 3 "const_int_operand" "") - (match_operand:INTR 2 "spu_reg_operand" ""))) - (clobber (match_dup:SI 4)) - (clobber (mem:BLK (scratch)))])] - "" - { /* We've swapped operands 2 and 3 in the pattern, reverse the - condition code too. */ - PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1]))); - operands[4] = gen_reg_rtx (SImode); - }) - (define_insn "set_intr_cc" - [(set (reg:INTR 131) - (if_then_else:INTR - (match_operator 1 "branch_comparison_operator" - [(match_operand 2 "spu_reg_operand" "r") - (const_int 0)]) - (match_operand:SI 3 "const_int_operand" "i") - (reg:INTR 131))) - (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) - (clobber (mem:BLK (scratch)))] + [(cond_exec (match_operator 1 "branch_comparison_operator" + [(match_operand 2 "spu_reg_operand" "r") + (const_int 0)]) + (parallel [(unspec_volatile [(match_operand:SI 3 "const_int_operand" "i")] UNSPEC_SET_INTR) + (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) + (clobber (mem:BLK (scratch)))]))] "! flag_pic" "ila\t%0,.+8\;bi%b2%b1z%I3\t%2,%0" [(set_attr "length" "8") (set_attr "type" "multi0")]) (define_insn "set_intr_cc_pic" - [(set (reg:INTR 131) - (if_then_else:INTR - (match_operator 1 "branch_comparison_operator" - [(match_operand 2 "spu_reg_operand" "r") - (const_int 0)]) - (match_operand:SI 3 "const_int_operand" "i") - (reg:INTR 131))) - (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) - (clobber (mem:BLK (scratch)))] + [(cond_exec (match_operator 1 "branch_comparison_operator" + [(match_operand 2 "spu_reg_operand" "r") + (const_int 0)]) + (parallel [(unspec_volatile [(match_operand:SI 3 "const_int_operand" "i")] UNSPEC_SET_INTR) + (clobber (match_operand:SI 0 "spu_reg_operand" "=&r")) + (clobber (mem:BLK (scratch)))]))] "flag_pic" - "brsl\t%0,.+4\;ai\t%0,%0,8\;%b2%b1z%I3\t%2,%0" + "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%b2%b1z%I3\t%2,%0" [(set_attr "length" "12") (set_attr "type" "multi1")]) (define_insn "set_intr_return" - [(set (reg:INTR 131) (match_operand 0 "const_int_operand" "i")) + [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")] UNSPEC_SET_INTR) (return)] "" "bi%I0\t$lr" @@ -698,7 +674,7 @@ (define_peephole2 [(parallel - [(set (reg:INTR 131) (match_operand 0 "const_int_operand")) + [(unspec_volatile [(match_operand:SI 0 "const_int_operand")] UNSPEC_SET_INTR) (clobber (match_operand:SI 1 "spu_reg_operand")) (clobber (mem:BLK (scratch)))]) (use (reg:SI 0)) @@ -706,7 +682,7 @@ "" [(use (reg:SI 0)) (parallel - [(set (reg:INTR 131) (match_dup 0)) + [(unspec_volatile [(match_dup:SI 0)] UNSPEC_SET_INTR) (return)])] "") diff --git a/gcc/config/spu/spu-modes.def b/gcc/config/spu/spu-modes.def index 49d577b..9d33fef 100644 --- a/gcc/config/spu/spu-modes.def +++ b/gcc/config/spu/spu-modes.def @@ -25,10 +25,6 @@ VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */ VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */ VECTOR_MODES (FLOAT, 16); /* V8HF V4SF V2DF */ -/* A special mode for the intr register so we can treat it differently - for conditional moves. */ -RANDOM_MODE (INTR); - /* cse_insn needs an INT_MODE larger than WORD_MODE, otherwise some parts of it will go into an infinite loop. */ INT_MODE (OI, 32); diff --git a/gcc/config/spu/spu-protos.h b/gcc/config/spu/spu-protos.h index 6f87ec0..4caaf1b 100644 --- a/gcc/config/spu/spu-protos.h +++ b/gcc/config/spu/spu-protos.h @@ -23,6 +23,7 @@ extern enum machine_mode spu_eh_return_filter_mode (void); extern void spu_cpu_cpp_builtins (struct cpp_reader * pfile); extern void builtin_define_std (const char *); +extern void spu_optimization_options (int level, int size); extern void spu_override_options (void); extern void spu_c_common_override_options (void); extern int valid_subreg (rtx op); @@ -88,6 +89,7 @@ extern void spu_builtin_promote (rtx ops[]); extern void spu_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt); extern void spu_expand_sign_extend (rtx ops[]); extern void spu_expand_vector_init (rtx target, rtx vals); +extern void spu_init_expanders (void); /* spu-c.c */ extern tree spu_resolve_overloaded_builtin (tree fndecl, tree fnargs); diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c index 9adeacf..252183b 100644 --- a/gcc/config/spu/spu.c +++ b/gcc/config/spu/spu.c @@ -157,6 +157,7 @@ enum immediate_class IC_IL2s, /* both ilhu and iohl instructions */ IC_FSMBI, /* the fsmbi instruction */ IC_CPAT, /* one of the c*d instructions */ + IC_FSMBI2 /* fsmbi plus 1 other instruction */ }; static enum spu_immediate which_immediate_load (HOST_WIDE_INT val); @@ -262,6 +263,22 @@ const struct attribute_spec spu_attribute_table[]; struct gcc_target targetm = TARGET_INITIALIZER; +void +spu_optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED) +{ + /* Small loops will be unpeeled at -O3. For SPU it is more important + to keep code small by default. */ + if (!flag_unroll_loops && !flag_peel_loops) + PARAM_VALUE (PARAM_MAX_COMPLETELY_PEEL_TIMES) = 1; + + /* Override some of the default param values. With so many registers + larger values are better for these params. */ + MAX_PENDING_LIST_LENGTH = 128; + + /* With so many registers this is better on by default. */ + flag_rename_registers = 1; +} + /* Sometimes certain combinations of command options do not make sense on a particular target machine. You can define a macro OVERRIDE_OPTIONS to take account of this. This macro, if defined, is @@ -269,13 +286,6 @@ struct gcc_target targetm = TARGET_INITIALIZER; void spu_override_options (void) { - /* Override some of the default param values. With so many registers - larger values are better for these params. */ - if (MAX_UNROLLED_INSNS == 100) - MAX_UNROLLED_INSNS = 250; - if (MAX_PENDING_LIST_LENGTH == 32) - MAX_PENDING_LIST_LENGTH = 128; - flag_omit_frame_pointer = 1; if (align_functions < 8) @@ -1142,6 +1152,7 @@ print_operand (FILE * file, rtx x, int code) fprintf (file, "hu"); break; case IC_FSMBI: + case IC_FSMBI2: case IC_IL2: case IC_IL2s: case IC_POOL: @@ -1194,21 +1205,17 @@ print_operand (FILE * file, rtx x, int code) fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)info); break; case IC_IL1s: - if (xcode == CONST_VECTOR) - { - x = CONST_VECTOR_ELT (x, 0); - xcode = GET_CODE (x); - } if (xcode == HIGH) - { - output_addr_const (file, XEXP (x, 0)); - fprintf (file, "@h"); - } - else - output_addr_const (file, x); + x = XEXP (x, 0); + if (GET_CODE (x) == CONST_VECTOR) + x = CONST_VECTOR_ELT (x, 0); + output_addr_const (file, x); + if (xcode == HIGH) + fprintf (file, "@h"); break; case IC_IL2: case IC_IL2s: + case IC_FSMBI2: case IC_POOL: abort (); } @@ -1307,6 +1314,58 @@ print_operand (FILE * file, rtx x, int code) } return; + case 'e': + val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); + val &= 0x7; + output_addr_const (file, GEN_INT (val)); + return; + + case 'f': + val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); + val &= 0x1f; + output_addr_const (file, GEN_INT (val)); + return; + + case 'g': + val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); + val &= 0x3f; + output_addr_const (file, GEN_INT (val)); + return; + + case 'h': + val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); + val = (val >> 3) & 0x1f; + output_addr_const (file, GEN_INT (val)); + return; + + case 'E': + val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); + val = -val; + val &= 0x7; + output_addr_const (file, GEN_INT (val)); + return; + + case 'F': + val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); + val = -val; + val &= 0x1f; + output_addr_const (file, GEN_INT (val)); + return; + + case 'G': + val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); + val = -val; + val &= 0x3f; + output_addr_const (file, GEN_INT (val)); + return; + + case 'H': + val = xcode == CONST_INT ? INTVAL (x) : INTVAL (CONST_VECTOR_ELT (x, 0)); + val = -(val & -8ll); + val = (val >> 3) & 0x1f; + output_addr_const (file, GEN_INT (val)); + return; + case 0: if (xcode == REG) fprintf (file, "%s", reg_names[REGNO (x)]); @@ -1318,6 +1377,9 @@ print_operand (FILE * file, rtx x, int code) output_addr_const (file, x); return; + /* unsed letters + o qr uvw yz + AB OPQR UVWXYZ */ default: output_operand_lossage ("invalid %%xn code"); } @@ -1341,8 +1403,9 @@ get_pic_reg (void) return pic_reg; } -/* Split constant addresses to handle cases that are too large. Also, add in - the pic register when in PIC mode. */ +/* Split constant addresses to handle cases that are too large. + Add in the pic register when in PIC mode. + Split immediates that require more than 1 instruction. */ int spu_split_immediate (rtx * ops) { @@ -1373,6 +1436,36 @@ spu_split_immediate (rtx * ops) (VOIDmode, ops[0], gen_rtx_IOR (mode, to, lo))); return 1; } + case IC_FSMBI2: + { + unsigned char arr_fsmbi[16]; + unsigned char arr_andbi[16]; + rtx to, reg_fsmbi, reg_and; + int i; + enum machine_mode imode = mode; + /* We need to do reals as ints because the constant used in the + * AND might not be a legitimate real constant. */ + imode = int_mode_for_mode (mode); + constant_to_array (mode, ops[1], arr_fsmbi); + if (imode != mode) + to = simplify_gen_subreg(imode, ops[0], GET_MODE (ops[0]), 0); + else + to = ops[0]; + for (i = 0; i < 16; i++) + if (arr_fsmbi[i] != 0) + { + arr_andbi[0] = arr_fsmbi[i]; + arr_fsmbi[i] = 0xff; + } + for (i = 1; i < 16; i++) + arr_andbi[i] = arr_andbi[0]; + reg_fsmbi = array_to_constant (imode, arr_fsmbi); + reg_and = array_to_constant (imode, arr_andbi); + emit_move_insn (to, reg_fsmbi); + emit_insn (gen_rtx_SET + (VOIDmode, to, gen_rtx_AND (imode, to, reg_and))); + return 1; + } case IC_POOL: if (reload_in_progress || reload_completed) { @@ -1393,8 +1486,8 @@ spu_split_immediate (rtx * ops) { if (c == IC_IL2s) { - emit_insn (gen_high (ops[0], ops[1])); - emit_insn (gen_low (ops[0], ops[0], ops[1])); + emit_move_insn (ops[0], gen_rtx_HIGH (mode, ops[1])); + emit_move_insn (ops[0], gen_rtx_LO_SUM (mode, ops[0], ops[1])); } else if (flag_pic) emit_insn (gen_pic (ops[0], ops[1])); @@ -1667,6 +1760,7 @@ spu_expand_prologue (void) REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, real, REG_NOTES (insn)); + REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY; } } @@ -2329,7 +2423,8 @@ immediate_load_p (rtx op, enum machine_mode mode) if (CONSTANT_P (op)) { enum immediate_class c = classify_immediate (op, mode); - return c == IC_IL1 || (!flow2_completed && c == IC_IL2); + return c == IC_IL1 || c == IC_IL1s + || (!flow2_completed && (c == IC_IL2 || c == IC_IL2s)); } return 0; } @@ -2390,7 +2485,7 @@ classify_immediate (rtx op, enum machine_mode mode) { HOST_WIDE_INT val; unsigned char arr[16]; - int i, j, repeated, fsmbi; + int i, j, repeated, fsmbi, repeat; gcc_assert (CONSTANT_P (op)); @@ -2398,7 +2493,8 @@ classify_immediate (rtx op, enum machine_mode mode) mode = GET_MODE (op); /* A V4SI const_vector with all identical symbols is ok. */ - if (mode == V4SImode + if (!flag_pic + && mode == V4SImode && GET_CODE (op) == CONST_VECTOR && GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT && GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_DOUBLE @@ -2452,11 +2548,14 @@ classify_immediate (rtx op, enum machine_mode mode) gcc_assert (GET_MODE_SIZE (mode) > 2); fsmbi = 1; + repeat = 0; for (i = 0; i < 16 && fsmbi; i++) - if (arr[i] != 0 && arr[i] != 0xff) + if (arr[i] != 0 && repeat == 0) + repeat = arr[i]; + else if (arr[i] != 0 && arr[i] != repeat) fsmbi = 0; if (fsmbi) - return IC_FSMBI; + return repeat == 0xff ? IC_FSMBI : IC_FSMBI2; if (cpat_info (arr, GET_MODE_SIZE (mode), 0, 0)) return IC_CPAT; @@ -2495,6 +2594,20 @@ which_logical_immediate (HOST_WIDE_INT val) return SPU_NONE; } +/* Return TRUE when X, a CONST_VECTOR, only contains CONST_INTs or + CONST_DOUBLEs. */ +static int +const_vector_immediate_p (rtx x) +{ + int i; + gcc_assert (GET_CODE (x) == CONST_VECTOR); + for (i = 0; i < GET_MODE_NUNITS (GET_MODE (x)); i++) + if (GET_CODE (CONST_VECTOR_ELT (x, i)) != CONST_INT + && GET_CODE (CONST_VECTOR_ELT (x, i)) != CONST_DOUBLE) + return 0; + return 1; +} + int logical_immediate_p (rtx op, enum machine_mode mode) { @@ -2505,6 +2618,10 @@ logical_immediate_p (rtx op, enum machine_mode mode) gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_VECTOR); + if (GET_CODE (op) == CONST_VECTOR + && !const_vector_immediate_p (op)) + return 0; + if (GET_MODE (op) != VOIDmode) mode = GET_MODE (op); @@ -2533,6 +2650,10 @@ iohl_immediate_p (rtx op, enum machine_mode mode) gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_VECTOR); + if (GET_CODE (op) == CONST_VECTOR + && !const_vector_immediate_p (op)) + return 0; + if (GET_MODE (op) != VOIDmode) mode = GET_MODE (op); @@ -2561,6 +2682,10 @@ arith_immediate_p (rtx op, enum machine_mode mode, gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_VECTOR); + if (GET_CODE (op) == CONST_VECTOR + && !const_vector_immediate_p (op)) + return 0; + if (GET_MODE (op) != VOIDmode) mode = GET_MODE (op); @@ -2596,22 +2721,21 @@ arith_immediate_p (rtx op, enum machine_mode mode, int spu_legitimate_constant_p (rtx x) { - int i; + if (GET_CODE (x) == HIGH) + x = XEXP (x, 0); /* V4SI with all identical symbols is valid. */ - if (GET_MODE (x) == V4SImode + if (!flag_pic + && GET_MODE (x) == V4SImode && (GET_CODE (CONST_VECTOR_ELT (x, 0)) == SYMBOL_REF || GET_CODE (CONST_VECTOR_ELT (x, 0)) == LABEL_REF - || GET_CODE (CONST_VECTOR_ELT (x, 0)) == CONST - || GET_CODE (CONST_VECTOR_ELT (x, 0)) == HIGH)) + || GET_CODE (CONST_VECTOR_ELT (x, 0)) == CONST)) return CONST_VECTOR_ELT (x, 0) == CONST_VECTOR_ELT (x, 1) && CONST_VECTOR_ELT (x, 1) == CONST_VECTOR_ELT (x, 2) && CONST_VECTOR_ELT (x, 2) == CONST_VECTOR_ELT (x, 3); - if (VECTOR_MODE_P (GET_MODE (x))) - for (i = 0; i < GET_MODE_NUNITS (GET_MODE (x)); i++) - if (GET_CODE (CONST_VECTOR_ELT (x, i)) != CONST_INT - && GET_CODE (CONST_VECTOR_ELT (x, i)) != CONST_DOUBLE) - return 0; + if (GET_CODE (x) == CONST_VECTOR + && !const_vector_immediate_p (x)) + return 0; return 1; } @@ -2668,7 +2792,7 @@ spu_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED, && GET_CODE (op1) == CONST_INT && INTVAL (op1) >= -0x2000 && INTVAL (op1) <= 0x1fff - && (REGNO_PTR_FRAME_P (REGNO (op0)) || (INTVAL (op1) & 15) == 0)) + && (regno_aligned_for_load (REGNO (op0)) || (INTVAL (op1) & 15) == 0)) return 1; if (GET_CODE (op0) == REG && INT_REG_OK_FOR_BASE_P (op0, reg_ok_strict) @@ -3135,7 +3259,6 @@ spu_conditional_register_usage (void) fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; } - global_regs[INTR_REGNUM] = 1; } /* This is called to decide when we can simplify a load instruction. We @@ -3149,9 +3272,10 @@ static int regno_aligned_for_load (int regno) { return regno == FRAME_POINTER_REGNUM - || regno == HARD_FRAME_POINTER_REGNUM + || (frame_pointer_needed && regno == HARD_FRAME_POINTER_REGNUM) || regno == STACK_POINTER_REGNUM - || (regno >= FIRST_VIRTUAL_REGISTER && regno <= LAST_VIRTUAL_REGISTER); + || (regno >= FIRST_VIRTUAL_REGISTER + && regno <= LAST_VIRTUAL_REGISTER); } /* Return TRUE when mem is known to be 16-byte aligned. */ @@ -3706,10 +3830,10 @@ fsmbi_const_p (rtx x) { if (CONSTANT_P (x)) { - /* We can always choose DImode for CONST_INT because the high bits + /* We can always choose TImode for CONST_INT because the high bits of an SImode will always be all 1s, i.e., valid for fsmbi. */ - enum immediate_class c = classify_immediate (x, DImode); - return c == IC_FSMBI; + enum immediate_class c = classify_immediate (x, TImode); + return c == IC_FSMBI || (!flow2_completed && c == IC_FSMBI2); } return 0; } @@ -3929,7 +4053,7 @@ reloc_diagnostic (rtx x) /* We use last_assemble_variable_decl to get line information. It's not always going to be right and might not even be close, but will be right for the more common cases. */ - if (!last_assemble_variable_decl) + if (!last_assemble_variable_decl || in_section == ctors_section) loc_decl = decl; else loc_decl = last_assemble_variable_decl; @@ -4346,7 +4470,7 @@ spu_builtin_splats (rtx ops[]) constant_to_array (GET_MODE_INNER (mode), ops[1], arr); emit_move_insn (ops[0], array_to_constant (mode, arr)); } - else if (GET_MODE (ops[0]) == V4SImode && CONSTANT_P (ops[1])) + else if (!flag_pic && GET_MODE (ops[0]) == V4SImode && CONSTANT_P (ops[1])) { rtvec v = rtvec_alloc (4); RTVEC_ELT (v, 0) = ops[1]; @@ -4773,10 +4897,8 @@ spu_check_builtin_parm (struct spu_builtin_description *d, rtx op, int p) if (p >= SPU_BTI_7 && p <= SPU_BTI_U18) { int range = p - SPU_BTI_7; - if (!CONSTANT_P (op) - || (GET_CODE (op) == CONST_INT - && (INTVAL (op) < spu_builtin_range[range].low - || INTVAL (op) > spu_builtin_range[range].high))) + + if (!CONSTANT_P (op)) error ("%s expects an integer literal in the range [%d, %d].", d->name, spu_builtin_range[range].low, spu_builtin_range[range].high); @@ -4790,6 +4912,18 @@ spu_check_builtin_parm (struct spu_builtin_description *d, rtx op, int p) } else if (GET_CODE (op) == CONST_INT) v = INTVAL (op); + else if (GET_CODE (op) == CONST_VECTOR + && GET_CODE (CONST_VECTOR_ELT (op, 0)) == CONST_INT) + v = INTVAL (CONST_VECTOR_ELT (op, 0)); + + /* The default for v is 0 which is valid in every range. */ + if (v < spu_builtin_range[range].low + || v > spu_builtin_range[range].high) + error ("%s expects an integer literal in the range [%d, %d]. (" + HOST_WIDE_INT_PRINT_DEC ")", + d->name, + spu_builtin_range[range].low, spu_builtin_range[range].high, + v); switch (p) { @@ -4814,7 +4948,7 @@ spu_check_builtin_parm (struct spu_builtin_description *d, rtx op, int p) if (GET_CODE (op) == LABEL_REF || (GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (op)) - || (INTVAL (op) & ((1 << lsbits) - 1)) != 0) + || (v & ((1 << lsbits) - 1)) != 0) warning (0, "%d least significant bits of %s are ignored.", lsbits, d->name); } @@ -4822,30 +4956,29 @@ spu_check_builtin_parm (struct spu_builtin_description *d, rtx op, int p) static void -expand_builtin_args (struct spu_builtin_description *d, tree arglist, +expand_builtin_args (struct spu_builtin_description *d, tree exp, rtx target, rtx ops[]) { enum insn_code icode = d->icode; - int i = 0; + int i = 0, a; /* Expand the arguments into rtl. */ if (d->parm[0] != SPU_BTI_VOID) ops[i++] = target; - for (; i < insn_data[icode].n_operands; i++) + for (a = 0; i < insn_data[icode].n_operands; i++, a++) { - tree arg = TREE_VALUE (arglist); + tree arg = CALL_EXPR_ARG (exp, a); if (arg == 0) abort (); ops[i] = expand_expr (arg, NULL_RTX, VOIDmode, 0); - arglist = TREE_CHAIN (arglist); } } static rtx spu_expand_builtin_1 (struct spu_builtin_description *d, - tree arglist, rtx target) + tree exp, rtx target) { rtx pat; rtx ops[8]; @@ -4855,7 +4988,7 @@ spu_expand_builtin_1 (struct spu_builtin_description *d, tree return_type; /* Set up ops[] with values from arglist. */ - expand_builtin_args (d, arglist, target, ops); + expand_builtin_args (d, exp, target, ops); /* Handle the target operand which must be operand 0. */ i = 0; @@ -4889,7 +5022,7 @@ spu_expand_builtin_1 (struct spu_builtin_description *d, rtx addr, op, pat; /* get addr */ - arg = TREE_VALUE (arglist); + arg = CALL_EXPR_ARG (exp, 0); gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE); op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL); addr = memory_address (mode, op); @@ -4947,10 +5080,10 @@ spu_expand_builtin_1 (struct spu_builtin_description *d, } } + spu_check_builtin_parm (d, ops[i], d->parm[p]); + if (!(*insn_data[icode].operand[i].predicate) (ops[i], mode)) ops[i] = spu_force_reg (mode, ops[i]); - - spu_check_builtin_parm (d, ops[i], d->parm[p]); } switch (insn_data[icode].n_operands) @@ -5012,16 +5145,15 @@ spu_expand_builtin (tree exp, enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED) { - tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); + tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); unsigned int fcode = DECL_FUNCTION_CODE (fndecl) - END_BUILTINS; - tree arglist = TREE_OPERAND (exp, 1); struct spu_builtin_description *d; if (fcode < NUM_SPU_BUILTINS) { d = &spu_builtins[fcode]; - return spu_expand_builtin_1 (d, arglist, target); + return spu_expand_builtin_1 (d, exp, target); } abort (); } @@ -5068,3 +5200,13 @@ spu_builtin_mask_for_load (void) gcc_assert (d); return d->fndecl; } + +void +spu_init_expanders (void) +{ + /* HARD_FRAME_REGISTER is only 128 bit aligned when + * frame_pointer_needed is true. We don't know that until we're + * expanding the prologue. */ + if (cfun) + REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = 8; +} diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h index 240d245..1fcc234 100644 --- a/gcc/config/spu/spu.h +++ b/gcc/config/spu/spu.h @@ -24,6 +24,11 @@ #define OVERRIDE_OPTIONS spu_override_options() #define C_COMMON_OVERRIDE_OPTIONS spu_c_common_override_options() +#define OPTIMIZATION_OPTIONS(level,size) \ + spu_optimization_options(level,size) + +#define INIT_EXPANDERS spu_init_expanders() + extern int target_flags; extern const char *spu_fixed_range_string; @@ -152,7 +157,7 @@ extern const char *spu_fixed_range_string; /* Register Basics */ /* 128-130 are special registers that never appear in assembly code. */ -#define FIRST_PSEUDO_REGISTER 132 +#define FIRST_PSEUDO_REGISTER 131 #define FIXED_REGISTERS { \ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ @@ -163,7 +168,7 @@ extern const char *spu_fixed_range_string; 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, \ - 1, 1, 1, 1 \ + 1, 1, 1 \ } #define CALL_USED_REGISTERS { \ @@ -175,7 +180,7 @@ extern const char *spu_fixed_range_string; 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, \ - 1, 1, 1, 1 \ + 1, 1, 1 \ } #define CONDITIONAL_REGISTER_USAGE \ @@ -299,9 +304,6 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \ * buffer. Users can also specify it in inline asm. */ #define HBR_REGNUM 130 -/* Used to keep track of enabling and disabling interrupts. */ -#define INTR_REGNUM 131 - #define MAX_REGISTER_ARGS 72 #define FIRST_ARG_REGNUM 3 #define LAST_ARG_REGNUM (FIRST_ARG_REGNUM + MAX_REGISTER_ARGS - 1) @@ -512,7 +514,7 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \ "$80", "$81", "$82", "$83", "$84", "$85", "$86", "$87", "$88", "$89", "$90", "$91", "$92", "$93", "$94", "$95", \ "$96", "$97", "$98", "$99", "$100", "$101", "$102", "$103", "$104", "$105", "$106", "$107", "$108", "$109", "$110", "$111", \ "$112", "$113", "$114", "$115", "$116", "$117", "$118", "$119", "$120", "$121", "$122", "$123", "$124", "$125", "$126", "$127", \ - "$vfp", "$vap", "hbr", "intr" \ + "$vfp", "$vap", "hbr" \ } #define PRINT_OPERAND(FILE, X, CODE) print_operand(FILE, X, CODE) diff --git a/gcc/config/spu/spu.md b/gcc/config/spu/spu.md index 523ecec..ccaf485 100644 --- a/gcc/config/spu/spu.md +++ b/gcc/config/spu/spu.md @@ -134,8 +134,7 @@ (UNSPEC_CFLTU 37) (UNSPEC_STOP 38) (UNSPEC_STOPD 39) - (UNSPEC_IDISABLE 40) - (UNSPEC_IENABLE 41) + (UNSPEC_SET_INTR 40) (UNSPEC_FSCRRD 42) (UNSPEC_FSCRWR 43) (UNSPEC_MFSPR 44) @@ -204,6 +203,11 @@ (define_mode_attr f2i [(SF "SI") (V4SF "V4SI") (DF "DI") (V2DF "V2DI")]) +(define_mode_attr umask [(HI "f") (V8HI "f") + (SI "g") (V4SI "g")]) +(define_mode_attr nmask [(HI "F") (V8HI "F") + (SI "G") (V4SI "G")]) + ;; Used for carry and borrow instructions. (define_mode_macro CBOP [SI DI V4SI V2DI]) @@ -293,16 +297,10 @@ stq%p0\t%1,%0" [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")]) -(define_insn "high" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (high:SI (match_operand:SI 1 "immediate_operand" "i")))] - "" - "ilhu\t%0,%1@h") - -(define_insn "low" - [(set (match_operand:SI 0 "spu_reg_operand" "=r") - (lo_sum:SI (match_operand:SI 1 "spu_reg_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))] +(define_insn "low_<mode>" + [(set (match_operand:VSI 0 "spu_reg_operand" "=r") + (lo_sum:VSI (match_operand:VSI 1 "spu_reg_operand" "0") + (match_operand:VSI 2 "immediate_operand" "i")))] "" "iohl\t%0,%2@l") @@ -1193,7 +1191,7 @@ (define_insn "mulhisi3_imm" [(set (match_operand:SI 0 "spu_reg_operand" "=r") (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")) - (match_operand:SI 2 "immediate_operand" "K")))] + (match_operand:SI 2 "imm_K_operand" "K")))] "" "mpyi\t%0,%1,%2" [(set_attr "type" "fp7")]) @@ -1209,7 +1207,7 @@ (define_insn "umulhisi3_imm" [(set (match_operand:SI 0 "spu_reg_operand" "=r") (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")) - (and:SI (match_operand:SI 2 "immediate_operand" "K") (const_int 65535))))] + (and:SI (match_operand:SI 2 "imm_K_operand" "K") (const_int 65535))))] "" "mpyui\t%0,%1,%2" [(set_attr "type" "fp7")]) @@ -1753,7 +1751,7 @@ "" "@ xor\t%0,%1,%2 - xor%j2i\t%0,%1,%S2") + xor%j2i\t%0,%1,%J2") (define_insn "xordi3" [(set (match_operand:DI 0 "spu_reg_operand" "=r,r") @@ -1912,17 +1910,17 @@ (define_insn "ashl<mode>3" [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r") - (match_operand:VHSI 2 "spu_shift_operand" "r,W")))] + (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))] "" "@ shl<bh>\t%0,%1,%2 - shl<bh>i\t%0,%1,%2" + shl<bh>i\t%0,%1,%<umask>2" [(set_attr "type" "fx3")]) (define_insn_and_split "ashldi3" [(set (match_operand:DI 0 "spu_reg_operand" "=r,r") (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r") - (match_operand:SI 2 "spu_shift_operand" "r,I"))) + (match_operand:SI 2 "spu_nonmem_operand" "r,I"))) (clobber (match_scratch:SI 3 "=&r,X"))] "" "#" @@ -1973,8 +1971,8 @@ (match_operand:SI 2 "immediate_operand" "O,P")))] "" "@ - shlqbyi\t%0,%1,%2/8 - shlqbii\t%0,%1,%2" + shlqbyi\t%0,%1,%h2 + shlqbii\t%0,%1,%e2" "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])" [(set (match_dup:TI 0) (ashift:TI (match_dup:TI 1) @@ -1985,7 +1983,7 @@ { HOST_WIDE_INT val = INTVAL(operands[2]); operands[3] = GEN_INT (val&7); - operands[4] = GEN_INT (val&0x78); + operands[4] = GEN_INT (val&-8); } [(set_attr "type" "shuf,shuf")]) @@ -2015,7 +2013,7 @@ "" "@ shlqbybi\t%0,%1,%2 - shlqbyi\t%0,%1,%2/8" + shlqbyi\t%0,%1,%h2" [(set_attr "type" "shuf,shuf")]) (define_insn "shlqbi_ti" @@ -2026,7 +2024,7 @@ "" "@ shlqbi\t%0,%1,%2 - shlqbii\t%0,%1,%2" + shlqbii\t%0,%1,%e2" [(set_attr "type" "shuf,shuf")]) (define_insn "shlqby_ti" @@ -2037,7 +2035,7 @@ "" "@ shlqby\t%0,%1,%2 - shlqbyi\t%0,%1,%2" + shlqbyi\t%0,%1,%f2" [(set_attr "type" "shuf,shuf")]) @@ -2046,12 +2044,12 @@ (define_insn_and_split "lshr<mode>3" [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r") - (match_operand:VHSI 2 "spu_shift_operand" "r,W"))) + (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))) (clobber (match_scratch:VHSI 3 "=&r,X"))] "" "@ # - rot<bh>mi\t%0,%1,%N2" + rot<bh>mi\t%0,%1,-%<umask>2" "reload_completed && GET_CODE (operands[2]) == REG" [(set (match_dup:VHSI 3) (neg:VHSI (match_dup:VHSI 2))) @@ -2065,11 +2063,11 @@ (define_insn "rotm_<mode>" [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r") - (neg:VHSI (match_operand:VHSI 2 "spu_shift_operand" "r,W"))))] + (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))] "" "@ rot<bh>m\t%0,%1,%2 - rot<bh>mi\t%0,%1,%2" + rot<bh>mi\t%0,%1,-%<nmask>2" [(set_attr "type" "fx3")]) (define_expand "lshr<mode>3" @@ -2095,8 +2093,8 @@ (match_operand:SI 2 "immediate_operand" "O,P")))] "" "@ - rotqmbyi\t%0,%1,%N2/8 - rotqmbii\t%0,%1,%N2" + rotqmbyi\t%0,%1,-%h2 + rotqmbii\t%0,%1,-%e2" "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])" [(set (match_dup:DTI 0) (lshiftrt:DTI (match_dup:DTI 1) @@ -2107,7 +2105,7 @@ { HOST_WIDE_INT val = INTVAL(operands[2]); operands[4] = GEN_INT (val&7); - operands[5] = GEN_INT (val&0x78); + operands[5] = GEN_INT (val&-8); } [(set_attr "type" "shuf,shuf")]) @@ -2127,7 +2125,8 @@ (const_int 7)))) (set (match_dup:DTI 0) (lshiftrt:DTI (match_dup:DTI 3) - (and:SI (neg:SI (match_dup:SI 5)) + (and:SI (neg:SI (and:SI (match_dup:SI 5) + (const_int -8))) (const_int -8))))] { emit_insn(gen_subsi3(operands[4], GEN_INT(0), operands[2])); @@ -2137,12 +2136,13 @@ (define_insn "rotqmbybi_<mode>" [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r") (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r") - (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")) + (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I") + (const_int -8))) (const_int -8))))] "" "@ rotqmbybi\t%0,%1,%2 - rotqmbyi\t%0,%1,%2/8" + rotqmbyi\t%0,%1,-%H2" [(set_attr "type" "shuf")]) (define_insn "rotqmbi_<mode>" @@ -2153,7 +2153,7 @@ "" "@ rotqmbi\t%0,%1,%2 - rotqmbii\t%0,%1,%2" + rotqmbii\t%0,%1,-%E2" [(set_attr "type" "shuf")]) (define_insn "rotqmby_<mode>" @@ -2164,7 +2164,7 @@ "" "@ rotqmby\t%0,%1,%2 - rotqmbyi\t%0,%1,%2" + rotqmbyi\t%0,%1,-%F2" [(set_attr "type" "shuf")]) @@ -2173,12 +2173,12 @@ (define_insn_and_split "ashr<mode>3" [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r") - (match_operand:VHSI 2 "spu_shift_operand" "r,W"))) + (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))) (clobber (match_scratch:VHSI 3 "=&r,X"))] "" "@ # - rotma<bh>i\t%0,%1,%N2" + rotma<bh>i\t%0,%1,-%<umask>2" "reload_completed && GET_CODE (operands[2]) == REG" [(set (match_dup:VHSI 3) (neg:VHSI (match_dup:VHSI 2))) @@ -2192,11 +2192,11 @@ (define_insn "rotma_<mode>" [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r") - (neg:VHSI (match_operand:VHSI 2 "spu_shift_operand" "r,W"))))] + (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))] "" "@ rotma<bh>\t%0,%1,%2 - rotma<bh>i\t%0,%1,%2" + rotma<bh>i\t%0,%1,-%<nmask>2" [(set_attr "type" "fx3")]) (define_insn_and_split "ashrdi3" @@ -2306,11 +2306,11 @@ (define_insn "rotl<mode>3" [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r") - (match_operand:VHSI 2 "spu_shift_operand" "r,W")))] + (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))] "" "@ rot<bh>\t%0,%1,%2 - rot<bh>i\t%0,%1,%2" + rot<bh>i\t%0,%1,%<umask>2" [(set_attr "type" "fx3")]) (define_insn "rotlti3" @@ -2320,9 +2320,9 @@ "" "@ rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2 - rotqbyi\t%0,%1,%2/8 - rotqbii\t%0,%1,%2 - rotqbyi\t%0,%1,%2/8\;rotqbii\t%0,%0,%2%%8" + rotqbyi\t%0,%1,%h2 + rotqbii\t%0,%1,%e2 + rotqbyi\t%0,%1,%h2\;rotqbii\t%0,%0,%e2" [(set_attr "length" "8,4,4,8") (set_attr "type" "multi1,shuf,shuf,multi1")]) @@ -2334,7 +2334,7 @@ "" "@ rotqbybi\t%0,%1,%2 - rotqbyi\t%0,%1,%2/8" + rotqbyi\t%0,%1,%h2" [(set_attr "type" "shuf,shuf")]) (define_insn "rotqby_ti" @@ -2345,7 +2345,7 @@ "" "@ rotqby\t%0,%1,%2 - rotqbyi\t%0,%1,%2" + rotqbyi\t%0,%1,%f2" [(set_attr "type" "shuf,shuf")]) (define_insn "rotqbi_ti" @@ -2356,7 +2356,7 @@ "" "@ rotqbi\t%0,%1,%2 - rotqbii\t%0,%1,%2%%8" + rotqbii\t%0,%1,%e2" [(set_attr "type" "shuf,shuf")]) @@ -3090,7 +3090,8 @@ selb\t%0,%4,%0,%3" [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)] "" "" - [(set_attr "length" "0")]) + [(set_attr "type" "convert") + (set_attr "length" "0")]) (define_expand "epilogue" [(const_int 2)] @@ -3234,6 +3235,14 @@ selb\t%0,%4,%0,%3" "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16" [(set_attr "type" "shuf")]) +(define_insn "_vec_extractv8hi_ze" + [(set (match_operand:SI 0 "spu_reg_operand" "=r") + (zero_extend:SI (vec_select:HI (match_operand:V8HI 1 "spu_reg_operand" "r") + (parallel [(const_int 0)]))))] + "" + "rotqmbyi\t%0,%1,-2" + [(set_attr "type" "shuf")]) + ;; misc @@ -3285,7 +3294,7 @@ selb\t%0,%4,%0,%3" (define_insn "hbr" [(set (reg:SI 130) - (unspec:SI [(match_operand:SI 0 "immediate_operand" "s,s,s") + (unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i,i") (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR)) (unspec [(const_int 0)] UNSPEC_HBR)] "" diff --git a/gcc/config/spu/spu_internals.h b/gcc/config/spu/spu_internals.h index 6a71f27..ecc8dc5 100644 --- a/gcc/config/spu/spu_internals.h +++ b/gcc/config/spu/spu_internals.h @@ -189,6 +189,9 @@ #define si_clgthi(ra,imm) __builtin_si_clgthi(ra,imm) #define si_clgt(ra,rb) __builtin_si_clgt(ra,rb) #define si_clgti(ra,imm) __builtin_si_clgti(ra,imm) +#define si_bisled(ra) __builtin_si_bisled(ra,0) +#define si_bisledd(ra) __builtin_si_bisledd(ra,0) +#define si_bislede(ra) __builtin_si_bislede(ra,0) #define si_fa(ra,rb) __builtin_si_fa(ra,rb) #define si_dfa(ra,rb) __builtin_si_dfa(ra,rb) #define si_fs(ra,rb) __builtin_si_fs(ra,rb) |