OSDN Git Service

2007-02-21 Trevor Smigiel <trevor_smigiel@playstation.sony.com>
authortsmigiel <tsmigiel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 Feb 2007 23:28:46 +0000 (23:28 +0000)
committertsmigiel <tsmigiel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 Feb 2007 23:28:46 +0000 (23:28 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122210 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/spu/constraints.md
gcc/config/spu/predicates.md
gcc/config/spu/spu-builtins.def
gcc/config/spu/spu-builtins.md
gcc/config/spu/spu-modes.def
gcc/config/spu/spu-protos.h
gcc/config/spu/spu.c
gcc/config/spu/spu.h
gcc/config/spu/spu.md
gcc/config/spu/spu_internals.h

index 37f33bb..f85cc79 100644 (file)
@@ -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
 2007-02-21  Paul Brook  <paul@codesourcery.com>
 
        * config/arm/arm.c (thumb2_final_prescan_insn): Don't incrememnt
index abc319b..1006b07 100644 (file)
@@ -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")
 (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."
 
 (define_constraint "Y"
   "An immediate for and/xor/or instructions.  const_int is sign extended as a 128 bit."
 (define_constraint "O"
   "An unsigned 7-bit constant whose 3 least significant bits are 0."
   (and (match_code "const_int")
 (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"
 
 (define_constraint "P"
   "An unsigned 3-bit constant for 16-byte rotates and shifts"
index 9d343e6..8b31e65 100644 (file)
     return 0;
   })
 
     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. 
 
 ;; 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. 
index c8b7851..6ae382f 100644 (file)
@@ -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_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))
 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))
index 9b9a21b..5cd3b54 100644 (file)
   ""
   "@
    mpy\t%0,%1,%2
   ""
   "@
    mpy\t%0,%1,%2
-   mpyi\t%0,%1,%H2"
+   mpyi\t%0,%1,%2"
   [(set_attr "type" "fp7")])
 
 (define_insn "spu_mpyu"
   [(set_attr "type" "fp7")])
 
 (define_insn "spu_mpyu"
   ""
   "@
    mpyu\t%0,%1,%2
   ""
   "@
    mpyu\t%0,%1,%2
-   mpyui\t%0,%1,%H2"
+   mpyui\t%0,%1,%2"
   [(set_attr "type" "fp7")])
 
 (define_insn "spu_mpya"
   [(set_attr "type" "fp7")])
 
 (define_insn "spu_mpya"
   [(set_attr "type" "br")])
 
 ;; interrupt disable/enable
   [(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
 (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)))])]
   ""
      (clobber (match_dup:SI 0))
      (clobber (mem:BLK (scratch)))])]
   ""
 
 (define_expand "spu_ienable"
   [(parallel
 
 (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"
      (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"
    (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
    (clobber (mem:BLK (scratch)))]
   "! flag_pic"
    (set_attr "type" "multi0")])
 
 (define_insn "set_intr_pic"
    (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"
    (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
    (clobber (mem:BLK (scratch)))]
   "flag_pic"
   [(set_attr "length" "12")
    (set_attr "type" "multi1")])
 
   [(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"
 (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"
   "! 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"
   "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_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"
    (return)]
   ""
   "bi%I0\t$lr"
 
 (define_peephole2
   [(parallel
 
 (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))
      (clobber (match_operand:SI 1 "spu_reg_operand"))
      (clobber (mem:BLK (scratch)))])
    (use (reg:SI 0))
   ""
   [(use (reg:SI 0))
    (parallel
   ""
   [(use (reg:SI 0))
    (parallel
-    [(set (reg:INTR 131) (match_dup 0))
+    [(unspec_volatile [(match_dup:SI 0)] UNSPEC_SET_INTR)
      (return)])]
   "")
 
      (return)])]
   "")
 
index 49d577b..9d33fef 100644 (file)
@@ -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 */ 
         
 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);
 /* 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);
index 6f87ec0..4caaf1b 100644 (file)
@@ -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 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);
 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_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);
 
 /* spu-c.c */
 extern tree spu_resolve_overloaded_builtin (tree fndecl, tree fnargs);
index 9adeacf..252183b 100644 (file)
@@ -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_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);
 };
 
 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;
 
 
 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
 /* 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)
 {
 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)
   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:
                fprintf (file, "hu");
              break;
            case IC_FSMBI:
+           case IC_FSMBI2:
            case IC_IL2:
            case IC_IL2s:
            case IC_POOL:
            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:
              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)
              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:
              break;
            case IC_IL2:
            case IC_IL2s:
+           case IC_FSMBI2:
            case IC_POOL:
              abort ();
            }
            case IC_POOL:
              abort ();
            }
@@ -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:
       if (xcode == REG)
        fprintf (file, "%s", reg_names[REGNO (x)]);
     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;
 
        output_addr_const (file, x);
       return;
 
+      /* unsed letters
+                     o qr  uvw yz
+       AB            OPQR  UVWXYZ */
     default:
       output_operand_lossage ("invalid %%xn code");
     }
     default:
       output_operand_lossage ("invalid %%xn code");
     }
@@ -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
-   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)
 {
 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;
       }
                   (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)
        {
     case IC_POOL:
       if (reload_in_progress || reload_completed)
        {
@@ -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_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]));
            }
          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));
          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);
   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;
 }
     }
   return 0;
 }
@@ -2390,7 +2485,7 @@ classify_immediate (rtx op, enum machine_mode mode)
 {
   HOST_WIDE_INT val;
   unsigned char arr[16];
 {
   HOST_WIDE_INT val;
   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)
     mode = GET_MODE (op);
 
   /* A V4SI const_vector with all identical symbols is ok. */
     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
       && 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;
       gcc_assert (GET_MODE_SIZE (mode) > 2);
 
       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;
       if (fsmbi)
          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;
 
       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 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)
 {
 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);
 
   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);
 
   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);
 
   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);
 
   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);
 
   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);
 
   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
 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)) == LABEL_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)) == 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);
 
     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;
 }
 
   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
            && 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)
          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;
     }
       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
 }
 
 /* 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_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 == 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)
 {
   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);
-      return c == IC_FSMBI;
+      enum immediate_class c = classify_immediate (x, TImode);
+      return c == IC_FSMBI || (!flow2_completed && c == IC_FSMBI2);
     }
   return 0;
 }
     }
   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. */
   /* 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;
     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));
     }
       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];
     {
       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 (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);
        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_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)
        {
 
       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))
       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);
     }
        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
 
 
 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;
                     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;
 
 
   /* 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);
       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,
     }
 }
 
 static rtx
 spu_expand_builtin_1 (struct spu_builtin_description *d,
-                     tree arglist, rtx target)
+                     tree exp, rtx target)
 {
   rtx pat;
   rtx ops[8];
 {
   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. */
   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;
 
   /* 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 */
       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);
       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]);
       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)
     }
 
   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)
 {
                    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;
   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];
 
   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 ();
 }
     }
   abort ();
 }
@@ -5068,3 +5200,13 @@ spu_builtin_mask_for_load (void)
   gcc_assert (d);
   return d->fndecl;
 }
   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;
+}       
index 240d245..1fcc234 100644 (file)
 #define OVERRIDE_OPTIONS spu_override_options()
 #define C_COMMON_OVERRIDE_OPTIONS spu_c_common_override_options()
 
 #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;
 
 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. */
 /* 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, \
 
 #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, \
     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;
     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;        \
  * buffer.  Users can also specify it in inline asm. */
 #define HBR_REGNUM 130
 
  * 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)
 #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", \
  "$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)
 }
 
 #define PRINT_OPERAND(FILE, X, CODE)  print_operand(FILE, X, CODE)
index 523ecec..ccaf485 100644 (file)
  (UNSPEC_CFLTU          37)
  (UNSPEC_STOP           38)
  (UNSPEC_STOPD          39)
  (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)
  (UNSPEC_FSCRRD         42)
  (UNSPEC_FSCRWR         43)
  (UNSPEC_MFSPR          44)
 (define_mode_attr f2i [(SF "SI") (V4SF "V4SI")
                        (DF "DI") (V2DF "V2DI")])
 
 (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])
 
 ;; Used for carry and borrow instructions.
 (define_mode_macro CBOP  [SI DI V4SI V2DI])
 
    stq%p0\t%1,%0"
   [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
 
    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")
 
   ""
   "iohl\t%0,%2@l")
 
 (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"))
 (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")])
   ""
   "mpyi\t%0,%1,%2"
   [(set_attr "type" "fp7")])
 (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"))
 (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")])
   ""
   "mpyui\t%0,%1,%2"
   [(set_attr "type" "fp7")])
   ""
   "@
   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"
   [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
 
 (define_insn "xordi3"
   [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
 (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")
 (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>\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")
   [(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"))]
   ""
   "#"
    (clobber (match_scratch:SI 3 "=&r,X"))]
   ""
   "#"
                   (match_operand:SI 2 "immediate_operand" "O,P")))]
   ""
   "@
                   (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)
   "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
   [(set (match_dup:TI 0)
        (ashift:TI (match_dup:TI 1)
   {
     HOST_WIDE_INT val = INTVAL(operands[2]);
     operands[3] = GEN_INT (val&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")])
 
   }
   [(set_attr "type" "shuf,shuf")])
 
   ""
   "@
    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")])
 
 (define_insn "shlqbi_ti"
   [(set_attr "type" "shuf,shuf")])
 
 (define_insn "shlqbi_ti"
   ""
   "@
    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")])
 
 (define_insn "shlqby_ti"
   [(set_attr "type" "shuf,shuf")])
 
 (define_insn "shlqby_ti"
   ""
   "@
    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")])
 
 \f
   [(set_attr "type" "shuf,shuf")])
 
 \f
 (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")
 (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"))]
   ""
   "@
    #
    (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)))
   "reload_completed && GET_CODE (operands[2]) == REG"
   [(set (match_dup:VHSI 3)
        (neg:VHSI (match_dup:VHSI 2)))
 (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")
 (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>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"
   [(set_attr "type" "fx3")])
  
 (define_expand "lshr<mode>3"
                      (match_operand:SI 2 "immediate_operand" "O,P")))]
   ""
   "@
                      (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)
   "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
   [(set (match_dup:DTI 0)
        (lshiftrt:DTI (match_dup:DTI 1)
   {
     HOST_WIDE_INT val = INTVAL(operands[2]);
     operands[4] = GEN_INT (val&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")])
 
   }
   [(set_attr "type" "shuf,shuf")])
 
                             (const_int 7))))
    (set (match_dup:DTI 0)
        (lshiftrt:DTI (match_dup:DTI 3)
                             (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]));
                             (const_int -8))))]
   {
     emit_insn(gen_subsi3(operands[4], GEN_INT(0), operands[2]));
 (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")
 (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
                              (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>"
   [(set_attr "type" "shuf")])
 
 (define_insn "rotqmbi_<mode>"
   ""
   "@
    rotqmbi\t%0,%1,%2
   ""
   "@
    rotqmbi\t%0,%1,%2
-   rotqmbii\t%0,%1,%2"
+   rotqmbii\t%0,%1,-%E2"
   [(set_attr "type" "shuf")])
 
 (define_insn "rotqmby_<mode>"
   [(set_attr "type" "shuf")])
 
 (define_insn "rotqmby_<mode>"
   ""
   "@
    rotqmby\t%0,%1,%2
   ""
   "@
    rotqmby\t%0,%1,%2
-   rotqmbyi\t%0,%1,%2"
+   rotqmbyi\t%0,%1,-%F2"
   [(set_attr "type" "shuf")])
 
 \f
   [(set_attr "type" "shuf")])
 
 \f
 (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")
 (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"))]
   ""
   "@
    #
    (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)))
   "reload_completed && GET_CODE (operands[2]) == REG"
   [(set (match_dup:VHSI 3)
        (neg:VHSI (match_dup:VHSI 2)))
 (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")
 (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>\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"
   [(set_attr "type" "fx3")])
  
 (define_insn_and_split "ashrdi3"
 (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")
 (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>\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"
   [(set_attr "type" "fx3")])
 
 (define_insn "rotlti3"
   ""
   "@
   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
-  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")])
 
   [(set_attr "length" "8,4,4,8")
    (set_attr "type" "multi1,shuf,shuf,multi1")])
 
   ""
   "@
   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")])
 
 (define_insn "rotqby_ti"
   [(set_attr "type" "shuf,shuf")])
 
 (define_insn "rotqby_ti"
   ""
   "@
   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")])
 
 (define_insn "rotqbi_ti"
   [(set_attr "type" "shuf,shuf")])
 
 (define_insn "rotqbi_ti"
   ""
   "@
   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")])
 
 \f
   [(set_attr "type" "shuf,shuf")])
 
 \f
@@ -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"
   [(const_int 2)]
 
 (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")])
 
   "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")])
+
 \f
 ;; misc
 
 \f
 ;; misc
 
@@ -3285,7 +3294,7 @@ selb\t%0,%4,%0,%3"
 
 (define_insn "hbr"
   [(set (reg:SI 130)
 
 (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)]
   ""
                    (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
    (unspec [(const_int 0)] UNSPEC_HBR)]
   ""
index 6a71f27..ecc8dc5 100644 (file)
 #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_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)
 #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)