diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 248 |
1 files changed, 159 insertions, 89 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index b61b77ec431..e9ae2963da5 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -3615,7 +3615,7 @@ #" [(set_attr "type" "compare") (set_attr "length" "4,8")]) - + (define_split [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") (compare:CC @@ -3635,7 +3635,7 @@ (compare:CC (match_dup 0) (const_int 0)))] "") - + ;; Rotate and shift insns, in all their variants. These support shifts, ;; field inserts and extracts, and various combinations thereof. (define_expand "insv" @@ -8349,8 +8349,8 @@ "") (define_insn "*movcc_internal1" - [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m") - (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))] + [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,cl,q,r,r,m") + (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,r,r,h,m,r"))] "register_operand (operands[0], CCmode) || register_operand (operands[1], CCmode)" "@ @@ -8360,10 +8360,13 @@ mfcr %0 mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000 mr %0,%1 + mt%0 %1 + mt%0 %1 + mf%1 %0 {l%U1%X1|lwz%U1%X1} %0,%1 {st%U0%U1|stw%U0%U1} %1,%0" - [(set_attr "type" "cr_logical,cr_logical,cr_logical,cr_logical,cr_logical,*,load,store") - (set_attr "length" "*,*,12,*,8,*,*,*")]) + [(set_attr "type" "cr_logical,cr_logical,cr_logical,cr_logical,cr_logical,*,*,mtjmpr,*,load,store") + (set_attr "length" "4,4,12,4,8,4,4,4,4,4,4")]) ;; For floating-point, we normally deal with the floating-point registers ;; unless -msoft-float is used. The sole exception is that parameter passing @@ -8402,8 +8405,8 @@ }") (define_insn "*movsf_hardfloat" - [(set (match_operand:SF 0 "nonimmediate_operand" "=!r,!r,m,f,f,m,!r,!r") - (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,G,Fn"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=!r,!r,m,f,f,m,!cl,!q,!r,!r,!r") + (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,r,r,h,G,Fn"))] "(gpc_reg_operand (operands[0], SFmode) || gpc_reg_operand (operands[1], SFmode)) && (TARGET_HARD_FLOAT && TARGET_FPRS)" @@ -8414,19 +8417,25 @@ fmr %0,%1 lfs%U1%X1 %0,%1 stfs%U0%X0 %1,%0 + mt%0 %1 + mt%0 %1 + mf%1 %0 # #" - [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*") - (set_attr "length" "4,4,4,4,4,4,4,8")]) + [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,mtjmpr,*,*,*") + (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8")]) (define_insn "*movsf_softfloat" - [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r") - (match_operand:SF 1 "input_operand" "r,m,r,I,L,R,G,Fn"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=r,cl,q,r,r,m,r,r,r,r,r") + (match_operand:SF 1 "input_operand" "r,r,r,h,m,r,I,L,R,G,Fn"))] "(gpc_reg_operand (operands[0], SFmode) || gpc_reg_operand (operands[1], SFmode)) && (TARGET_SOFT_FLOAT || !TARGET_FPRS)" "@ mr %0,%1 + mt%0 %1 + mt%0 %1 + mf%1 %0 {l%U1%X1|lwz%U1%X1} %0,%1 {st%U0%X0|stw%U0%X0} %1,%0 {lil|li} %0,%1 @@ -8434,8 +8443,8 @@ {cal|la} %0,%a1 # #" - [(set_attr "type" "*,load,store,*,*,*,*,*") - (set_attr "length" "4,4,4,4,4,4,4,8")]) + [(set_attr "type" "*,mtjmpr,*,*,load,store,*,*,*,*,*") + (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8")]) (define_expand "movdf" @@ -8518,10 +8527,10 @@ operands[2] = gen_lowpart (DImode, operands[0]); /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ #if HOST_BITS_PER_WIDE_INT >= 64 - val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 | - ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); + val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 + | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); - operands[3] = immed_double_const (val, -(val < 0), DImode); + operands[3] = gen_int_mode (val, DImode); #else operands[3] = immed_double_const (l[1 - endian], l[endian], DImode); #endif @@ -8534,8 +8543,8 @@ ;; The "??" is a kludge until we can figure out a more reasonable way ;; of handling these non-offsettable values. (define_insn "*movdf_hardfloat32" - [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,!r,!r,!r,f,f,m") - (match_operand:DF 1 "input_operand" "r,m,r,G,H,F,f,m,f"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!r,!r,!r") + (match_operand:DF 1 "input_operand" "r,m,r,f,m,f,G,H,F"))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" @@ -8612,19 +8621,19 @@ return \"\"; } case 3: + return \"fmr %0,%1\"; case 4: + return \"lfd%U1%X1 %0,%1\"; case 5: - return \"#\"; + return \"stfd%U0%X0 %1,%0\"; case 6: - return \"fmr %0,%1\"; case 7: - return \"lfd%U1%X1 %0,%1\"; case 8: - return \"stfd%U0%X0 %1,%0\"; + return \"#\"; } }" - [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore") - (set_attr "length" "8,16,16,8,12,16,*,*,*")]) + [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*") + (set_attr "length" "8,16,16,4,4,4,8,12,16")]) (define_insn "*movdf_softfloat32" [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r") @@ -8668,8 +8677,8 @@ (set_attr "length" "8,8,8,8,12,16")]) (define_insn "*movdf_hardfloat64" - [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,!r,!r,!r,f,f,m") - (match_operand:DF 1 "input_operand" "r,m,r,G,H,F,f,m,f"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!cl,!r,!r,!r,!r") + (match_operand:DF 1 "input_operand" "r,m,r,f,m,f,r,h,G,H,F"))] "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" @@ -8677,30 +8686,34 @@ mr %0,%1 ld%U1%X1 %0,%1 std%U0%X0 %1,%0 - # - # - # fmr %0,%1 lfd%U1%X1 %0,%1 - stfd%U0%X0 %1,%0" - [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore") - (set_attr "length" "4,4,4,8,12,16,4,4,4")]) + stfd%U0%X0 %1,%0 + mt%0 %1 + mf%1 %0 + # + # + #" + [(set_attr "type" "*,load,store,fp,fpload,fpstore,mtjmpr,*,*,*,*") + (set_attr "length" "4,4,4,4,4,4,4,4,8,12,16")]) (define_insn "*movdf_softfloat64" - [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r") - (match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r") + (match_operand:DF 1 "input_operand" "r,r,h,m,r,G,H,F"))] "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS) && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" "@ mr %0,%1 + mt%0 %1 + mf%1 %0 ld%U1%X1 %0,%1 std%U0%X0 %1,%0 # # #" - [(set_attr "type" "*,load,store,*,*,*") - (set_attr "length" "*,*,*,8,12,16")]) + [(set_attr "type" "*,*,*,load,store,*,*,*") + (set_attr "length" "4,4,4,4,4,8,12,16")]) (define_expand "movtf" [(set (match_operand:TF 0 "general_operand" "") @@ -8731,9 +8744,9 @@ else return \"fmr %0,%1\;fmr %L0,%L1\"; case 1: - return \"lfd %0,%1\;lfd %L0,%L1\"; + return \"lfd %0,%1\;lfd %L0,%Y1\"; case 2: - return \"stfd %1,%0\;stfd %L1,%L0\"; + return \"stfd %1,%0\;stfd %L1,%Y0\"; case 3: case 4: case 5: @@ -8745,45 +8758,100 @@ (define_split [(set (match_operand:TF 0 "gpc_reg_operand" "") - (match_operand:TF 1 "const_double_operand" ""))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS - && TARGET_LONG_DOUBLE_128" - [(set (match_dup 3) (match_dup 1)) - (set (match_dup 0) - (float_extend:TF (match_dup 3)))] + (match_operand:TF 1 "easy_fp_constant" ""))] + "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) + && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_POWERPC64 + && TARGET_LONG_DOUBLE_128 && reload_completed + && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) + || (GET_CODE (operands[0]) == SUBREG + && GET_CODE (SUBREG_REG (operands[0])) == REG + && REGNO (SUBREG_REG (operands[0])) <= 31))" + [(set (match_dup 2) (match_dup 6)) + (set (match_dup 3) (match_dup 7)) + (set (match_dup 4) (match_dup 8)) + (set (match_dup 5) (match_dup 9))] " { - operands[2] = operand_subword (operands[1], 0, 0, DFmode); - operands[3] = gen_reg_rtx (DFmode); + long l[4]; + REAL_VALUE_TYPE rv; + + REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); + REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l); + + operands[2] = operand_subword (operands[0], 0, 0, TFmode); + operands[3] = operand_subword (operands[0], 1, 0, TFmode); + operands[4] = operand_subword (operands[0], 2, 0, TFmode); + operands[5] = operand_subword (operands[0], 3, 0, TFmode); + operands[6] = gen_int_mode (l[0], SImode); + operands[7] = gen_int_mode (l[1], SImode); + operands[8] = gen_int_mode (l[2], SImode); + operands[9] = gen_int_mode (l[3], SImode); }") -(define_insn_and_split "extenddftf2" +(define_split + [(set (match_operand:TF 0 "gpc_reg_operand" "") + (match_operand:TF 1 "easy_fp_constant" ""))] + "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 + && TARGET_LONG_DOUBLE_128 && reload_completed + && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) + || (GET_CODE (operands[0]) == SUBREG + && GET_CODE (SUBREG_REG (operands[0])) == REG + && REGNO (SUBREG_REG (operands[0])) <= 31))" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] + " +{ + long l[4]; + REAL_VALUE_TYPE rv; + HOST_WIDE_INT val; + + REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); + REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l); + + operands[2] = gen_lowpart (DImode, operands[0]); + operands[3] = gen_highpart (DImode, operands[0]); +#if HOST_BITS_PER_WIDE_INT >= 64 + val = ((HOST_WIDE_INT)(unsigned long)l[0] << 32 + | ((HOST_WIDE_INT)(unsigned long)l[1])); + operands[4] = gen_int_mode (val, DImode); + + val = ((HOST_WIDE_INT)(unsigned long)l[2] << 32 + | ((HOST_WIDE_INT)(unsigned long)l[3])); + operands[5] = gen_int_mode (val, DImode); +#else + operands[4] = immed_double_const (l[1], l[0], DImode); + operands[5] = immed_double_const (l[3], l[2], DImode); +#endif +}") + +(define_insn "extenddftf2" [(set (match_operand:TF 0 "gpc_reg_operand" "=f") (float_extend:TF (match_operand:DF 1 "gpc_reg_operand" "f")))] "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" - "#" - "" - [(set (match_dup 2) (match_dup 3))] - " + "* { - operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0] + 1)); - operands[3] = CONST0_RTX (DFmode); -}") + if (REGNO (operands[0]) == REGNO (operands[1])) + return \"fsub %L0,%L0,%L0\"; + else + return \"fmr %0,%1\;fsub %L0,%L0,%L0\"; +}" + [(set_attr "type" "fp")]) -(define_insn_and_split "extendsftf2" +(define_insn "extendsftf2" [(set (match_operand:TF 0 "gpc_reg_operand" "=f") (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "f")))] "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" - "#" - "" - [(set (match_dup 2) (match_dup 3))] - " + "* { - operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0] + 1)); - operands[3] = CONST0_RTX (SFmode); -}") + if (REGNO (operands[0]) == REGNO (operands[1])) + return \"fsub %L0,%L0,%L0\"; + else + return \"fmr %0,%1\;fsub %L0,%L0,%L0\"; +}" + [(set_attr "type" "fp")]) (define_insn "trunctfdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") @@ -8817,8 +8885,8 @@ "#" "&& reload_completed" [(set (match_dup 2) - (float:DF (match_operand:DI 1 "gpc_reg_operand" ""))) - (set (match_operand:TF 0 "gpc_reg_operand" "") + (float:DF (match_dup 1))) + (set (match_dup 0) (float_extend:TF (match_dup 2)))] "") @@ -8831,34 +8899,36 @@ "#" "&& reload_completed" [(set (match_dup 2) - (float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) - (set (match_operand:TF 0 "gpc_reg_operand" "") + (float:DF (match_dup 1))) + (set (match_dup 0) (float_extend:TF (match_dup 2)))] "") (define_insn_and_split "fix_trunctfdi2" [(set (match_operand:DI 0 "gpc_reg_operand" "=*f") - (fix:DI (match_operand:TF 1 "gpc_reg_operand" "f")))] + (fix:DI (match_operand:TF 1 "gpc_reg_operand" "f"))) + (clobber (match_scratch:DF 2 "=f"))] "DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" "#" "&& reload_completed" [(set (match_dup 2) - (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" ""))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (fix:SI (match_dup 2)))] + (float_truncate:DF (match_dup 1))) + (set (match_dup 0) + (fix:DI (match_dup 2)))] "") (define_insn_and_split "fix_trunctfsi2" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f")))] + (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f"))) + (clobber (match_scratch:DF 2 "=f"))] "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" "#" "&& reload_completed" [(set (match_dup 2) - (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" ""))) - (set (match_operand:SI 0 "gpc_reg_operand" "") + (float_truncate:DF (match_dup 1))) + (set (match_dup 0) (fix:SI (match_dup 2)))] "") @@ -8962,7 +9032,7 @@ } }" [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*") - (set_attr "length" "8,8,8,*,*,*,8,12,8,12,16")]) + (set_attr "length" "8,8,8,4,4,4,8,12,8,12,16")]) (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") @@ -9177,7 +9247,7 @@ } }" [(set_attr "type" "store,store,*,load,load") - (set_attr "length" "*,16,16,*,16")]) + (set_attr "length" "4,16,16,4,16")]) (define_insn "*movti_string" [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r") @@ -10219,7 +10289,7 @@ (define_insn "load_toc_v4_PIC_2" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") (minus:SI (match_operand:SI 2 "immediate_operand" "s") (match_operand:SI 3 "immediate_operand" "s")))))] "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" @@ -14089,7 +14159,7 @@ return \"bdz $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrsi_internal2" [(set (pc) @@ -14113,7 +14183,7 @@ return \"{bdn|bdnz} $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrdi_internal1" [(set (pc) @@ -14137,7 +14207,7 @@ return \"bdz $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrdi_internal2" [(set (pc) @@ -14161,7 +14231,7 @@ return \"{bdn|bdnz} $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) ;; Similar, but we can use GE since we have a REG_NONNEG. @@ -14187,7 +14257,7 @@ return \"bdz $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrsi_internal4" [(set (pc) @@ -14211,7 +14281,7 @@ return \"{bdn|bdnz} $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrdi_internal3" [(set (pc) @@ -14235,7 +14305,7 @@ return \"bdz $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrdi_internal4" [(set (pc) @@ -14259,7 +14329,7 @@ return \"{bdn|bdnz} $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) ;; Similar but use EQ @@ -14285,7 +14355,7 @@ return \"{bdn|bdnz} $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrsi_internal6" [(set (pc) @@ -14309,7 +14379,7 @@ return \"bdz $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrdi_internal5" [(set (pc) @@ -14333,7 +14403,7 @@ return \"{bdn|bdnz} $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrdi_internal6" [(set (pc) @@ -14357,7 +14427,7 @@ return \"bdz $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) ;; Now the splitters if we could not allocate the CTR register |