; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
+; Load/Store Unit -- POWER/2 and pure PowerPC only
+; (POWER and 601 use Integer Unit)
(define_function_unit "lsu" 1 0
(and (eq_attr "type" "load")
(eq_attr "cpu" "rios2,ppc603,ppc604,ppc620"))
(eq_attr "cpu" "rios1,ppc601"))
3 0)
+; Integer Unit (RIOS1, PPC601, PPC603)
+; Trivial operations take one cycle which need not be listed here.
(define_function_unit "iu" 1 0
(and (eq_attr "type" "imul")
(eq_attr "cpu" "rios1"))
- 3 0)
+ 3 3)
(define_function_unit "iu" 1 0
(and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
- 5 0)
+ (eq_attr "cpu" "ppc601,ppc603"))
+ 5 5)
(define_function_unit "iu" 1 0
(and (eq_attr "type" "idiv")
(eq_attr "cpu" "rios1"))
- 19 0)
+ 19 19)
(define_function_unit "iu" 1 0
(and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
- 36 0)
+ (eq_attr "cpu" "ppc601"))
+ 36 36)
+
+(define_function_unit "iu" 1 0
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc603"))
+ 37 36)
+
+; RIOS2 has two integer units: a primary one which can perform all
+; operations and a secondary one which is fed in lock step with the first
+; and can perform "simple" integer operations.
+(define_function_unit "iu2" 2 0
+ (and (eq_attr "type" "integer")
+ (eq_attr "cpu" "rios2"))
+ 1 0
+ [(eq_attr "type" "imul,idiv")])
+
+(define_function_unit "imuldiv" 1 0
+ (and (eq_attr "type" "imul")
+ (eq_attr "cpu" "rios2"))
+ 2 2
+ [(eq_attr "type" "integer")])
+
+(define_function_unit "imuldiv" 1 0
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "rios2"))
+ 13 13
+ [(eq_attr "type" "integer")])
+
+; PPC604 has three integer units: one primary and two secondary.
+(define_function_unit "iu3" 3 0
+ (and (eq_attr "type" "integer")
+ (eq_attr "cpu" "ppc604,ppc620"))
+ 1 0
+ [(eq_attr "type" "imul,idiv")])
+
+(define_function_unit "imuldiv" 1 0
+ (and (eq_attr "type" "imul")
+ (eq_attr "cpu" "ppc604,ppc620"))
+ 4 2
+ [(eq_attr "type" "integer")])
+
+(define_function_unit "imuldiv" 1 0
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc604,ppc620"))
+ 20 19
+ [(eq_attr "type" "integer")])
+; Branch Processing Unit
(define_function_unit "bpu" 1 0
(eq_attr "type" "compare")
4 0)
(eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
4 0)
+; Floating Point Unit (RIOS1, PPC601, PPC603, PPC604).
(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp")
+ (and (eq_attr "type" "fp,dmul")
(eq_attr "cpu" "rios1"))
2 0)
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "fp")
- (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
+ (eq_attr "cpu" "ppc601"))
4 0)
+(define_function_unit "fpu" 1 0
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "ppc603,ppc604,ppc620"))
+ 3 0)
+
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "dmul")
- (eq_attr "cpu" "rios1"))
- 2 0)
+ (eq_attr "cpu" "ppc601"))
+ 5 5)
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "dmul")
- (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
- 5 0)
+ (eq_attr "cpu" "ppc603"))
+ 4 2)
(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "ppc604,ppc620"))
+ 3 0)
+
+(define_function_unit "fpu" 1 0
+ (and (eq_attr "type" "sdiv,ddiv")
(eq_attr "cpu" "rios1"))
- 19 0)
+ 19 19)
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
- 17 0)
+ (eq_attr "cpu" "ppc601"))
+ 17 17)
+
+(define_function_unit "fpu" 1 0
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc603,ppc604,ppc620"))
+ 18 18)
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "rios1"))
- 19 0)
+ (eq_attr "cpu" "ppc601,ppc604,ppc620"))
+ 31 31)
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
- 31 0)
+ (eq_attr "cpu" "ppc603"))
+ 33 33)
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "ssqrt")
- (eq_attr "cpu" "ppc603,ppc604,ppc620"))
- 31 0)
+ (eq_attr "cpu" "ppc604,ppc620"))
+ 31 31)
(define_function_unit "fpu" 1 0
(and (eq_attr "type" "dsqrt")
- (eq_attr "cpu" "ppc603,ppc604,ppc620"))
- 31 0)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "rios2"))
- 1 0
- [(eq_attr "type" "imul,idiv")])
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "rios2"))
- 2 0
- [(eq_attr "type" "integer")])
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "rios2"))
- 13 0
- [(eq_attr "type" "integer")])
+ (eq_attr "cpu" "ppc604,ppc620"))
+ 31 31)
+; RIOS2 has two symmetric FPUs.
(define_function_unit "fpu2" 2 0
(and (eq_attr "type" "fp")
(eq_attr "cpu" "rios2"))
2 0)
(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "rios2"))
- 17 0)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "ddiv")
+ (and (eq_attr "type" "sdiv,ddiv")
(eq_attr "cpu" "rios2"))
- 17 0)
+ 17 17)
(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "ssqrt")
+ (and (eq_attr "type" "ssqrt,dsqrt")
(eq_attr "cpu" "rios2"))
- 26 0)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "dsqrt")
- (eq_attr "cpu" "rios2"))
- 26 0)
+ 26 26)
\f
;; Start with fixed-point load and store insns. Here we put only the more
;; complex forms. Basic data transfer is done later.
+(define_expand "zero_extendqidi2"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "")
+ (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")))]
+ "TARGET_POWERPC64"
+ "")
+
+(define_insn ""
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+ (zero_extend:DI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
+ "TARGET_POWERPC64"
+ "@
+ lbz%U1%X1 %0,%1
+ andi %0,%1,0xff"
+ [(set_attr "type" "load,*")])
+
+(define_insn ""
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+ (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 2 "=r"))]
+ ""
+ "andi. %2,%1,0xff"
+ [(set_attr "type" "compare")])
+
+(define_insn ""
+ [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+ (compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (zero_extend:DI (match_dup 1)))]
+ ""
+ "andi. %0,%1,0xff"
+ [(set_attr "type" "compare")])
+
+(define_expand "extendqidi2"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "")
+ (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")))]
+ "TARGET_POWERPC64"
+ "")
+
+(define_insn ""
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+ (sign_extend:DI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
+ "TARGET_POWERPC64"
+ "@
+ lba%U1%X1 %0,%1
+ extsb %0,%1"
+ [(set_attr "type" "load,*")])
+
+(define_insn ""
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+ (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 2 "=r"))]
+ "TARGET_POWERPC64"
+ "extsb. %2,%1"
+ [(set_attr "type" "compare")])
+
+(define_insn ""
+ [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+ (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (sign_extend:DI (match_dup 1)))]
+ "TARGET_POWERPC64"
+ "extsb. %0,%1"
+ [(set_attr "type" "compare")])
+
+(define_expand "zero_extendhidi2"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "")
+ (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))]
+ "TARGET_POWERPC64"
+ "")
+
+(define_insn ""
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+ (zero_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
+ "TARGET_POWERPC64"
+ "@
+ lhz%U1%X1 %0,%1
+ andi %0,%1,0xffff"
+ [(set_attr "type" "load,*")])
+
+(define_insn ""
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+ (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 2 "=r"))]
+ "TARGET_POWERPC64"
+ "andi. %2,%1,0xffff"
+ [(set_attr "type" "compare")])
+
+(define_insn ""
+ [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+ (compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (zero_extend:DI (match_dup 1)))]
+ "TARGET_POWERPC64"
+ "andi. %0,%1,0xffff"
+ [(set_attr "type" "compare")])
+
+(define_expand "extendhidi2"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "")
+ (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))]
+ "TARGET_POWERPC64"
+ "")
+
+(define_insn ""
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+ (sign_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
+ "TARGET_POWERPC64"
+ "@
+ lha%U1%X1 %0,%1
+ extsh %0,%1"
+ [(set_attr "type" "load,*")])
+
+(define_insn ""
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+ (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 2 "=r"))]
+ "TARGET_POWERPC64"
+ "extsh. %2,%1"
+ [(set_attr "type" "compare")])
+
+(define_insn ""
+ [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+ (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (sign_extend:DI (match_dup 1)))]
+ "TARGET_POWERPC64"
+ "extsh. %0,%1"
+ [(set_attr "type" "compare")])
+
+(define_expand "zero_extendsidi2"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "")
+ (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))]
+ "TARGET_POWERPC64"
+ "")
+
+(define_insn ""
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+ (zero_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "m,r")))]
+ "TARGET_POWERPC64"
+ "@
+ lwz%U1%X1 %0,%1
+ rldicl %0,%1,0,32"
+ [(set_attr "type" "load,*")])
+
+(define_insn ""
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+ (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 2 "=r"))]
+ "TARGET_POWERPC64"
+ "rldicl. %2,%1,0,32"
+ [(set_attr "type" "compare")])
+
+(define_insn ""
+ [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+ (compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (zero_extend:DI (match_dup 1)))]
+ "TARGET_POWERPC64"
+ "rldicl. %0,%1,0,32"
+ [(set_attr "type" "compare")])
+
+(define_expand "extendsidi2"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))]
+ "TARGET_POWERPC64"
+ "")
+
+(define_insn ""
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+ (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "m,r")))]
+ "TARGET_POWERPC64"
+ "@
+ lwa%U1%X1 %0,%1
+ extsw %0,%1"
+ [(set_attr "type" "load,*")])
+
+(define_insn ""
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+ (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 2 "=r"))]
+ "TARGET_POWERPC64"
+ "extsw. %2,%1"
+ [(set_attr "type" "compare")])
+
+(define_insn ""
+ [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+ (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (sign_extend:DI (match_dup 1)))]
+ "TARGET_POWERPC64"
+ "extsw. %0,%1"
+ [(set_attr "type" "compare")])
+
(define_expand "zero_extendqisi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")))]
""
"@
lbz%U1%X1 %0,%1
- {rlinm|rlwinm} %0,%1,0,0xff"
+ {andil|andi} %0,%1,0xff"
[(set_attr "type" "load,*")])
(define_insn ""
"{andil.|andi.} %0,%1,0xff"
[(set_attr "type" "compare")])
+(define_expand "extendqisi2"
+ [(use (match_operand:SI 0 "gpc_reg_operand" ""))
+ (use (match_operand:QI 1 "gpc_reg_operand" ""))]
+ ""
+ "
+{
+ if (TARGET_POWERPC)
+ emit_insn (gen_extendqisi2_ppc (operands[0], operands[1]));
+ else if (TARGET_POWER)
+ emit_insn (gen_extendqisi2_power (operands[0], operands[1]));
+ else
+ emit_insn (gen_extendqisi2_no_power (operands[0], operands[1]));
+ DONE;
+}")
+
+(define_insn "extendqisi2_ppc"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+ (sign_extend:SI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
+ "TARGET_POWERPC"
+ "@
+ lba%U1%X1 %0,%1
+ extsb %0,%1"
+ [(set_attr "type" "load,*")])
+
+(define_insn ""
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+ (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (clobber (match_scratch:SI 2 "=r"))]
+ "TARGET_POWERPC"
+ "extsb. %2,%1"
+ [(set_attr "type" "compare")])
+
+(define_insn ""
+ [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+ (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (sign_extend:SI (match_dup 1)))]
+ "TARGET_POWERPC"
+ "extsb. %0,%1"
+ [(set_attr "type" "compare")])
+
+(define_expand "extendqisi2_power"
+ [(parallel [(set (match_dup 2)
+ (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
+ (const_int 24)))
+ (clobber (scratch:SI))])
+ (parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
+ (ashiftrt:SI (match_dup 2)
+ (const_int 24)))
+ (clobber (scratch:SI))])]
+ "TARGET_POWER"
+ "
+{ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = gen_reg_rtx (SImode); }")
+
+(define_expand "extendqisi2_no_power"
+ [(set (match_dup 2)
+ (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
+ (const_int 24)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "")
+ (ashiftrt:SI (match_dup 2)
+ (const_int 24)))]
+ "! TARGET_POWER && ! TARGET_POWERPC"
+ "
+{ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = gen_reg_rtx (SImode); }")
+
(define_expand "zero_extendqihi2"
[(set (match_operand:HI 0 "gpc_reg_operand" "")
(zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")))]
""
"@
lbz%U1%X1 %0,%1
- {rlinm|rlwinm} %0,%1,0,0xff"
+ {andil|andi} %0,%1,0xff"
+ [(set_attr "type" "load,*")])
+
+(define_insn ""
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+ (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (clobber (match_scratch:HI 2 "=r"))]
+ ""
+ "{andil.|andi.} %2,%1,0xff"
+ [(set_attr "type" "compare")])
+
+(define_insn ""
+ [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+ (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:HI 0 "gpc_reg_operand" "=r")
+ (zero_extend:HI (match_dup 1)))]
+ ""
+ "{andil.|andi.} %0,%1,0xff"
+ [(set_attr "type" "compare")])
+
+(define_expand "extendqihi2"
+ [(use (match_operand:HI 0 "gpc_reg_operand" ""))
+ (use (match_operand:QI 1 "gpc_reg_operand" ""))]
+ ""
+ "
+{
+ if (TARGET_POWERPC)
+ emit_insn (gen_extendqihi2_ppc (operands[0], operands[1]));
+ else if (TARGET_POWER)
+ emit_insn (gen_extendqihi2_power (operands[0], operands[1]));
+ else
+ emit_insn (gen_extendqihi2_no_power (operands[0], operands[1]));
+ DONE;
+}")
+
+(define_insn "extendqihi2_ppc"
+ [(set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
+ (sign_extend:HI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
+ "TARGET_POWERPC"
+ "@
+ lba%U1%X1 %0,%1
+ extsb %0,%1"
[(set_attr "type" "load,*")])
+(define_insn ""
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+ (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (clobber (match_scratch:HI 2 "=r"))]
+ "TARGET_POWERPC"
+ "extsb. %2,%1"
+ [(set_attr "type" "compare")])
+
+(define_insn ""
+ [(set (match_operand:CC 2 "cc_reg_operand" "=x")
+ (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r"))
+ (const_int 0)))
+ (set (match_operand:HI 0 "gpc_reg_operand" "=r")
+ (sign_extend:HI (match_dup 1)))]
+ "TARGET_POWERPC"
+ "extsb. %0,%1"
+ [(set_attr "type" "compare")])
+
+(define_expand "extendqihi2_power"
+ [(parallel [(set (match_dup 2)
+ (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
+ (const_int 24)))
+ (clobber (scratch:SI))])
+ (parallel [(set (match_operand:HI 0 "gpc_reg_operand" "")
+ (ashiftrt:SI (match_dup 2)
+ (const_int 24)))
+ (clobber (scratch:SI))])]
+ "TARGET_POWER"
+ "
+{ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = gen_reg_rtx (SImode); }")
+
+(define_expand "extendqihi2_no_power"
+ [(set (match_dup 2)
+ (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
+ (const_int 24)))
+ (set (match_operand:HI 0 "gpc_reg_operand" "")
+ (ashiftrt:SI (match_dup 2)
+ (const_int 24)))]
+ "! TARGET_POWER && ! TARGET_POWERPC"
+ "
+{ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = gen_reg_rtx (SImode); }")
+
(define_expand "zero_extendhisi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
""
"@
lhz%U1%X1 %0,%1
- {rlinm|rlwinm} %0,%1,0,0xffff"
+ {andil|andi} %0,%1,0xffff"
[(set_attr "type" "load,*")])
(define_insn ""
"! TARGET_POWER"
"sraw%I2. %0,%1,%2"
[(set_attr "type" "delayed_compare")])
-
-(define_expand "extendqisi2"
- [(use (match_operand:SI 0 "gpc_reg_operand" ""))
- (use (match_operand:QI 1 "gpc_reg_operand" ""))]
- ""
- "
-{
- if (TARGET_POWER)
- emit_insn (gen_extendqisi2_power (operands[0], operands[1]));
- else
- emit_insn (gen_extendqisi2_no_power (operands[0], operands[1]));
- DONE;
-}")
-
-(define_expand "extendqisi2_power"
- [(parallel [(set (match_dup 2)
- (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
- (const_int 24)))
- (clobber (scratch:SI))])
- (parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (ashiftrt:SI (match_dup 2)
- (const_int 24)))
- (clobber (scratch:SI))])]
- "TARGET_POWER"
- "
-{ operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_reg_rtx (SImode); }")
-
-(define_expand "extendqisi2_no_power"
- [(set (match_dup 2)
- (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
- (const_int 24)))
- (set (match_operand:SI 0 "gpc_reg_operand" "")
- (ashiftrt:SI (match_dup 2)
- (const_int 24)))]
- "! TARGET_POWER"
- "
-{ operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_reg_rtx (SImode); }")
-
-(define_expand "extendqihi2"
- [(use (match_operand:HI 0 "gpc_reg_operand" ""))
- (use (match_operand:QI 1 "gpc_reg_operand" ""))]
- ""
- "
-{
- if (TARGET_POWER)
- emit_insn (gen_extendqihi2_power (operands[0], operands[1]));
- else
- emit_insn (gen_extendqihi2_no_power (operands[0], operands[1]));
- DONE;
-}")
-
-(define_expand "extendqihi2_power"
- [(parallel [(set (match_dup 2)
- (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
- (const_int 24)))
- (clobber (scratch:SI))])
- (parallel [(set (match_operand:HI 0 "gpc_reg_operand" "")
- (ashiftrt:SI (match_dup 2)
- (const_int 24)))
- (clobber (scratch:SI))])]
- "TARGET_POWER"
- "
-{ operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_reg_rtx (SImode); }")
-
-(define_expand "extendqihi2_no_power"
- [(set (match_dup 2)
- (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
- (const_int 24)))
- (set (match_operand:HI 0 "gpc_reg_operand" "")
- (ashiftrt:SI (match_dup 2)
- (const_int 24)))]
- "! TARGET_POWER"
- "
-{ operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_reg_rtx (SImode); }")
\f
;; Floating-point insns, excluding normal data motion.
;;
""
"
{
- if (! TARGET_POWER
+ if (! TARGET_POWER && ! TARGET_POWERPC64
&& short_cint_operand (operands[2], DImode))
FAIL;
}")
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
(match_operand:DI 2 "reg_or_short_operand" "r,I")))]
- "TARGET_POWER"
+ "TARGET_POWER && ! TARGET_POWERPC64"
"@
{a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2
{ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
(match_operand:DI 2 "gpc_reg_operand" "r")))]
- "! TARGET_POWER"
+ "! TARGET_POWER && ! TARGET_POWERPC64"
"addc %L0,%L1,%L2\;adde %0,%1,%2"
[(set_attr "length" "8")])
""
"
{
- if (! TARGET_POWER
+ if (! TARGET_POWER && ! TARGET_POWERPC64
&& short_cint_operand (operands[1], DImode))
FAIL;
}")
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I")
(match_operand:DI 2 "gpc_reg_operand" "r,r")))]
- "TARGET_POWER"
+ "TARGET_POWER && ! TARGET_POWERPC64"
"@
{sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1
{sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:DI 2 "gpc_reg_operand" "r")))]
- "! TARGET_POWER"
+ "! TARGET_POWER && ! TARGET_POWERPC64"
"subfc %L0,%L2,%L1\;subfe %0,%2,%1"
[(set_attr "length" "8")])
(define_insn ""
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
- ""
+ "! TARGET_POWERPC64"
"{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1"
[(set_attr "length" "8")])
;; just handle shifts by constants.
(define_expand "ashrdi3"
- [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=")
- (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
- (match_operand:SI 2 "general_operand" "")))
- (clobber (match_scratch:SI 3 ""))])]
- "TARGET_POWER"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "")
+ (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
+ (match_operand:SI 2 "reg_or_cint_operand" "")))]
+ ""
"
-{ if (GET_CODE (operands[2]) != CONST_INT)
+{
+ if (TARGET_POWER && GET_CODE (operands[2]) != CONST_INT)
+ {
+ emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+ else if (! TARGET_POWERPC64)
FAIL;
}")
-(define_insn ""
+(define_insn "ashrdi3_power"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "M,i")))
(define_insn ""
[(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m")
(match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
- "register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode)"
+ "! TARGET_POWERPC64 && (register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode))"
"*
{
switch (which_alternative)
}"
[(set_attr "type" "*,load,*,*,fp,fpload,*")
(set_attr "length" "8,8,8,8,*,*,*")])
+
+(define_insn ""
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,f,f,m")
+ (match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
+ "TARGET_POWERPC64 && (register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode))"
+ "@
+ mr %0,%1
+ ld%U1%X1 %0,%1
+ sd%U0%X0 %1,%0
+ #
+ fmr %0,%1
+ lfd %0,%1
+ stfd%U0%X0 %1,%0"
+ [(set_attr "type" "*,load,*,*,fp,fpload,*")])
\f
;; Next come the multi-word integer load and store and the load and store
;; multiple insns.
(define_insn ""
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m")
(match_operand:DI 1 "input_operand" "r,m,r,f,m,f"))]
- "gpc_reg_operand (operands[0], DImode)
- || gpc_reg_operand (operands[1], DImode)"
+ "! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode)
+ || gpc_reg_operand (operands[1], DImode))"
"*
{
switch (which_alternative)
}"
[(set_attr "type" "*,load,*,fp,fpload,*")
(set_attr "length" "8,8,8,*,*,*")])
+
+(define_insn ""
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,f,f,m,r,*h")
+ (match_operand:DI 1 "input_operand" "r,m,r,I,J,f,m,f,*h,r"))]
+ "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode)
+ || gpc_reg_operand (operands[1], DImode))"
+ "@
+ mr %0,%1
+ ld%U1%X1 %0,%1
+ sd%U0%X0 %1,%0
+ li %0,%1
+ lis %0,%u1
+ fmr %0,%1
+ lfd%U1%X1 %0,%1
+ stfd%U0%X0 %1,%0
+ mf%1 %0
+ mt%0 %1"
+ [(set_attr "type" "*,load,*,*,*,fp,fpload,*,*,mtjmpr")])
\f
;; TImode is similar, except that we usually want to compute the address into
;; a register and use lsi/stsi (the exception is during reload). MQ is also
[(parallel [(set (match_operand:TI 0 "general_operand" "")
(match_operand:TI 1 "general_operand" ""))
(clobber (scratch:SI))])]
- "TARGET_POWER"
+ "TARGET_POWER || TARGET_POWERPC64"
"
{
if (GET_CODE (operands[0]) == MEM)
[(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
(match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
(clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
- "TARGET_POWER && (gpc_reg_operand (operands[0], TImode)
+ "TARGET_POWER && ! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
|| gpc_reg_operand (operands[1], TImode))"
"*
{
}"
[(set_attr "type" "*,load,load,*,*")
(set_attr "length" "*,16,16,*,16")])
+
+(define_insn ""
+ [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
+ (match_operand:TI 1 "input_operand" "r,m,r"))]
+ "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
+ || gpc_reg_operand (operands[1], TImode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ /* We normally copy the low-numbered register first. However, if
+ the first register operand 0 is the same as the second register of
+ operand 1, we must copy in the opposite order. */
+ if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ return \"mr %L0,%L1\;mr %0,%1\";
+ else
+ return \"mr %0,%1\;mr %L0,%L1\";
+ case 1:
+ /* If the low-address word is used in the address, we must load it
+ last. Otherwise, load it first. Note that we cannot have
+ auto-increment in that case since the address register is known to be
+ dead. */
+ if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
+ operands [1], 0))
+ return \"ld %L0,%L1\;ld %0,%1\";
+ else
+ return \"ld%U1 %0,%1\;ld %L0,%L1\";
+ case 2:
+ return \"std%U0 %1,%0\;std %L1,%L0\";
+ }
+}"
+ [(set_attr "type" "*,load,*")
+ (set_attr "length" "8,8,8")])
\f
(define_expand "load_multiple"
[(match_par_dup 3 [(set (match_operand:SI 0 "" "")
;; tie and these are the pair most likely to be tieable (and the ones
;; that will benefit the most).
+(define_insn ""
+ [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
+ (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
+ (match_operand:DI 2 "reg_or_short_operand" "r,I"))))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
+ (plus:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_POWERPC64"
+ "@
+ ldux %3,%0,%2
+ ldu %3,%2(%0)"
+ [(set_attr "type" "load")])
+
+(define_insn ""
+ [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
+ (match_operand:DI 2 "reg_or_short_operand" "r,I")))
+ (match_operand:DI 3 "gpc_reg_operand" "r,r"))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
+ (plus:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_POWERPC64"
+ "@
+ stdux %3,%0,%2
+ stdu %3,%2(%0)")
+
(define_insn ""
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
}"
[(set_attr "type" "branch")])
-
(define_insn ""
[(set (pc)
(if_then_else (match_operator 0 "branch_comparison_operator"