Commit 73701e27 by Trevor Smigiel Committed by Trevor Smigiel

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
parent c0bca7e1
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> 2007-02-21 Paul Brook <paul@codesourcery.com>
* config/arm/arm.c (thumb2_final_prescan_insn): Don't incrememnt * config/arm/arm.c (thumb2_final_prescan_insn): Don't incrememnt
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
(define_constraint "W" (define_constraint "W"
"An immediate for shift and rotate instructions. const_int is treated as a 32-bit value." "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") (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" (define_constraint "Y"
"An immediate for and/xor/or instructions. const_int is sign extended as a 128 bit." "An immediate for and/xor/or instructions. const_int is sign extended as a 128 bit."
...@@ -131,7 +131,7 @@ ...@@ -131,7 +131,7 @@
(define_constraint "O" (define_constraint "O"
"An unsigned 7-bit constant whose 3 least significant bits are 0." "An unsigned 7-bit constant whose 3 least significant bits are 0."
(and (match_code "const_int") (and (match_code "const_int")
(match_test "ival >= 0 && ival <= 0x7f && (ival & 7) == 0"))) (match_test "(ival & 7) == 0")))
(define_constraint "P" (define_constraint "P"
"An unsigned 3-bit constant for 16-byte rotates and shifts" "An unsigned 3-bit constant for 16-byte rotates and shifts"
......
...@@ -85,15 +85,9 @@ ...@@ -85,15 +85,9 @@
return 0; return 0;
}) })
(define_predicate "spu_shift_operand" (define_predicate "imm_K_operand"
(match_code "reg,subreg,const_int,const_vector") (and (match_code "const_int")
{ (match_test "arith_immediate_p (op, mode, -0x200, 0x1ff)")))
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;
})
;; Return 1 if OP is a comparison operation that is valid for a branch insn. ;; 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. ;; We only check the opcode against the mode of the register value here.
......
...@@ -163,6 +163,9 @@ DEF_BUILTIN (SI_CLGTH, CODE_FOR_clgt_v8hi, "si_clgth", B_INSN, ...@@ -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_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_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_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_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_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)) DEF_BUILTIN (SI_FS, CODE_FOR_subv4sf3, "si_fs", B_INSN, _A3(SPU_BTI_QUADWORD, SPU_BTI_QUADWORD, SPU_BTI_QUADWORD))
......
...@@ -213,7 +213,7 @@ ...@@ -213,7 +213,7 @@
"" ""
"@ "@
mpy\t%0,%1,%2 mpy\t%0,%1,%2
mpyi\t%0,%1,%H2" mpyi\t%0,%1,%2"
[(set_attr "type" "fp7")]) [(set_attr "type" "fp7")])
(define_insn "spu_mpyu" (define_insn "spu_mpyu"
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
"" ""
"@ "@
mpyu\t%0,%1,%2 mpyu\t%0,%1,%2
mpyui\t%0,%1,%H2" mpyui\t%0,%1,%2"
[(set_attr "type" "fp7")]) [(set_attr "type" "fp7")])
(define_insn "spu_mpya" (define_insn "spu_mpya"
...@@ -607,12 +607,9 @@ ...@@ -607,12 +607,9 @@
[(set_attr "type" "br")]) [(set_attr "type" "br")])
;; interrupt disable/enable ;; 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" (define_expand "spu_idisable"
[(parallel [(parallel
[(set (reg:INTR 131) (const_int 0)) [(unspec_volatile [(const_int 0)] UNSPEC_SET_INTR)
(clobber (match_dup:SI 0)) (clobber (match_dup:SI 0))
(clobber (mem:BLK (scratch)))])] (clobber (mem:BLK (scratch)))])]
"" ""
...@@ -620,14 +617,14 @@ ...@@ -620,14 +617,14 @@
(define_expand "spu_ienable" (define_expand "spu_ienable"
[(parallel [(parallel
[(set (reg:INTR 131) (const_int 1)) [(unspec_volatile [(const_int 1)] UNSPEC_SET_INTR)
(clobber (match_dup:SI 0)) (clobber (match_dup:SI 0))
(clobber (mem:BLK (scratch)))])] (clobber (mem:BLK (scratch)))])]
"" ""
"operands[0] = gen_reg_rtx (SImode);") "operands[0] = gen_reg_rtx (SImode);")
(define_insn "set_intr" (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 (match_operand:SI 0 "spu_reg_operand" "=&r"))
(clobber (mem:BLK (scratch)))] (clobber (mem:BLK (scratch)))]
"! flag_pic" "! flag_pic"
...@@ -636,7 +633,7 @@ ...@@ -636,7 +633,7 @@
(set_attr "type" "multi0")]) (set_attr "type" "multi0")])
(define_insn "set_intr_pic" (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 (match_operand:SI 0 "spu_reg_operand" "=&r"))
(clobber (mem:BLK (scratch)))] (clobber (mem:BLK (scratch)))]
"flag_pic" "flag_pic"
...@@ -644,53 +641,32 @@ ...@@ -644,53 +641,32 @@
[(set_attr "length" "12") [(set_attr "length" "12")
(set_attr "type" "multi1")]) (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" (define_insn "set_intr_cc"
[(set (reg:INTR 131) [(cond_exec (match_operator 1 "branch_comparison_operator"
(if_then_else:INTR [(match_operand 2 "spu_reg_operand" "r")
(match_operator 1 "branch_comparison_operator" (const_int 0)])
[(match_operand 2 "spu_reg_operand" "r") (parallel [(unspec_volatile [(match_operand:SI 3 "const_int_operand" "i")] UNSPEC_SET_INTR)
(const_int 0)]) (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
(match_operand:SI 3 "const_int_operand" "i") (clobber (mem:BLK (scratch)))]))]
(reg:INTR 131)))
(clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
(clobber (mem:BLK (scratch)))]
"! flag_pic" "! flag_pic"
"ila\t%0,.+8\;bi%b2%b1z%I3\t%2,%0" "ila\t%0,.+8\;bi%b2%b1z%I3\t%2,%0"
[(set_attr "length" "8") [(set_attr "length" "8")
(set_attr "type" "multi0")]) (set_attr "type" "multi0")])
(define_insn "set_intr_cc_pic" (define_insn "set_intr_cc_pic"
[(set (reg:INTR 131) [(cond_exec (match_operator 1 "branch_comparison_operator"
(if_then_else:INTR [(match_operand 2 "spu_reg_operand" "r")
(match_operator 1 "branch_comparison_operator" (const_int 0)])
[(match_operand 2 "spu_reg_operand" "r") (parallel [(unspec_volatile [(match_operand:SI 3 "const_int_operand" "i")] UNSPEC_SET_INTR)
(const_int 0)]) (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
(match_operand:SI 3 "const_int_operand" "i") (clobber (mem:BLK (scratch)))]))]
(reg:INTR 131)))
(clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
(clobber (mem:BLK (scratch)))]
"flag_pic" "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 "length" "12")
(set_attr "type" "multi1")]) (set_attr "type" "multi1")])
(define_insn "set_intr_return" (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)] (return)]
"" ""
"bi%I0\t$lr" "bi%I0\t$lr"
...@@ -698,7 +674,7 @@ ...@@ -698,7 +674,7 @@
(define_peephole2 (define_peephole2
[(parallel [(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 (match_operand:SI 1 "spu_reg_operand"))
(clobber (mem:BLK (scratch)))]) (clobber (mem:BLK (scratch)))])
(use (reg:SI 0)) (use (reg:SI 0))
...@@ -706,7 +682,7 @@ ...@@ -706,7 +682,7 @@
"" ""
[(use (reg:SI 0)) [(use (reg:SI 0))
(parallel (parallel
[(set (reg:INTR 131) (match_dup 0)) [(unspec_volatile [(match_dup:SI 0)] UNSPEC_SET_INTR)
(return)])] (return)])]
"") "")
......
...@@ -25,10 +25,6 @@ VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */ ...@@ -25,10 +25,6 @@ VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */
VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */ VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */
VECTOR_MODES (FLOAT, 16); /* V8HF V4SF V2DF */ 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 /* cse_insn needs an INT_MODE larger than WORD_MODE, otherwise some
parts of it will go into an infinite loop. */ parts of it will go into an infinite loop. */
INT_MODE (OI, 32); INT_MODE (OI, 32);
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
extern enum machine_mode spu_eh_return_filter_mode (void); extern enum machine_mode spu_eh_return_filter_mode (void);
extern void spu_cpu_cpp_builtins (struct cpp_reader * pfile); extern void spu_cpu_cpp_builtins (struct cpp_reader * pfile);
extern void builtin_define_std (const char *); 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_override_options (void);
extern void spu_c_common_override_options (void); extern void spu_c_common_override_options (void);
extern int valid_subreg (rtx op); extern int valid_subreg (rtx op);
...@@ -88,6 +89,7 @@ extern void spu_builtin_promote (rtx ops[]); ...@@ -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_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt);
extern void spu_expand_sign_extend (rtx ops[]); extern void spu_expand_sign_extend (rtx ops[]);
extern void spu_expand_vector_init (rtx target, rtx vals); extern void spu_expand_vector_init (rtx target, rtx vals);
extern void spu_init_expanders (void);
/* spu-c.c */ /* spu-c.c */
extern tree spu_resolve_overloaded_builtin (tree fndecl, tree fnargs); extern tree spu_resolve_overloaded_builtin (tree fndecl, tree fnargs);
......
...@@ -157,6 +157,7 @@ enum immediate_class ...@@ -157,6 +157,7 @@ enum immediate_class
IC_IL2s, /* both ilhu and iohl instructions */ IC_IL2s, /* both ilhu and iohl instructions */
IC_FSMBI, /* the fsmbi instruction */ IC_FSMBI, /* the fsmbi instruction */
IC_CPAT, /* one of the c*d instructions */ 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); static enum spu_immediate which_immediate_load (HOST_WIDE_INT val);
...@@ -262,6 +263,22 @@ const struct attribute_spec spu_attribute_table[]; ...@@ -262,6 +263,22 @@ const struct attribute_spec spu_attribute_table[];
struct gcc_target targetm = TARGET_INITIALIZER; 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 /* Sometimes certain combinations of command options do not make sense
on a particular target machine. You can define a macro on a particular target machine. You can define a macro
OVERRIDE_OPTIONS to take account of this. This macro, if defined, is OVERRIDE_OPTIONS to take account of this. This macro, if defined, is
...@@ -269,13 +286,6 @@ struct gcc_target targetm = TARGET_INITIALIZER; ...@@ -269,13 +286,6 @@ struct gcc_target targetm = TARGET_INITIALIZER;
void void
spu_override_options (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; flag_omit_frame_pointer = 1;
if (align_functions < 8) if (align_functions < 8)
...@@ -1142,6 +1152,7 @@ print_operand (FILE * file, rtx x, int code) ...@@ -1142,6 +1152,7 @@ print_operand (FILE * file, rtx x, int code)
fprintf (file, "hu"); fprintf (file, "hu");
break; break;
case IC_FSMBI: case IC_FSMBI:
case IC_FSMBI2:
case IC_IL2: case IC_IL2:
case IC_IL2s: case IC_IL2s:
case IC_POOL: case IC_POOL:
...@@ -1194,21 +1205,17 @@ print_operand (FILE * file, rtx x, int code) ...@@ -1194,21 +1205,17 @@ print_operand (FILE * file, rtx x, int code)
fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)info); fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)info);
break; break;
case IC_IL1s: case IC_IL1s:
if (xcode == CONST_VECTOR)
{
x = CONST_VECTOR_ELT (x, 0);
xcode = GET_CODE (x);
}
if (xcode == HIGH) if (xcode == HIGH)
{ x = XEXP (x, 0);
output_addr_const (file, XEXP (x, 0)); if (GET_CODE (x) == CONST_VECTOR)
fprintf (file, "@h"); x = CONST_VECTOR_ELT (x, 0);
} output_addr_const (file, x);
else if (xcode == HIGH)
output_addr_const (file, x); fprintf (file, "@h");
break; break;
case IC_IL2: case IC_IL2:
case IC_IL2s: case IC_IL2s:
case IC_FSMBI2:
case IC_POOL: case IC_POOL:
abort (); abort ();
} }
...@@ -1307,6 +1314,58 @@ print_operand (FILE * file, rtx x, int code) ...@@ -1307,6 +1314,58 @@ print_operand (FILE * file, rtx x, int code)
} }
return; 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: case 0:
if (xcode == REG) if (xcode == REG)
fprintf (file, "%s", reg_names[REGNO (x)]); fprintf (file, "%s", reg_names[REGNO (x)]);
...@@ -1318,6 +1377,9 @@ print_operand (FILE * file, rtx x, int code) ...@@ -1318,6 +1377,9 @@ print_operand (FILE * file, rtx x, int code)
output_addr_const (file, x); output_addr_const (file, x);
return; return;
/* unsed letters
o qr uvw yz
AB OPQR UVWXYZ */
default: default:
output_operand_lossage ("invalid %%xn code"); output_operand_lossage ("invalid %%xn code");
} }
...@@ -1341,8 +1403,9 @@ get_pic_reg (void) ...@@ -1341,8 +1403,9 @@ get_pic_reg (void)
return pic_reg; return pic_reg;
} }
/* Split constant addresses to handle cases that are too large. Also, add in /* Split constant addresses to handle cases that are too large.
the pic register when in PIC mode. */ Add in the pic register when in PIC mode.
Split immediates that require more than 1 instruction. */
int int
spu_split_immediate (rtx * ops) spu_split_immediate (rtx * ops)
{ {
...@@ -1373,6 +1436,36 @@ spu_split_immediate (rtx * ops) ...@@ -1373,6 +1436,36 @@ spu_split_immediate (rtx * ops)
(VOIDmode, ops[0], gen_rtx_IOR (mode, to, lo))); (VOIDmode, ops[0], gen_rtx_IOR (mode, to, lo)));
return 1; 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: case IC_POOL:
if (reload_in_progress || reload_completed) if (reload_in_progress || reload_completed)
{ {
...@@ -1393,8 +1486,8 @@ spu_split_immediate (rtx * ops) ...@@ -1393,8 +1486,8 @@ spu_split_immediate (rtx * ops)
{ {
if (c == IC_IL2s) if (c == IC_IL2s)
{ {
emit_insn (gen_high (ops[0], ops[1])); emit_move_insn (ops[0], gen_rtx_HIGH (mode, ops[1]));
emit_insn (gen_low (ops[0], ops[0], ops[1])); emit_move_insn (ops[0], gen_rtx_LO_SUM (mode, ops[0], ops[1]));
} }
else if (flag_pic) else if (flag_pic)
emit_insn (gen_pic (ops[0], ops[1])); emit_insn (gen_pic (ops[0], ops[1]));
...@@ -1667,6 +1760,7 @@ spu_expand_prologue (void) ...@@ -1667,6 +1760,7 @@ spu_expand_prologue (void)
REG_NOTES (insn) = REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
real, REG_NOTES (insn)); 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) ...@@ -2329,7 +2423,8 @@ immediate_load_p (rtx op, enum machine_mode mode)
if (CONSTANT_P (op)) if (CONSTANT_P (op))
{ {
enum immediate_class c = classify_immediate (op, mode); 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; return 0;
} }
...@@ -2390,7 +2485,7 @@ classify_immediate (rtx op, enum machine_mode mode) ...@@ -2390,7 +2485,7 @@ classify_immediate (rtx op, enum machine_mode mode)
{ {
HOST_WIDE_INT val; HOST_WIDE_INT val;
unsigned char arr[16]; unsigned char arr[16];
int i, j, repeated, fsmbi; int i, j, repeated, fsmbi, repeat;
gcc_assert (CONSTANT_P (op)); gcc_assert (CONSTANT_P (op));
...@@ -2398,7 +2493,8 @@ classify_immediate (rtx op, enum machine_mode mode) ...@@ -2398,7 +2493,8 @@ classify_immediate (rtx op, enum machine_mode mode)
mode = GET_MODE (op); mode = GET_MODE (op);
/* A V4SI const_vector with all identical symbols is ok. */ /* 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 (op) == CONST_VECTOR
&& GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT && GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
&& GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_DOUBLE && GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_DOUBLE
...@@ -2452,11 +2548,14 @@ classify_immediate (rtx op, enum machine_mode mode) ...@@ -2452,11 +2548,14 @@ classify_immediate (rtx op, enum machine_mode mode)
gcc_assert (GET_MODE_SIZE (mode) > 2); gcc_assert (GET_MODE_SIZE (mode) > 2);
fsmbi = 1; fsmbi = 1;
repeat = 0;
for (i = 0; i < 16 && fsmbi; i++) 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; fsmbi = 0;
if (fsmbi) if (fsmbi)
return IC_FSMBI; return repeat == 0xff ? IC_FSMBI : IC_FSMBI2;
if (cpat_info (arr, GET_MODE_SIZE (mode), 0, 0)) if (cpat_info (arr, GET_MODE_SIZE (mode), 0, 0))
return IC_CPAT; return IC_CPAT;
...@@ -2495,6 +2594,20 @@ which_logical_immediate (HOST_WIDE_INT val) ...@@ -2495,6 +2594,20 @@ which_logical_immediate (HOST_WIDE_INT val)
return SPU_NONE; 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 int
logical_immediate_p (rtx op, enum machine_mode mode) logical_immediate_p (rtx op, enum machine_mode mode)
{ {
...@@ -2505,6 +2618,10 @@ 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 gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE
|| GET_CODE (op) == CONST_VECTOR); || GET_CODE (op) == CONST_VECTOR);
if (GET_CODE (op) == CONST_VECTOR
&& !const_vector_immediate_p (op))
return 0;
if (GET_MODE (op) != VOIDmode) if (GET_MODE (op) != VOIDmode)
mode = GET_MODE (op); mode = GET_MODE (op);
...@@ -2533,6 +2650,10 @@ iohl_immediate_p (rtx op, enum machine_mode mode) ...@@ -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 gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE
|| GET_CODE (op) == CONST_VECTOR); || GET_CODE (op) == CONST_VECTOR);
if (GET_CODE (op) == CONST_VECTOR
&& !const_vector_immediate_p (op))
return 0;
if (GET_MODE (op) != VOIDmode) if (GET_MODE (op) != VOIDmode)
mode = GET_MODE (op); mode = GET_MODE (op);
...@@ -2561,6 +2682,10 @@ arith_immediate_p (rtx op, enum machine_mode mode, ...@@ -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 gcc_assert (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE
|| GET_CODE (op) == CONST_VECTOR); || GET_CODE (op) == CONST_VECTOR);
if (GET_CODE (op) == CONST_VECTOR
&& !const_vector_immediate_p (op))
return 0;
if (GET_MODE (op) != VOIDmode) if (GET_MODE (op) != VOIDmode)
mode = GET_MODE (op); mode = GET_MODE (op);
...@@ -2596,22 +2721,21 @@ arith_immediate_p (rtx op, enum machine_mode mode, ...@@ -2596,22 +2721,21 @@ arith_immediate_p (rtx op, enum machine_mode mode,
int int
spu_legitimate_constant_p (rtx x) spu_legitimate_constant_p (rtx x)
{ {
int i; if (GET_CODE (x) == HIGH)
x = XEXP (x, 0);
/* V4SI with all identical symbols is valid. */ /* 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)) == SYMBOL_REF
|| GET_CODE (CONST_VECTOR_ELT (x, 0)) == LABEL_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)) == CONST))
|| GET_CODE (CONST_VECTOR_ELT (x, 0)) == HIGH))
return CONST_VECTOR_ELT (x, 0) == CONST_VECTOR_ELT (x, 1) 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, 1) == CONST_VECTOR_ELT (x, 2)
&& CONST_VECTOR_ELT (x, 2) == CONST_VECTOR_ELT (x, 3); && CONST_VECTOR_ELT (x, 2) == CONST_VECTOR_ELT (x, 3);
if (VECTOR_MODE_P (GET_MODE (x))) if (GET_CODE (x) == CONST_VECTOR
for (i = 0; i < GET_MODE_NUNITS (GET_MODE (x)); i++) && !const_vector_immediate_p (x))
if (GET_CODE (CONST_VECTOR_ELT (x, i)) != CONST_INT return 0;
&& GET_CODE (CONST_VECTOR_ELT (x, i)) != CONST_DOUBLE)
return 0;
return 1; return 1;
} }
...@@ -2668,7 +2792,7 @@ spu_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED, ...@@ -2668,7 +2792,7 @@ spu_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED,
&& GET_CODE (op1) == CONST_INT && GET_CODE (op1) == CONST_INT
&& INTVAL (op1) >= -0x2000 && INTVAL (op1) >= -0x2000
&& INTVAL (op1) <= 0x1fff && 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; return 1;
if (GET_CODE (op0) == REG if (GET_CODE (op0) == REG
&& INT_REG_OK_FOR_BASE_P (op0, reg_ok_strict) && INT_REG_OK_FOR_BASE_P (op0, reg_ok_strict)
...@@ -3135,7 +3259,6 @@ spu_conditional_register_usage (void) ...@@ -3135,7 +3259,6 @@ spu_conditional_register_usage (void)
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
call_used_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 /* This is called to decide when we can simplify a load instruction. We
...@@ -3149,9 +3272,10 @@ static int ...@@ -3149,9 +3272,10 @@ static int
regno_aligned_for_load (int regno) regno_aligned_for_load (int regno)
{ {
return regno == FRAME_POINTER_REGNUM return regno == FRAME_POINTER_REGNUM
|| regno == HARD_FRAME_POINTER_REGNUM || (frame_pointer_needed && regno == HARD_FRAME_POINTER_REGNUM)
|| regno == STACK_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. */ /* Return TRUE when mem is known to be 16-byte aligned. */
...@@ -3706,10 +3830,10 @@ fsmbi_const_p (rtx x) ...@@ -3706,10 +3830,10 @@ fsmbi_const_p (rtx x)
{ {
if (CONSTANT_P (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. */ of an SImode will always be all 1s, i.e., valid for fsmbi. */
enum immediate_class c = classify_immediate (x, DImode); enum immediate_class c = classify_immediate (x, TImode);
return c == IC_FSMBI; return c == IC_FSMBI || (!flow2_completed && c == IC_FSMBI2);
} }
return 0; return 0;
} }
...@@ -3929,7 +4053,7 @@ reloc_diagnostic (rtx x) ...@@ -3929,7 +4053,7 @@ reloc_diagnostic (rtx x)
/* We use last_assemble_variable_decl to get line information. It's /* 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 not always going to be right and might not even be close, but will
be right for the more common cases. */ be right for the more common cases. */
if (!last_assemble_variable_decl) if (!last_assemble_variable_decl || in_section == ctors_section)
loc_decl = decl; loc_decl = decl;
else else
loc_decl = last_assemble_variable_decl; loc_decl = last_assemble_variable_decl;
...@@ -4346,7 +4470,7 @@ spu_builtin_splats (rtx ops[]) ...@@ -4346,7 +4470,7 @@ spu_builtin_splats (rtx ops[])
constant_to_array (GET_MODE_INNER (mode), ops[1], arr); constant_to_array (GET_MODE_INNER (mode), ops[1], arr);
emit_move_insn (ops[0], array_to_constant (mode, 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 v = rtvec_alloc (4);
RTVEC_ELT (v, 0) = ops[1]; RTVEC_ELT (v, 0) = ops[1];
...@@ -4773,10 +4897,8 @@ spu_check_builtin_parm (struct spu_builtin_description *d, rtx op, int p) ...@@ -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) if (p >= SPU_BTI_7 && p <= SPU_BTI_U18)
{ {
int range = p - SPU_BTI_7; int range = p - SPU_BTI_7;
if (!CONSTANT_P (op)
|| (GET_CODE (op) == CONST_INT if (!CONSTANT_P (op))
&& (INTVAL (op) < spu_builtin_range[range].low
|| INTVAL (op) > spu_builtin_range[range].high)))
error ("%s expects an integer literal in the range [%d, %d].", error ("%s expects an integer literal in the range [%d, %d].",
d->name, d->name,
spu_builtin_range[range].low, spu_builtin_range[range].high); 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) ...@@ -4790,6 +4912,18 @@ spu_check_builtin_parm (struct spu_builtin_description *d, rtx op, int p)
} }
else if (GET_CODE (op) == CONST_INT) else if (GET_CODE (op) == CONST_INT)
v = INTVAL (op); 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) switch (p)
{ {
...@@ -4814,7 +4948,7 @@ spu_check_builtin_parm (struct spu_builtin_description *d, rtx op, int p) ...@@ -4814,7 +4948,7 @@ spu_check_builtin_parm (struct spu_builtin_description *d, rtx op, int p)
if (GET_CODE (op) == LABEL_REF if (GET_CODE (op) == LABEL_REF
|| (GET_CODE (op) == SYMBOL_REF || (GET_CODE (op) == SYMBOL_REF
&& SYMBOL_REF_FUNCTION_P (op)) && 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, warning (0, "%d least significant bits of %s are ignored.", lsbits,
d->name); d->name);
} }
...@@ -4822,30 +4956,29 @@ spu_check_builtin_parm (struct spu_builtin_description *d, rtx op, int p) ...@@ -4822,30 +4956,29 @@ spu_check_builtin_parm (struct spu_builtin_description *d, rtx op, int p)
static void 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[]) rtx target, rtx ops[])
{ {
enum insn_code icode = d->icode; enum insn_code icode = d->icode;
int i = 0; int i = 0, a;
/* Expand the arguments into rtl. */ /* Expand the arguments into rtl. */
if (d->parm[0] != SPU_BTI_VOID) if (d->parm[0] != SPU_BTI_VOID)
ops[i++] = target; 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) if (arg == 0)
abort (); abort ();
ops[i] = expand_expr (arg, NULL_RTX, VOIDmode, 0); ops[i] = expand_expr (arg, NULL_RTX, VOIDmode, 0);
arglist = TREE_CHAIN (arglist);
} }
} }
static rtx static rtx
spu_expand_builtin_1 (struct spu_builtin_description *d, spu_expand_builtin_1 (struct spu_builtin_description *d,
tree arglist, rtx target) tree exp, rtx target)
{ {
rtx pat; rtx pat;
rtx ops[8]; rtx ops[8];
...@@ -4855,7 +4988,7 @@ spu_expand_builtin_1 (struct spu_builtin_description *d, ...@@ -4855,7 +4988,7 @@ spu_expand_builtin_1 (struct spu_builtin_description *d,
tree return_type; tree return_type;
/* Set up ops[] with values from arglist. */ /* 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. */ /* Handle the target operand which must be operand 0. */
i = 0; i = 0;
...@@ -4889,7 +5022,7 @@ spu_expand_builtin_1 (struct spu_builtin_description *d, ...@@ -4889,7 +5022,7 @@ spu_expand_builtin_1 (struct spu_builtin_description *d,
rtx addr, op, pat; rtx addr, op, pat;
/* get addr */ /* get addr */
arg = TREE_VALUE (arglist); arg = CALL_EXPR_ARG (exp, 0);
gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE); gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL); op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
addr = memory_address (mode, op); addr = memory_address (mode, op);
...@@ -4947,10 +5080,10 @@ spu_expand_builtin_1 (struct spu_builtin_description *d, ...@@ -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)) if (!(*insn_data[icode].operand[i].predicate) (ops[i], mode))
ops[i] = spu_force_reg (mode, ops[i]); ops[i] = spu_force_reg (mode, ops[i]);
spu_check_builtin_parm (d, ops[i], d->parm[p]);
} }
switch (insn_data[icode].n_operands) switch (insn_data[icode].n_operands)
...@@ -5012,16 +5145,15 @@ spu_expand_builtin (tree exp, ...@@ -5012,16 +5145,15 @@ spu_expand_builtin (tree exp,
enum machine_mode mode ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED,
int ignore 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; unsigned int fcode = DECL_FUNCTION_CODE (fndecl) - END_BUILTINS;
tree arglist = TREE_OPERAND (exp, 1);
struct spu_builtin_description *d; struct spu_builtin_description *d;
if (fcode < NUM_SPU_BUILTINS) if (fcode < NUM_SPU_BUILTINS)
{ {
d = &spu_builtins[fcode]; d = &spu_builtins[fcode];
return spu_expand_builtin_1 (d, arglist, target); return spu_expand_builtin_1 (d, exp, target);
} }
abort (); abort ();
} }
...@@ -5068,3 +5200,13 @@ spu_builtin_mask_for_load (void) ...@@ -5068,3 +5200,13 @@ spu_builtin_mask_for_load (void)
gcc_assert (d); gcc_assert (d);
return d->fndecl; 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;
}
...@@ -24,6 +24,11 @@ ...@@ -24,6 +24,11 @@
#define OVERRIDE_OPTIONS spu_override_options() #define OVERRIDE_OPTIONS spu_override_options()
#define C_COMMON_OVERRIDE_OPTIONS spu_c_common_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 int target_flags;
extern const char *spu_fixed_range_string; extern const char *spu_fixed_range_string;
...@@ -152,7 +157,7 @@ extern const char *spu_fixed_range_string; ...@@ -152,7 +157,7 @@ extern const char *spu_fixed_range_string;
/* Register Basics */ /* Register Basics */
/* 128-130 are special registers that never appear in assembly code. */ /* 128-130 are special registers that never appear in assembly code. */
#define FIRST_PSEUDO_REGISTER 132 #define FIRST_PSEUDO_REGISTER 131
#define FIXED_REGISTERS { \ #define FIXED_REGISTERS { \
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 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; ...@@ -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, \ 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 { \ #define CALL_USED_REGISTERS { \
...@@ -175,7 +180,7 @@ extern const char *spu_fixed_range_string; ...@@ -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, \ 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 \ #define CONDITIONAL_REGISTER_USAGE \
...@@ -299,9 +304,6 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \ ...@@ -299,9 +304,6 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \
* buffer. Users can also specify it in inline asm. */ * buffer. Users can also specify it in inline asm. */
#define HBR_REGNUM 130 #define HBR_REGNUM 130
/* Used to keep track of enabling and disabling interrupts. */
#define INTR_REGNUM 131
#define MAX_REGISTER_ARGS 72 #define MAX_REGISTER_ARGS 72
#define FIRST_ARG_REGNUM 3 #define FIRST_ARG_REGNUM 3
#define LAST_ARG_REGNUM (FIRST_ARG_REGNUM + MAX_REGISTER_ARGS - 1) #define LAST_ARG_REGNUM (FIRST_ARG_REGNUM + MAX_REGISTER_ARGS - 1)
...@@ -512,7 +514,7 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \ ...@@ -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", \ "$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", \ "$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", \ "$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) #define PRINT_OPERAND(FILE, X, CODE) print_operand(FILE, X, CODE)
......
...@@ -134,8 +134,7 @@ ...@@ -134,8 +134,7 @@
(UNSPEC_CFLTU 37) (UNSPEC_CFLTU 37)
(UNSPEC_STOP 38) (UNSPEC_STOP 38)
(UNSPEC_STOPD 39) (UNSPEC_STOPD 39)
(UNSPEC_IDISABLE 40) (UNSPEC_SET_INTR 40)
(UNSPEC_IENABLE 41)
(UNSPEC_FSCRRD 42) (UNSPEC_FSCRRD 42)
(UNSPEC_FSCRWR 43) (UNSPEC_FSCRWR 43)
(UNSPEC_MFSPR 44) (UNSPEC_MFSPR 44)
...@@ -204,6 +203,11 @@ ...@@ -204,6 +203,11 @@
(define_mode_attr f2i [(SF "SI") (V4SF "V4SI") (define_mode_attr f2i [(SF "SI") (V4SF "V4SI")
(DF "DI") (V2DF "V2DI")]) (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. ;; Used for carry and borrow instructions.
(define_mode_macro CBOP [SI DI V4SI V2DI]) (define_mode_macro CBOP [SI DI V4SI V2DI])
...@@ -293,16 +297,10 @@ ...@@ -293,16 +297,10 @@
stq%p0\t%1,%0" stq%p0\t%1,%0"
[(set_attr "type" "fx2,fx2,shuf,shuf,load,store")]) [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
(define_insn "high" (define_insn "low_<mode>"
[(set (match_operand:SI 0 "spu_reg_operand" "=r") [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
(high:SI (match_operand:SI 1 "immediate_operand" "i")))] (lo_sum:VSI (match_operand:VSI 1 "spu_reg_operand" "0")
"" (match_operand:VSI 2 "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")))]
"" ""
"iohl\t%0,%2@l") "iohl\t%0,%2@l")
...@@ -1193,7 +1191,7 @@ ...@@ -1193,7 +1191,7 @@
(define_insn "mulhisi3_imm" (define_insn "mulhisi3_imm"
[(set (match_operand:SI 0 "spu_reg_operand" "=r") [(set (match_operand:SI 0 "spu_reg_operand" "=r")
(mult:SI (sign_extend:SI (match_operand:HI 1 "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" "mpyi\t%0,%1,%2"
[(set_attr "type" "fp7")]) [(set_attr "type" "fp7")])
...@@ -1209,7 +1207,7 @@ ...@@ -1209,7 +1207,7 @@
(define_insn "umulhisi3_imm" (define_insn "umulhisi3_imm"
[(set (match_operand:SI 0 "spu_reg_operand" "=r") [(set (match_operand:SI 0 "spu_reg_operand" "=r")
(mult:SI (zero_extend:SI (match_operand:HI 1 "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" "mpyui\t%0,%1,%2"
[(set_attr "type" "fp7")]) [(set_attr "type" "fp7")])
...@@ -1753,7 +1751,7 @@ ...@@ -1753,7 +1751,7 @@
"" ""
"@ "@
xor\t%0,%1,%2 xor\t%0,%1,%2
xor%j2i\t%0,%1,%S2") xor%j2i\t%0,%1,%J2")
(define_insn "xordi3" (define_insn "xordi3"
[(set (match_operand:DI 0 "spu_reg_operand" "=r,r") [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
...@@ -1912,17 +1910,17 @@ ...@@ -1912,17 +1910,17 @@
(define_insn "ashl<mode>3" (define_insn "ashl<mode>3"
[(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
(ashift:VHSI (match_operand:VHSI 1 "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>\t%0,%1,%2
shl<bh>i\t%0,%1,%2" shl<bh>i\t%0,%1,%<umask>2"
[(set_attr "type" "fx3")]) [(set_attr "type" "fx3")])
(define_insn_and_split "ashldi3" (define_insn_and_split "ashldi3"
[(set (match_operand:DI 0 "spu_reg_operand" "=r,r") [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
(ashift:DI (match_operand:DI 1 "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"))] (clobber (match_scratch:SI 3 "=&r,X"))]
"" ""
"#" "#"
...@@ -1973,8 +1971,8 @@ ...@@ -1973,8 +1971,8 @@
(match_operand:SI 2 "immediate_operand" "O,P")))] (match_operand:SI 2 "immediate_operand" "O,P")))]
"" ""
"@ "@
shlqbyi\t%0,%1,%2/8 shlqbyi\t%0,%1,%h2
shlqbii\t%0,%1,%2" shlqbii\t%0,%1,%e2"
"!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])" "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
[(set (match_dup:TI 0) [(set (match_dup:TI 0)
(ashift:TI (match_dup:TI 1) (ashift:TI (match_dup:TI 1)
...@@ -1985,7 +1983,7 @@ ...@@ -1985,7 +1983,7 @@
{ {
HOST_WIDE_INT val = INTVAL(operands[2]); HOST_WIDE_INT val = INTVAL(operands[2]);
operands[3] = GEN_INT (val&7); operands[3] = GEN_INT (val&7);
operands[4] = GEN_INT (val&0x78); operands[4] = GEN_INT (val&-8);
} }
[(set_attr "type" "shuf,shuf")]) [(set_attr "type" "shuf,shuf")])
...@@ -2015,7 +2013,7 @@ ...@@ -2015,7 +2013,7 @@
"" ""
"@ "@
shlqbybi\t%0,%1,%2 shlqbybi\t%0,%1,%2
shlqbyi\t%0,%1,%2/8" shlqbyi\t%0,%1,%h2"
[(set_attr "type" "shuf,shuf")]) [(set_attr "type" "shuf,shuf")])
(define_insn "shlqbi_ti" (define_insn "shlqbi_ti"
...@@ -2026,7 +2024,7 @@ ...@@ -2026,7 +2024,7 @@
"" ""
"@ "@
shlqbi\t%0,%1,%2 shlqbi\t%0,%1,%2
shlqbii\t%0,%1,%2" shlqbii\t%0,%1,%e2"
[(set_attr "type" "shuf,shuf")]) [(set_attr "type" "shuf,shuf")])
(define_insn "shlqby_ti" (define_insn "shlqby_ti"
...@@ -2037,7 +2035,7 @@ ...@@ -2037,7 +2035,7 @@
"" ""
"@ "@
shlqby\t%0,%1,%2 shlqby\t%0,%1,%2
shlqbyi\t%0,%1,%2" shlqbyi\t%0,%1,%f2"
[(set_attr "type" "shuf,shuf")]) [(set_attr "type" "shuf,shuf")])
...@@ -2046,12 +2044,12 @@ ...@@ -2046,12 +2044,12 @@
(define_insn_and_split "lshr<mode>3" (define_insn_and_split "lshr<mode>3"
[(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
(lshiftrt:VHSI (match_operand:VHSI 1 "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"))] (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" "reload_completed && GET_CODE (operands[2]) == REG"
[(set (match_dup:VHSI 3) [(set (match_dup:VHSI 3)
(neg:VHSI (match_dup:VHSI 2))) (neg:VHSI (match_dup:VHSI 2)))
...@@ -2065,11 +2063,11 @@ ...@@ -2065,11 +2063,11 @@
(define_insn "rotm_<mode>" (define_insn "rotm_<mode>"
[(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
(lshiftrt:VHSI (match_operand:VHSI 1 "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>m\t%0,%1,%2
rot<bh>mi\t%0,%1,%2" rot<bh>mi\t%0,%1,-%<nmask>2"
[(set_attr "type" "fx3")]) [(set_attr "type" "fx3")])
(define_expand "lshr<mode>3" (define_expand "lshr<mode>3"
...@@ -2095,8 +2093,8 @@ ...@@ -2095,8 +2093,8 @@
(match_operand:SI 2 "immediate_operand" "O,P")))] (match_operand:SI 2 "immediate_operand" "O,P")))]
"" ""
"@ "@
rotqmbyi\t%0,%1,%N2/8 rotqmbyi\t%0,%1,-%h2
rotqmbii\t%0,%1,%N2" rotqmbii\t%0,%1,-%e2"
"!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])" "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
[(set (match_dup:DTI 0) [(set (match_dup:DTI 0)
(lshiftrt:DTI (match_dup:DTI 1) (lshiftrt:DTI (match_dup:DTI 1)
...@@ -2107,7 +2105,7 @@ ...@@ -2107,7 +2105,7 @@
{ {
HOST_WIDE_INT val = INTVAL(operands[2]); HOST_WIDE_INT val = INTVAL(operands[2]);
operands[4] = GEN_INT (val&7); operands[4] = GEN_INT (val&7);
operands[5] = GEN_INT (val&0x78); operands[5] = GEN_INT (val&-8);
} }
[(set_attr "type" "shuf,shuf")]) [(set_attr "type" "shuf,shuf")])
...@@ -2127,7 +2125,8 @@ ...@@ -2127,7 +2125,8 @@
(const_int 7)))) (const_int 7))))
(set (match_dup:DTI 0) (set (match_dup:DTI 0)
(lshiftrt:DTI (match_dup:DTI 3) (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))))] (const_int -8))))]
{ {
emit_insn(gen_subsi3(operands[4], GEN_INT(0), operands[2])); emit_insn(gen_subsi3(operands[4], GEN_INT(0), operands[2]));
...@@ -2137,12 +2136,13 @@ ...@@ -2137,12 +2136,13 @@
(define_insn "rotqmbybi_<mode>" (define_insn "rotqmbybi_<mode>"
[(set (match_operand:DTI 0 "spu_reg_operand" "=r,r") [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
(lshiftrt:DTI (match_operand:DTI 1 "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))))] (const_int -8))))]
"" ""
"@ "@
rotqmbybi\t%0,%1,%2 rotqmbybi\t%0,%1,%2
rotqmbyi\t%0,%1,%2/8" rotqmbyi\t%0,%1,-%H2"
[(set_attr "type" "shuf")]) [(set_attr "type" "shuf")])
(define_insn "rotqmbi_<mode>" (define_insn "rotqmbi_<mode>"
...@@ -2153,7 +2153,7 @@ ...@@ -2153,7 +2153,7 @@
"" ""
"@ "@
rotqmbi\t%0,%1,%2 rotqmbi\t%0,%1,%2
rotqmbii\t%0,%1,%2" rotqmbii\t%0,%1,-%E2"
[(set_attr "type" "shuf")]) [(set_attr "type" "shuf")])
(define_insn "rotqmby_<mode>" (define_insn "rotqmby_<mode>"
...@@ -2164,7 +2164,7 @@ ...@@ -2164,7 +2164,7 @@
"" ""
"@ "@
rotqmby\t%0,%1,%2 rotqmby\t%0,%1,%2
rotqmbyi\t%0,%1,%2" rotqmbyi\t%0,%1,-%F2"
[(set_attr "type" "shuf")]) [(set_attr "type" "shuf")])
...@@ -2173,12 +2173,12 @@ ...@@ -2173,12 +2173,12 @@
(define_insn_and_split "ashr<mode>3" (define_insn_and_split "ashr<mode>3"
[(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
(ashiftrt:VHSI (match_operand:VHSI 1 "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"))] (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" "reload_completed && GET_CODE (operands[2]) == REG"
[(set (match_dup:VHSI 3) [(set (match_dup:VHSI 3)
(neg:VHSI (match_dup:VHSI 2))) (neg:VHSI (match_dup:VHSI 2)))
...@@ -2192,11 +2192,11 @@ ...@@ -2192,11 +2192,11 @@
(define_insn "rotma_<mode>" (define_insn "rotma_<mode>"
[(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
(ashiftrt:VHSI (match_operand:VHSI 1 "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>\t%0,%1,%2
rotma<bh>i\t%0,%1,%2" rotma<bh>i\t%0,%1,-%<nmask>2"
[(set_attr "type" "fx3")]) [(set_attr "type" "fx3")])
(define_insn_and_split "ashrdi3" (define_insn_and_split "ashrdi3"
...@@ -2306,11 +2306,11 @@ ...@@ -2306,11 +2306,11 @@
(define_insn "rotl<mode>3" (define_insn "rotl<mode>3"
[(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r") [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
(rotate:VHSI (match_operand:VHSI 1 "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>\t%0,%1,%2
rot<bh>i\t%0,%1,%2" rot<bh>i\t%0,%1,%<umask>2"
[(set_attr "type" "fx3")]) [(set_attr "type" "fx3")])
(define_insn "rotlti3" (define_insn "rotlti3"
...@@ -2320,9 +2320,9 @@ ...@@ -2320,9 +2320,9 @@
"" ""
"@ "@
rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2 rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
rotqbyi\t%0,%1,%2/8 rotqbyi\t%0,%1,%h2
rotqbii\t%0,%1,%2 rotqbii\t%0,%1,%e2
rotqbyi\t%0,%1,%2/8\;rotqbii\t%0,%0,%2%%8" rotqbyi\t%0,%1,%h2\;rotqbii\t%0,%0,%e2"
[(set_attr "length" "8,4,4,8") [(set_attr "length" "8,4,4,8")
(set_attr "type" "multi1,shuf,shuf,multi1")]) (set_attr "type" "multi1,shuf,shuf,multi1")])
...@@ -2334,7 +2334,7 @@ ...@@ -2334,7 +2334,7 @@
"" ""
"@ "@
rotqbybi\t%0,%1,%2 rotqbybi\t%0,%1,%2
rotqbyi\t%0,%1,%2/8" rotqbyi\t%0,%1,%h2"
[(set_attr "type" "shuf,shuf")]) [(set_attr "type" "shuf,shuf")])
(define_insn "rotqby_ti" (define_insn "rotqby_ti"
...@@ -2345,7 +2345,7 @@ ...@@ -2345,7 +2345,7 @@
"" ""
"@ "@
rotqby\t%0,%1,%2 rotqby\t%0,%1,%2
rotqbyi\t%0,%1,%2" rotqbyi\t%0,%1,%f2"
[(set_attr "type" "shuf,shuf")]) [(set_attr "type" "shuf,shuf")])
(define_insn "rotqbi_ti" (define_insn "rotqbi_ti"
...@@ -2356,7 +2356,7 @@ ...@@ -2356,7 +2356,7 @@
"" ""
"@ "@
rotqbi\t%0,%1,%2 rotqbi\t%0,%1,%2
rotqbii\t%0,%1,%2%%8" rotqbii\t%0,%1,%e2"
[(set_attr "type" "shuf,shuf")]) [(set_attr "type" "shuf,shuf")])
...@@ -3090,7 +3090,8 @@ selb\t%0,%4,%0,%3" ...@@ -3090,7 +3090,8 @@ selb\t%0,%4,%0,%3"
[(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)] [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
"" ""
"" ""
[(set_attr "length" "0")]) [(set_attr "type" "convert")
(set_attr "length" "0")])
(define_expand "epilogue" (define_expand "epilogue"
[(const_int 2)] [(const_int 2)]
...@@ -3234,6 +3235,14 @@ selb\t%0,%4,%0,%3" ...@@ -3234,6 +3235,14 @@ selb\t%0,%4,%0,%3"
"rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16" "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16"
[(set_attr "type" "shuf")]) [(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 ;; misc
...@@ -3285,7 +3294,7 @@ selb\t%0,%4,%0,%3" ...@@ -3285,7 +3294,7 @@ selb\t%0,%4,%0,%3"
(define_insn "hbr" (define_insn "hbr"
[(set (reg:SI 130) [(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)) (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
(unspec [(const_int 0)] UNSPEC_HBR)] (unspec [(const_int 0)] UNSPEC_HBR)]
"" ""
......
...@@ -189,6 +189,9 @@ ...@@ -189,6 +189,9 @@
#define si_clgthi(ra,imm) __builtin_si_clgthi(ra,imm) #define si_clgthi(ra,imm) __builtin_si_clgthi(ra,imm)
#define si_clgt(ra,rb) __builtin_si_clgt(ra,rb) #define si_clgt(ra,rb) __builtin_si_clgt(ra,rb)
#define si_clgti(ra,imm) __builtin_si_clgti(ra,imm) #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_fa(ra,rb) __builtin_si_fa(ra,rb)
#define si_dfa(ra,rb) __builtin_si_dfa(ra,rb) #define si_dfa(ra,rb) __builtin_si_dfa(ra,rb)
#define si_fs(ra,rb) __builtin_si_fs(ra,rb) #define si_fs(ra,rb) __builtin_si_fs(ra,rb)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment