OSDN Git Service

gcc/
authorjbeulich <jbeulich@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 28 Jul 2005 06:58:58 +0000 (06:58 +0000)
committerjbeulich <jbeulich@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 28 Jul 2005 06:58:58 +0000 (06:58 +0000)
2005-07-28 Jan Beulich <jbeulich@novell.com>

* config/ia64/ia64.c (ia64_load_pair_ok): New.
(ia64_print_operand): Describe and handle 'X'.
(ia64_register_move_cost): Also handle FP_REGS.
(ia64_preferred_reload_class): Likewise.
(ia64_secondary_reload_class): Likewise.
(ia64_dependencies_evaluation_hook): New local variable c. Initialize
it. Also check for ITANIUM_CLASS_FLDP.
* config/ia64/ia64.h (FP_REGNO_P): New.
(HARD_REGNO_MODE_OK): Remove explusion of TImode.
(reg_class): Add FP_REGS.
(REG_CLASS_NAMES): Adjust for it.
(REG_CLASS_CONTENTS): Likewise.
(REGNO_REG_CLASS): Use FP_REGS where appropriate.
(REG_CLASS_FROM_LETTER): Handle 'x'.
(CLASS_MAX_NREGS): Handle FP_REGS.
(MEMORY_MOVE_COST): Likewise.
* config/ia64/ia64.md (itanium_class): Add fldp.
(type): Handle fldp.
(movti_internal): More allowable operand combinations. Use ldfp8 when
splitting unnecessary. Remove predicable attribute. Adjust
itanium_class attribute.
(smuldi3_highpart): Remove outdated comment.
(mulditi3, umulditi3, rotlti3): New expanders.
(addti3, subti3, mulditi3_internal, umulditi3_internal, negti2, rotlti3_internal): New insns.
(absti2): Disabled new insn for future reference.
Respective new splitters.
* config/ia64/itanium1.md (1_fldp, 1b_fldp): New insn reservations.
* config/ia64/itanium2.md (2_fldp, 2b_fldp): Likewise.
* config/ia64/ia64-protos.h (ia64_load_pair_ok): New.

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

gcc/ChangeLog
gcc/config/ia64/ia64-protos.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h
gcc/config/ia64/ia64.md
gcc/config/ia64/itanium1.md
gcc/config/ia64/itanium2.md

index d888c82..264b072 100644 (file)
@@ -1,3 +1,35 @@
+2005-07-28 Jan Beulich <jbeulich@novell.com>
+
+       * config/ia64/ia64.c (ia64_load_pair_ok): New.
+       (ia64_print_operand): Describe and handle 'X'.
+       (ia64_register_move_cost): Also handle FP_REGS.
+       (ia64_preferred_reload_class): Likewise.
+       (ia64_secondary_reload_class): Likewise.
+       (ia64_dependencies_evaluation_hook): New local variable c. Initialize
+       it. Also check for ITANIUM_CLASS_FLDP.
+       * config/ia64/ia64.h (FP_REGNO_P): New.
+       (HARD_REGNO_MODE_OK): Remove explusion of TImode.
+       (reg_class): Add FP_REGS.
+       (REG_CLASS_NAMES): Adjust for it.
+       (REG_CLASS_CONTENTS): Likewise.
+       (REGNO_REG_CLASS): Use FP_REGS where appropriate.
+       (REG_CLASS_FROM_LETTER): Handle 'x'.
+       (CLASS_MAX_NREGS): Handle FP_REGS.
+       (MEMORY_MOVE_COST): Likewise.
+       * config/ia64/ia64.md (itanium_class): Add fldp.
+       (type): Handle fldp.
+       (movti_internal): More allowable operand combinations. Use ldfp8 when
+       splitting unnecessary. Remove predicable attribute. Adjust
+       itanium_class attribute.
+       (smuldi3_highpart): Remove outdated comment.
+       (mulditi3, umulditi3, rotlti3): New expanders.
+       (addti3, subti3, mulditi3_internal, umulditi3_internal, negti2, rotlti3_internal): New insns.
+       (absti2): Disabled new insn for future reference.
+       Respective new splitters.
+       * config/ia64/itanium1.md (1_fldp, 1b_fldp): New insn reservations.
+       * config/ia64/itanium2.md (2_fldp, 2b_fldp): Likewise.
+       * config/ia64/ia64-protos.h (ia64_load_pair_ok): New.
+
 2005-07-25  James A. Morrison  <phython@gcc.gnu.org>
 
        PR rtl-optimization/23047
index 8684649..0c6355a 100644 (file)
@@ -41,6 +41,7 @@ extern bool ia64_legitimate_constant_p (rtx);
 
 extern rtx ia64_expand_move (rtx, rtx);
 extern int ia64_move_ok (rtx, rtx);
+extern int ia64_load_pair_ok (rtx, rtx);
 extern int addp4_optimize_ok (rtx, rtx);
 extern void ia64_emit_cond_move (rtx, rtx, rtx);
 extern int ia64_depz_field_mask (rtx, rtx);
index fd97cbe..1873f89 100644 (file)
@@ -690,6 +690,37 @@ ia64_move_ok (rtx dst, rtx src)
     return GET_CODE (src) == CONST_DOUBLE && CONST_DOUBLE_OK_FOR_G (src);
 }
 
+/* Return 1 if the operands are ok for a floating point load pair.  */
+
+int
+ia64_load_pair_ok (rtx dst, rtx src)
+{
+  if (GET_CODE (dst) != REG || !FP_REGNO_P (REGNO (dst)))
+    return 0;
+  if (GET_CODE (src) != MEM || MEM_VOLATILE_P (src))
+    return 0;
+  switch (GET_CODE (XEXP (src, 0)))
+    {
+    case REG:
+    case POST_INC:
+      break;
+    case POST_DEC:
+      return 0;
+    case POST_MODIFY:
+      {
+       rtx adjust = XEXP (XEXP (XEXP (src, 0), 1), 1);
+
+       if (GET_CODE (adjust) != CONST_INT
+           || INTVAL (adjust) != GET_MODE_SIZE (GET_MODE (src)))
+         return 0;
+      }
+      break;
+    default:
+      abort ();
+    }
+  return 1;
+}
+
 int
 addp4_optimize_ok (rtx op1, rtx op2)
 {
@@ -4305,6 +4336,7 @@ ia64_print_operand_address (FILE * stream ATTRIBUTE_UNUSED,
        for Intel assembler.
    U   Print an 8-bit sign extended number (K) as a 64-bit unsigned number
        for Intel assembler.
+   X   A pair of floating point registers.
    r   Print register name, or constant 0 as r0.  HP compatibility for
        Linux kernel.
    v    Print vector constant value as an 8-byte integer value.  */
@@ -4453,6 +4485,13 @@ ia64_print_operand (FILE * file, rtx x, int code)
        }
       break;
 
+    case 'X':
+      {
+       unsigned int regno = REGNO (x);
+       fprintf (file, "%s, %s", reg_names [regno], reg_names [regno + 1]);
+      }
+      return;
+
     case 'r':
       /* If this operand is the constant zero, write it as register zero.
         Any register, zero, or CONST_INT value is OK here.  */
@@ -4682,6 +4721,7 @@ ia64_register_move_cost (enum machine_mode mode, enum reg_class from,
 
     case GR_REGS:
     case FR_REGS:
+    case FP_REGS:
     case GR_AND_FR_REGS:
     case GR_AND_BR_REGS:
     case ALL_REGS:
@@ -4703,6 +4743,7 @@ ia64_preferred_reload_class (rtx x, enum reg_class class)
   switch (class)
     {
     case FR_REGS:
+    case FP_REGS:
       /* Don't allow volatile mem reloads into floating point registers.
         This is defined to force reload to choose the r/m case instead
         of the f/f case when reloading (set (reg fX) (mem/v)).  */
@@ -4768,6 +4809,7 @@ ia64_secondary_reload_class (enum reg_class class,
       break;
 
     case FR_REGS:
+    case FP_REGS:
       /* Need to go through general registers to get to other class regs.  */
       if (regno >= 0 && ! (FR_REGNO_P (regno) || GENERAL_REGNO_P (regno)))
        return GR_REGS;
@@ -6113,16 +6155,19 @@ ia64_dependencies_evaluation_hook (rtx head, rtx tail)
       {
        for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
          {
+           enum attr_itanium_class c;
+
            if (REG_NOTE_KIND (link) != REG_DEP_TRUE)
              continue;
            next = XEXP (link, 0);
-           if ((ia64_safe_itanium_class (next) == ITANIUM_CLASS_ST
-                || ia64_safe_itanium_class (next) == ITANIUM_CLASS_STF)
+           c = ia64_safe_itanium_class (next);
+           if ((c == ITANIUM_CLASS_ST
+                || c == ITANIUM_CLASS_STF)
                && ia64_st_address_bypass_p (insn, next))
              break;
-           else if ((ia64_safe_itanium_class (next) == ITANIUM_CLASS_LD
-                     || ia64_safe_itanium_class (next)
-                     == ITANIUM_CLASS_FLD)
+           else if ((c == ITANIUM_CLASS_LD
+                     || c == ITANIUM_CLASS_FLD
+                     || c == ITANIUM_CLASS_FLDP)
                     && ia64_ld_address_bypass_p (insn, next))
              break;
          }
index 9e52773..8b92ced 100644 (file)
@@ -324,6 +324,7 @@ while (0)
 #define ADDL_REGNO_P(REGNO) ((unsigned HOST_WIDE_INT) (REGNO) <= 3)
 #define GR_REGNO_P(REGNO) ((unsigned HOST_WIDE_INT) (REGNO) <= 127)
 #define FR_REGNO_P(REGNO) ((REGNO) >= 128 && (REGNO) <= 255)
+#define FP_REGNO_P(REGNO) ((REGNO) >= 128 && (REGNO) <= 254 && (REGNO) != 159)
 #define PR_REGNO_P(REGNO) ((REGNO) >= 256 && (REGNO) <= 319)
 #define BR_REGNO_P(REGNO) ((REGNO) >= 320 && (REGNO) <= 327)
 #define GENERAL_REGNO_P(REGNO) \
@@ -651,7 +652,6 @@ while (0)
 #define HARD_REGNO_MODE_OK(REGNO, MODE)                                \
   (FR_REGNO_P (REGNO) ?                                                \
      GET_MODE_CLASS (MODE) != MODE_CC &&                       \
-     (MODE) != TImode &&                                       \
      (MODE) != BImode &&                                       \
      (MODE) != TFmode                                          \
    : PR_REGNO_P (REGNO) ?                                      \
@@ -721,6 +721,7 @@ enum reg_class
   AR_I_REGS,
   ADDL_REGS,
   GR_REGS,
+  FP_REGS,
   FR_REGS,
   GR_AND_BR_REGS,
   GR_AND_FR_REGS,
@@ -737,7 +738,7 @@ enum reg_class
    constants.  These names are used in writing some of the debugging dumps.  */
 #define REG_CLASS_NAMES \
 { "NO_REGS", "PR_REGS", "BR_REGS", "AR_M_REGS", "AR_I_REGS", \
-  "ADDL_REGS", "GR_REGS", "FR_REGS", \
+  "ADDL_REGS", "GR_REGS", "FP_REGS", "FR_REGS", \
   "GR_AND_BR_REGS", "GR_AND_FR_REGS", "ALL_REGS" }
 
 /* An initializer containing the contents of the register classes, as integers
@@ -774,6 +775,10 @@ enum reg_class
   { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,    \
     0x00000000, 0x00000000, 0x00000000, 0x00000000,    \
     0x00000000, 0x00000000, 0x0100 },                  \
+  /* FP_REGS.  */                                      \
+  { 0x00000000, 0x00000000, 0x00000000, 0x00000000,    \
+    0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF,    \
+    0x00000000, 0x00000000, 0x0000 },                  \
   /* FR_REGS.  */                                      \
   { 0x00000000, 0x00000000, 0x00000000, 0x00000000,    \
     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,    \
@@ -801,7 +806,8 @@ enum reg_class
 #define REGNO_REG_CLASS(REGNO) \
 (ADDL_REGNO_P (REGNO) ? ADDL_REGS      \
  : GENERAL_REGNO_P (REGNO) ? GR_REGS   \
- : FR_REGNO_P (REGNO) ? FR_REGS                \
+ : FR_REGNO_P (REGNO) ? (REGNO) != R_FR (31) \
+                       && (REGNO) != R_FR(127) ? FP_REGS : FR_REGS \
  : PR_REGNO_P (REGNO) ? PR_REGS                \
  : BR_REGNO_P (REGNO) ? BR_REGS                \
  : AR_M_REGNO_P (REGNO) ? AR_M_REGS    \
@@ -832,6 +838,7 @@ enum reg_class
  : (CHAR) == 'c' ? PR_REGS             \
  : (CHAR) == 'd' ? AR_M_REGS           \
  : (CHAR) == 'e' ? AR_I_REGS           \
+ : (CHAR) == 'x' ? FP_REGS             \
  : NO_REGS)
 
 /* A C expression which is nonzero if register number NUM is suitable for use
@@ -888,8 +895,8 @@ enum reg_class
 
 #define CLASS_MAX_NREGS(CLASS, MODE) \
   ((MODE) == BImode && (CLASS) == PR_REGS ? 2                  \
-   : ((CLASS) == FR_REGS && (MODE) == XFmode) ? 1              \
-   : ((CLASS) == FR_REGS && (MODE) == XCmode) ? 2              \
+   : (((CLASS) == FR_REGS || (CLASS) == FP_REGS) && (MODE) == XFmode) ? 1 \
+   : (((CLASS) == FR_REGS || (CLASS) == FP_REGS) && (MODE) == XCmode) ? 2 \
    : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
 
 /* In FP regs, we can't change FP values to integer values and vice versa,
@@ -1414,7 +1421,7 @@ do {                                                                      \
 /* A C expression for the cost of moving data of mode M between a
    register and memory.  */
 #define MEMORY_MOVE_COST(MODE,CLASS,IN) \
-  ((CLASS) == GENERAL_REGS || (CLASS) == FR_REGS \
+  ((CLASS) == GENERAL_REGS || (CLASS) == FR_REGS || (CLASS) == FP_REGS \
    || (CLASS) == GR_AND_FR_REGS ? 4 : 10)
 
 /* A C expression for the cost of a branch instruction.  A value of 1 is the
index 18e6cb3..3f43e48 100644 (file)
 ;; which emit instruction that can go in any slot (e.g. nop).
 
 (define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
-       fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld,
-       chk_s,long_i,mmalua,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,
+       fldp,fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,
+       ld,chk_s,long_i,mmalua,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,
         st,syst_m0, syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,
         nop_b,nop_f,nop_i,nop_m,nop_x,lfetch,pre_cycle"
   (const_string "unknown"))
 
 ;; chk_s has an I and an M form; use type A for convenience.
 (define_attr "type" "unknown,A,I,M,F,B,L,X,S"
-  (cond [(eq_attr "itanium_class" "ld,st,fld,stf,sem,nop_m") (const_string "M")
+  (cond [(eq_attr "itanium_class" "ld,st,fld,fldp,stf,sem,nop_m") (const_string "M")
         (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M")
         (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M")
         (eq_attr "itanium_class" "lfetch") (const_string "M")
 })
 
 (define_insn_and_split "*movti_internal"
-  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
-       (match_operand:TI 1 "general_operand"      "ri,m,r"))]
+  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,   *fm,*x,*f,  Q")
+       (match_operand:TI 1 "general_operand"      "r*fim,r,  Q, *fOQ,*f"))]
   "ia64_move_ok (operands[0], operands[1])"
-  "#"
-  "reload_completed"
+  "@
+   #
+   #
+   ldfp8 %X0 = %1%P1
+   #
+   #"
+  "reload_completed && !ia64_load_pair_ok(operands[0], operands[1])"
   [(const_int 0)]
 {
   ia64_split_tmode_move (operands);
   DONE;
 }
-  [(set_attr "itanium_class" "unknown")
-   (set_attr "predicable" "no")])
+  [(set_attr "itanium_class" "unknown,unknown,fldp,unknown,unknown")])
 
 ;; Floating Point Moves
 ;;
    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
   "")
 
-;; ??? There are highpart multiply and add instructions, but we have no way
-;; to generate them.
-
 (define_insn "smuldi3_highpart"
   [(set (match_operand:DI 0 "fr_register_operand" "=f")
        (truncate:DI
 \f
 ;; ::::::::::::::::::::
 ;; ::
+;; :: 128 bit Integer arithmetic
+;; ::
+;; ::::::::::::::::::::
+
+(define_insn "addti3"
+  [(set (match_operand:TI 0 "gr_register_operand" "=&r")
+       (plus:TI (match_operand:TI 1 "gr_register_operand" "%r")
+                (match_operand:TI 2 "gr_reg_or_14bit_operand" "rI")))
+   (clobber (match_scratch:BI 3 "=&c"))]
+  ""
+  "#"
+  [(set_attr "itanium_class" "unknown")])
+
+(define_split
+  [(set (match_operand:TI 0 "register_operand" "")
+       (plus:TI (match_operand:TI 1 "register_operand" "")
+                (match_operand:TI 2 "register_operand" "")))
+   (clobber (match_scratch:BI 3 ""))]
+  "reload_completed"
+  [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3) (ltu:BI (match_dup 0) (match_dup 1)))
+   (cond_exec (eq (match_dup 3) (const_int 0))
+             (set (match_dup 4) (plus:DI (match_dup 5) (match_dup 6))))
+   (cond_exec (ne (match_dup 3) (const_int 0))
+             (set (match_dup 4)
+                  (plus:DI (plus:DI (match_dup 5) (match_dup 6))
+                           (const_int 1))))]
+{
+  operands[4] = gen_highpart (DImode, operands[0]);
+  operands[0] = gen_lowpart (DImode, operands[0]);
+  operands[5] = gen_highpart (DImode, operands[1]);
+  operands[1] = gen_lowpart (DImode, operands[1]);
+  operands[6] = gen_highpart (DImode, operands[2]);
+  operands[2] = gen_lowpart (DImode, operands[2]);
+})
+
+(define_split
+  [(set (match_operand:TI 0 "register_operand" "")
+       (plus:TI (match_operand:TI 1 "register_operand" "")
+                (match_operand:TI 2 "immediate_operand" "")))
+   (clobber (match_scratch:BI 3 ""))]
+  "reload_completed"
+  [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3) (ltu:BI (match_dup 0) (match_dup 1)))
+   (cond_exec (eq (match_dup 3) (const_int 0))
+             (set (match_dup 4)
+                  (plus:DI (match_dup 5) (match_dup 6))))
+   (cond_exec (ne (match_dup 3) (const_int 0))
+             (set (match_dup 4)
+                  (plus:DI (match_dup 5) (match_dup 7))))]
+{
+  operands[4] = gen_highpart (DImode, operands[0]);
+  operands[0] = gen_lowpart (DImode, operands[0]);
+  operands[5] = gen_highpart (DImode, operands[1]);
+  operands[1] = gen_lowpart (DImode, operands[1]);
+  operands[6] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
+  operands[7] = INTVAL (operands[2]) < 0 ? const0_rtx : const1_rtx;
+})
+
+(define_insn "subti3"
+  [(set (match_operand:TI 0 "gr_register_operand" "=&r")
+       (minus:TI (match_operand:TI 1 "gr_reg_or_8bit_operand" "rK")
+                 (match_operand:TI 2 "gr_register_operand" "r")))
+   (clobber (match_scratch:BI 3 "=&c"))]
+  ""
+  "#"
+  [(set_attr "itanium_class" "unknown")])
+
+(define_split
+  [(set (match_operand:TI 0 "register_operand" "")
+       (minus:TI (match_operand:TI 1 "register_operand" "")
+                 (match_operand:TI 2 "register_operand" "")))
+   (clobber (match_scratch:BI 3 "=&c"))]
+  "reload_completed"
+  [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3) (ltu:BI (match_dup 1) (match_dup 0)))
+   (cond_exec (eq (match_dup 3) (const_int 0))
+             (set (match_dup 4) (minus:DI (match_dup 5) (match_dup 6))))
+   (cond_exec (ne (match_dup 3) (const_int 0))
+             (set (match_dup 4)
+                  (plus:DI (not:DI (match_dup 6)) (match_dup 5))))]
+{
+  operands[4] = gen_highpart (DImode, operands[0]);
+  operands[0] = gen_lowpart (DImode, operands[0]);
+  operands[5] = gen_highpart (DImode, operands[1]);
+  operands[1] = gen_lowpart (DImode, operands[1]);
+  operands[6] = gen_highpart (DImode, operands[2]);
+  operands[2] = gen_lowpart (DImode, operands[2]);
+})
+
+(define_split
+  [(set (match_operand:TI 0 "register_operand" "")
+       (minus:TI (match_operand:TI 1 "immediate_operand" "")
+                 (match_operand:TI 2 "register_operand" "")))
+   (clobber (match_scratch:BI 3 "=&c"))]
+  "reload_completed && CONST_OK_FOR_K (INTVAL (operands[1]))"
+  [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3) (gtu:BI (match_dup 0) (match_dup 1)))
+   (cond_exec (ne (match_dup 3) (const_int 0))
+             (set (match_dup 4) (minus:DI (match_dup 6) (match_dup 5))))
+   (cond_exec (eq (match_dup 3) (const_int 0))
+             (set (match_dup 4) (minus:DI (match_dup 7) (match_dup 5))))]
+{
+  operands[4] = gen_highpart (DImode, operands[0]);
+  operands[0] = gen_lowpart (DImode, operands[0]);
+  operands[5] = gen_highpart (DImode, operands[2]);
+  operands[2] = gen_lowpart (DImode, operands[2]);
+  operands[6] = INTVAL (operands[1]) < 0 ? GEN_INT (-2) : constm1_rtx;
+  operands[7] = INTVAL (operands[1]) < 0 ? constm1_rtx : const0_rtx;
+})
+
+(define_expand "mulditi3"
+  [(set (match_operand:TI 0 "fr_register_operand" "")
+       (mult:TI (sign_extend:TI
+                  (match_operand:DI 1 "fr_register_operand" ""))
+                (sign_extend:TI
+                  (match_operand:DI 2 "fr_register_operand" ""))))]
+  ""
+  "")
+
+(define_insn_and_split "*mulditi3_internal"
+  [(set (match_operand:TI 0 "fr_register_operand" "=&f")
+       (mult:TI (sign_extend:TI
+                  (match_operand:DI 1 "fr_register_operand" "%f"))
+                (sign_extend:TI
+                  (match_operand:DI 2 "fr_register_operand" "f"))))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (match_dup 0) (mult:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3) (truncate:DI
+                       (lshiftrt:TI
+                         (mult:TI (sign_extend:TI (match_dup 1))
+                                  (sign_extend:TI (match_dup 2)))
+                         (const_int 64))))]
+{
+  operands[3] = gen_highpart (DImode, operands[0]);
+  operands[0] = gen_lowpart (DImode, operands[0]);
+}
+  [(set_attr "itanium_class" "unknown")])
+
+(define_expand "umulditi3"
+  [(set (match_operand:TI 0 "fr_register_operand" "")
+       (mult:TI (zero_extend:TI
+                  (match_operand:DI 1 "fr_register_operand" ""))
+                (zero_extend:TI
+                  (match_operand:DI 2 "fr_register_operand" ""))))]
+  ""
+  "")
+
+(define_insn_and_split "*umulditi3_internal"
+  [(set (match_operand:TI 0 "fr_register_operand" "=&f")
+       (mult:TI (zero_extend:TI
+                  (match_operand:DI 1 "fr_register_operand" "%f"))
+                (zero_extend:TI
+                  (match_operand:DI 2 "fr_register_operand" "f"))))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (match_dup 0) (mult:DI (match_dup 1) (match_dup 2)))
+   (set (match_dup 3) (truncate:DI
+                       (lshiftrt:TI
+                         (mult:TI (zero_extend:TI (match_dup 1))
+                                  (zero_extend:TI (match_dup 2)))
+                         (const_int 64))))]
+{
+  operands[3] = gen_highpart (DImode, operands[0]);
+  operands[0] = gen_lowpart (DImode, operands[0]);
+}
+  [(set_attr "itanium_class" "unknown")])
+
+(define_insn_and_split "negti2"
+  [(set (match_operand:TI 0 "gr_register_operand" "=&r")
+       (neg:TI (match_operand:TI 1 "gr_register_operand" "r")))
+   (clobber (match_scratch:BI 2 "=&c"))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (match_dup 2) (eq:BI (match_dup 1) (const_int 0)))
+   (set (match_dup 0) (minus:DI (const_int 0) (match_dup 1)))
+   (cond_exec (eq (match_dup 2) (const_int 0))
+             (set (match_dup 3) (minus:DI (const_int -1) (match_dup 4))))
+   (cond_exec (ne (match_dup 2) (const_int 0))
+             (set (match_dup 3) (minus:DI (const_int 0) (match_dup 4))))]
+{
+  operands[3] = gen_highpart (DImode, operands[0]);
+  operands[0] = gen_lowpart (DImode, operands[0]);
+  operands[4] = gen_highpart (DImode, operands[1]);
+  operands[1] = gen_lowpart (DImode, operands[1]);
+}
+  [(set_attr "itanium_class" "unknown")])
+\f
+;; ::::::::::::::::::::
+;; ::
 ;; :: 32 bit floating point arithmetic
 ;; ::
 ;; ::::::::::::::::::::
   DONE;
 })
 
+(define_expand "rotlti3"
+  [(set (match_operand:TI 0 "gr_register_operand" "")
+       (rotate:TI (match_operand:TI 1 "gr_register_operand" "")
+                  (match_operand:DI 2 "nonmemory_operand" "")))]
+  ""
+{
+  if (! dshift_count_operand (operands[2], DImode))
+    FAIL;
+})
+
+(define_insn_and_split "*rotlti3_internal"
+  [(set (match_operand:TI 0 "gr_register_operand" "=&r")
+       (rotate:TI (match_operand:TI 1 "gr_register_operand" "r")
+                  (match_operand:DI 2 "dshift_count_operand" "n")))]
+  ""
+  "#"
+  "reload_completed"
+  [(const_int 0)]
+{
+  HOST_WIDE_INT count = INTVAL (operands[2]);
+  rtx rl = gen_lowpart (DImode, operands[0]);
+  rtx rh = gen_highpart (DImode, operands[0]);
+  rtx lo = gen_lowpart (DImode, operands[1]);
+  rtx hi = gen_highpart (DImode, operands[1]);
+  rtx countlo = GEN_INT (-count & 63);
+
+  if (count & 64)
+    {
+      if (count & 63)
+       {
+         emit_insn (gen_shrp (rl, hi, lo, countlo));
+         emit_insn (gen_shrp (rh, lo, hi, countlo));
+       }
+      else
+       {
+         emit_move_insn (rl, hi);
+         emit_move_insn (rh, lo);
+       }
+    }
+  else
+    {
+      emit_insn (gen_shrp (rl, lo, hi, countlo));
+      emit_insn (gen_shrp (rh, hi, lo, countlo));
+    }
+  DONE;
+}
+  [(set_attr "itanium_class" "unknown")])
+
 (define_insn "shrp"
   [(set (match_operand:DI 0 "gr_register_operand" "=r")
        (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")
index 21c8764..e93475a 100644 (file)
   (and (and (eq_attr "cpu" "itanium")
             (eq_attr "itanium_class" "fld"))
        (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+(define_insn_reservation "1_fldp"    9
+  (and (and (eq_attr "cpu" "itanium")
+            (eq_attr "itanium_class" "fldp"))
+       (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
 (define_insn_reservation "1_fmac"    5
   (and (and (eq_attr "cpu" "itanium")
             (eq_attr "itanium_class" "fmac"))
   (and (and (eq_attr "cpu" "itanium")
             (eq_attr "itanium_class" "fld"))
        (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_fldp"    9
+  (and (and (eq_attr "cpu" "itanium")
+            (eq_attr "itanium_class" "fldp"))
+       (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
 (define_insn_reservation "1b_fmac"    5
   (and (and (eq_attr "cpu" "itanium")
             (eq_attr "itanium_class" "fmac"))
index e00341a..f16d185 100644 (file)
   (and (and (eq_attr "cpu" "itanium2")
             (eq_attr "itanium_class" "fld"))
        (eq (symbol_ref "bundling_p") (const_int 0))) "2_M")
+(define_insn_reservation "2_fldp"    6
+  (and (and (eq_attr "cpu" "itanium2")
+            (eq_attr "itanium_class" "fldp"))
+       (eq (symbol_ref "bundling_p") (const_int 0)))
+  "2_M_only_um01")
 (define_insn_reservation "2_fmac"    4
   (and (and (eq_attr "cpu" "itanium2")
             (eq_attr "itanium_class" "fmac"))
   (and (and (eq_attr "cpu" "itanium2")
             (eq_attr "itanium_class" "fld"))
        (ne (symbol_ref "bundling_p") (const_int 0))) "2b_M")
+(define_insn_reservation "2b_fldp"    6
+  (and (and (eq_attr "cpu" "itanium2")
+            (eq_attr "itanium_class" "fldp"))
+       (ne (symbol_ref "bundling_p") (const_int 0)))
+  "2b_M_only_um01")
 (define_insn_reservation "2b_fmac"    4
   (and (and (eq_attr "cpu" "itanium2")
             (eq_attr "itanium_class" "fmac"))