From 51b8fc2c697ae80971166d44acd18a1cb2c0d19b Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Thu, 12 May 1994 19:33:39 -0400 Subject: [PATCH] (function units): Numerous cycle count change. (zero_extendqidi2, extendqidi2, zero_extendhidi2): New patterns. (extendhidi2, zero_extendsidi2, extendsidi2): Likewise. (zero_extendqisi2, zero_extendqihi2, zero_extendhisi2): Use andil/andi instead of rlinm/rlwinm. (zero_extendqihi2): Add condition register variants. (extendqisi2, extendqihi2): Use extsb for PowerPC. (adddi3, subdi3, negdi2, ashrdi3): Emulate only if !TARGET_POWERPC64. (movdf, movdi, movti): New PowerPC64 versions. (load/store with update): New PowerPC64 patterns. From-SVN: r7288 --- gcc/config/rs6000/rs6000.md | 736 ++++++++++++++++++++++++++++-------- 1 file changed, 576 insertions(+), 160 deletions(-) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 69c2a617b03..3796e5eac86 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -45,6 +45,8 @@ ; (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")) @@ -65,26 +67,74 @@ (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) @@ -113,74 +163,73 @@ (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")) @@ -192,28 +241,222 @@ 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) ;; 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" "")))] @@ -226,7 +469,7 @@ "" "@ lbz%U1%X1 %0,%1 - {rlinm|rlwinm} %0,%1,0,0xff" + {andil|andi} %0,%1,0xff" [(set_attr "type" "load,*")]) (define_insn "" @@ -248,6 +491,75 @@ "{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" "")))] @@ -260,9 +572,99 @@ "" "@ 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" "")))] @@ -275,7 +677,7 @@ "" "@ lhz%U1%X1 %0,%1 - {rlinm|rlwinm} %0,%1,0,0xffff" + {andil|andi} %0,%1,0xffff" [(set_attr "type" "load,*")]) (define_insn "" @@ -2101,86 +2503,6 @@ "! 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); }") ;; Floating-point insns, excluding normal data motion. ;; @@ -2862,7 +3184,7 @@ "" " { - if (! TARGET_POWER + if (! TARGET_POWER && ! TARGET_POWERPC64 && short_cint_operand (operands[2], DImode)) FAIL; }") @@ -2871,7 +3193,7 @@ [(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" @@ -2881,7 +3203,7 @@ [(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")]) @@ -2892,7 +3214,7 @@ "" " { - if (! TARGET_POWER + if (! TARGET_POWER && ! TARGET_POWERPC64 && short_cint_operand (operands[1], DImode)) FAIL; }") @@ -2901,7 +3223,7 @@ [(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" @@ -2911,7 +3233,7 @@ [(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")]) @@ -2924,7 +3246,7 @@ (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")]) @@ -3068,17 +3390,22 @@ ;; 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"))) @@ -3488,8 +3815,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"))] - "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) @@ -3526,6 +3853,21 @@ }" [(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,*")]) ;; Next come the multi-word integer load and store and the load and store ;; multiple insns. @@ -3552,8 +3894,8 @@ (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) @@ -3588,6 +3930,24 @@ }" [(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")]) ;; 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 @@ -3596,7 +3956,7 @@ [(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) @@ -3624,7 +3984,7 @@ [(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))" "* { @@ -3670,6 +4030,40 @@ }" [(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")]) (define_expand "load_multiple" [(match_par_dup 3 [(set (match_operand:SI 0 "" "") @@ -3798,6 +4192,29 @@ ;; 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") @@ -5727,7 +6144,6 @@ }" [(set_attr "type" "branch")]) - (define_insn "" [(set (pc) (if_then_else (match_operator 0 "branch_comparison_operator" -- 2.30.2