ia64.c (ia64_load_pair_ok): New.
gcc/ 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. From-SVN: r102463
This commit is contained in:
parent
9e7705cbd1
commit
a71aef0bb3
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -123,15 +123,15 @@
|
|||
;; 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")
|
||||
|
@ -659,18 +659,22 @@
|
|||
})
|
||||
|
||||
(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
|
||||
;;
|
||||
|
@ -2140,9 +2144,6 @@
|
|||
(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
|
||||
|
@ -2493,6 +2494,200 @@
|
|||
|
||||
;; ::::::::::::::::::::
|
||||
;; ::
|
||||
;; :: 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")])
|
||||
|
||||
;; ::::::::::::::::::::
|
||||
;; ::
|
||||
;; :: 32 bit floating point arithmetic
|
||||
;; ::
|
||||
;; ::::::::::::::::::::
|
||||
|
@ -4505,6 +4700,54 @@
|
|||
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")
|
||||
|
|
|
@ -529,6 +529,10 @@
|
|||
(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"))
|
||||
|
@ -1407,6 +1411,10 @@
|
|||
(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"))
|
||||
|
|
|
@ -734,6 +734,11 @@
|
|||
(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"))
|
||||
|
@ -1541,6 +1546,11 @@
|
|||
(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"))
|
||||
|
|
Loading…
Reference in New Issue