return 0;
}
+/* Return 1 if OP is a signed 8-bit constant. Int multiplication
+ by such constants completes more quickly. */
+
+int
+s8bit_cint_operand (op, mode)
+ rtx op;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+ return ( GET_CODE (op) == CONST_INT
+ && (INTVAL (op) >= -128 && INTVAL (op) <= 127));
+}
+
/* Return 1 if OP is a constant that can fit in a D field. */
int
if (GET_CODE (operands[1]) != LABEL_REF)
emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
+#if TARGET_MACHO
/* Darwin uses a special PIC legitimizer. */
if (DEFAULT_ABI == ABI_DARWIN && flag_pic)
{
-#if TARGET_MACHO
- rtx temp_reg = ((reload_in_progress || reload_completed)
- ? operands[0] : NULL);
-
operands[1] =
rs6000_machopic_legitimize_pic_address (operands[1], mode,
- temp_reg);
-#endif
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
+ operands[0]);
+ if (operands[0] != operands[1])
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
return;
}
+#endif
/* If we are to limit the number of things we put in the TOC and
this is a symbol plus a constant we can add in one insn,
output_addr_const (file, XEXP (x, 1));
fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
}
+#endif
+#if TARGET_MACHO
+ else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
+ && CONSTANT_P (XEXP (x, 1)))
+ {
+ fprintf (file, "lo16(");
+ output_addr_const (file, XEXP (x, 1));
+ fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
+ }
#endif
else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
{
position-independent addresses go into a reg. This is REG if non
zero, otherwise we allocate register(s) as necessary. */
-#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x4000) < 0x8000)
+#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x8000) < 0x10000)
rtx
rs6000_machopic_legitimize_pic_address (orig, mode, reg)
else if (! reload_in_progress && ! reload_completed)
offset = force_reg (Pmode, offset);
else
- abort ();
+ {
+ rtx mem = force_const_mem (Pmode, orig);
+ return machopic_legitimize_pic_address (mem, Pmode, reg);
+ }
}
return gen_rtx (PLUS, Pmode, base, offset);
}
\f
;; Define an insn type attribute. This is used in function unit delay
;; computations.
-(define_attr "type" "integer,load,store,fpload,fpstore,vecload,vecstore,imul,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,vecsimple,veccomplex,veccmp,vecperm,vecfloat,altivec"
+(define_attr "type" "integer,load,store,fpload,fpstore,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,vecsimple,veccomplex,veccmp,vecperm,vecfloat,altivec"
(const_string "integer"))
;; Length (in bytes).
1 1)
(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul")
+ (and (eq_attr "type" "imul,imul2,imul3")
(eq_attr "cpu" "ppc403"))
4 4)
(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul")
+ (and (eq_attr "type" "imul,imul2,imul3")
(eq_attr "cpu" "rios1,ppc601,ppc603"))
5 5)
(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul")
+ (and (eq_attr "type" "imul,imul2,imul3")
(eq_attr "cpu" "rs64a"))
20 14)
1 1)
(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul")
+ (and (eq_attr "type" "imul,imul2,imul3")
(eq_attr "cpu" "rios2"))
2 2)
13 13)
(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
+ (and (eq_attr "type" "imul,imul2,imul3")
(eq_attr "cpu" "rios2"))
2 2)
; MPCCORE has separate IMUL/IDIV unit for multicycle instructions
; Divide latency varies greatly from 2-11, use 6 as average
(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
+ (and (eq_attr "type" "imul,imul2,imul3")
(eq_attr "cpu" "mpccore"))
2 1)
1 1)
(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
+ (and (eq_attr "type" "imul,imul2,imul3")
(eq_attr "cpu" "ppc604"))
4 2)
(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
+ (and (eq_attr "type" "imul,imul2,imul3")
(eq_attr "cpu" "ppc620,ppc630"))
5 3)
5 3)
(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
+ (and (eq_attr "type" "imul,imul2,imul3")
(eq_attr "cpu" "ppc604e"))
2 1)
(eq_attr "cpu" "ppc7450"))
4 4)
+(define_function_unit "imuldiv" 1 0
+ (and (eq_attr "type" "imul2,imul3")
+ (eq_attr "cpu" "ppc7450"))
+ 3 1)
+
(define_function_unit "imuldiv" 1 0
(and (eq_attr "type" "idiv")
(eq_attr "cpu" "ppc7450"))
(eq_attr "cpu" "ppc750,ppc7400"))
4 4)
+(define_function_unit "iu2" 2 0
+ (and (eq_attr "type" "imul2")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ 3 2)
+
+(define_function_unit "iu2" 2 0
+ (and (eq_attr "type" "imul3")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ 2 1)
+
(define_function_unit "iu2" 2 0
(and (eq_attr "type" "idiv")
(eq_attr "cpu" "ppc750,ppc7400"))
(eq_attr "cpu" "ppc750,ppc7400"))
4 4)
+(define_function_unit "imuldiv" 1 0
+ (and (eq_attr "type" "imul2")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ 3 2)
+
+(define_function_unit "imuldiv" 1 0
+ (and (eq_attr "type" "imul3")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ 2 1)
+
(define_function_unit "imuldiv" 1 0
(and (eq_attr "type" "idiv")
(eq_attr "cpu" "ppc750,ppc7400"))
; some extra cycles added by TARGET_SCHED_ADJUST_COST between compare
; and a following branch, to reduce mispredicts
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 1 1)
-
(define_function_unit "iu3" 3 0
(and (eq_attr "type" "compare,delayed_compare")
(eq_attr "cpu" "ppc7450"))
(define_function_unit "bpu" 1 0
(and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "mpccore,ppc403,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450"))
+ (eq_attr "cpu" "mpccore,ppc403,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630"))
4 1)
+(define_function_unit "sru" 1 0
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ 2 2)
+
+(define_function_unit "imuldiv" 1 0
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc7450"))
+ 2 2)
+
(define_function_unit "bpu" 1 0
(and (eq_attr "type" "cr_logical")
(eq_attr "cpu" "rios1,rios2,ppc604"))
"@
{muls|mullw} %0,%1,%2
{muli|mulli} %0,%1,%2"
- [(set_attr "type" "imul")])
+ [(set (attr "type")
+ (cond [(match_operand:SI 2 "s8bit_cint_operand" "")
+ (const_string "imul3")
+ (match_operand:SI 2 "short_cint_operand" "")
+ (const_string "imul2")]
+ (const_string "imul")))])
(define_insn "mulsi3_no_mq"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
"@
{muls|mullw} %0,%1,%2
{muli|mulli} %0,%1,%2"
- [(set_attr "type" "imul")])
+ [(set (attr "type")
+ (cond [(match_operand:SI 2 "s8bit_cint_operand" "")
+ (const_string "imul3")
+ (match_operand:SI 2 "short_cint_operand" "")
+ (const_string "imul2")]
+ (const_string "imul")))])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
[(set_attr "type" "load")
(set_attr "length" "4")])
+(define_insn "movsi_low_st"
+ [(set (mem:SI (lo_sum:SI (match_operand:SI 1 "register_operand" "b")
+ (match_operand 2 "" "")))
+ (match_operand:SI 0 "gpc_reg_operand" "r"))]
+ "TARGET_MACHO && ! TARGET_64BIT"
+ "{st|stw} %0,lo16(%2)(%1)"
+ [(set_attr "type" "store")
+ (set_attr "length" "4")])
+
+(define_insn "movdf_low"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (mem:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "b")
+ (match_operand 2 "" ""))))]
+ "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT"
+ "lfd %0,lo16(%2)(%1)"
+ [(set_attr "type" "load")
+ (set_attr "length" "4")])
+
+(define_insn "movdf_low_st"
+ [(set (mem:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "b")
+ (match_operand 2 "" "")))
+ (match_operand:DF 0 "gpc_reg_operand" "f"))]
+ "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT"
+ "stfd %0,lo16(%2)(%1)"
+ [(set_attr "type" "store")
+ (set_attr "length" "4")])
+
+(define_insn "movsf_low"
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+ (mem:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "b")
+ (match_operand 2 "" ""))))]
+ "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT"
+ "lfs %0,lo16(%2)(%1)"
+ [(set_attr "type" "load")
+ (set_attr "length" "4")])
+
+(define_insn "movsf_low_st"
+ [(set (mem:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "b")
+ (match_operand 2 "" "")))
+ (match_operand:SF 0 "gpc_reg_operand" "f"))]
+ "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT"
+ "stfs %0,lo16(%2)(%1)"
+ [(set_attr "type" "store")
+ (set_attr "length" "4")])
+
(define_insn "*movsi_internal1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h")
(match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,0"))]
(define_insn ""
[(set (pc)
- (match_operand:SI 0 "register_operand" "cl"))
+ (match_operand:SI 0 "register_operand" "c,*l"))
(use (label_ref (match_operand 1 "" "")))]
"TARGET_32BIT"
- "b%T0"
+ "@
+ bctr
+ {br|blr}"
[(set_attr "type" "jmpreg")])
(define_insn ""
[(set (pc)
- (match_operand:DI 0 "register_operand" "cl"))
+ (match_operand:DI 0 "register_operand" "c,*l"))
(use (label_ref (match_operand 1 "" "")))]
"TARGET_64BIT"
- "b%T0"
+ "@
+ bctr
+ blr"
[(set_attr "type" "jmpreg")])
(define_insn "nop"