diff options
Diffstat (limited to 'gcc-4.9/gcc/config/rs6000/rs6000.md')
-rw-r--r-- | gcc-4.9/gcc/config/rs6000/rs6000.md | 88 |
1 files changed, 53 insertions, 35 deletions
diff --git a/gcc-4.9/gcc/config/rs6000/rs6000.md b/gcc-4.9/gcc/config/rs6000/rs6000.md index d078491e1..f77754aa1 100644 --- a/gcc-4.9/gcc/config/rs6000/rs6000.md +++ b/gcc-4.9/gcc/config/rs6000/rs6000.md @@ -137,6 +137,7 @@ UNSPEC_UNPACK_128BIT UNSPEC_PACK_128BIT UNSPEC_LSQ + UNSPEC_FUSION_GPR ]) ;; @@ -328,8 +329,25 @@ (define_mode_attr f32_sv [(SF "stxsspx %x1,%y0") (SD "stxsiwzx %x1,%y0")]) ; Definitions for 32-bit fpr direct move +; At present, the decimal modes are not allowed in the traditional altivec +; registers, so restrict the constraints to just the traditional FPRs. (define_mode_attr f32_dm [(SF "wn") (SD "wh")]) +; Definitions for 32-bit VSX +(define_mode_attr f32_vsx [(SF "ww") (SD "wn")]) + +; Definitions for 32-bit use of altivec registers +(define_mode_attr f32_av [(SF "wu") (SD "wn")]) + +; Definitions for 64-bit VSX +(define_mode_attr f64_vsx [(DF "ws") (DD "wn")]) + +; Definitions for 64-bit direct move +(define_mode_attr f64_dm [(DF "wk") (DD "wh")]) + +; Definitions for 64-bit use of altivec registers +(define_mode_attr f64_av [(DF "wv") (DD "wn")]) + ; These modes do not fit in integer registers in 32-bit mode. ; but on e500v2, the gpr are 64 bit registers (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD]) @@ -435,7 +453,7 @@ ;; either. ;; Mode attribute for boolean operation register constraints for output -(define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v") +(define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v") (PTI "&r,r,r") (V16QI "wa,v,&?r,?r,?r") (V8HI "wa,v,&?r,?r,?r") @@ -446,7 +464,7 @@ (V1TI "wa,v,&?r,?r,?r")]) ;; Mode attribute for boolean operation register constraints for operand1 -(define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v") +(define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v") (PTI "r,0,r") (V16QI "wa,v,r,0,r") (V8HI "wa,v,r,0,r") @@ -457,7 +475,7 @@ (V1TI "wa,v,r,0,r")]) ;; Mode attribute for boolean operation register constraints for operand2 -(define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v") +(define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v") (PTI "r,r,0") (V16QI "wa,v,r,r,0") (V8HI "wa,v,r,r,0") @@ -470,7 +488,7 @@ ;; Mode attribute for boolean operation register constraints for operand1 ;; for one_cmpl. To simplify things, we repeat the constraint where 0 ;; is used for operand1 or operand2 -(define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v") +(define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v") (PTI "r,0,0") (V16QI "wa,v,r,0,0") (V8HI "wa,v,r,0,0") @@ -8582,8 +8600,8 @@ [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") (match_operator:BOOL_128 3 "boolean_operator" [(not:BOOL_128 - (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP1>")) - (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP2>")]))] + (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")) + (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))] "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)" { if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) @@ -8598,7 +8616,7 @@ && reload_completed && int_reg_operand (operands[0], <MODE>mode)" [(const_int 0)] { - rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, false, + rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true, NULL_RTX); DONE; } @@ -8620,14 +8638,14 @@ [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") (match_operator:TI2 3 "boolean_operator" [(not:TI2 - (match_operand:TI2 1 "int_reg_operand" "r,0,r")) - (match_operand:TI2 2 "int_reg_operand" "r,r,0")]))] + (match_operand:TI2 2 "int_reg_operand" "r,0,r")) + (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))] "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" "#" "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" [(const_int 0)] { - rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, false, + rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true, NULL_RTX); DONE; } @@ -9188,8 +9206,8 @@ }") (define_insn "mov<mode>_hardfloat" - [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,wa,wa,<f32_lr>,<f32_sm>,wu,Z,?<f32_dm>,?r,*c*l,!r,*h,!r,!r") - (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,wa,j,<f32_lm>,<f32_sr>,Z,wu,r,<f32_dm>,r,h,0,G,Fn"))] + [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,<f32_lr>,<f32_sm>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h,!r,!r") + (match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,<f32_lm>,<f32_sr>,Z,<f32_av>,r,<f32_dm>,r, h, 0, G,Fn"))] "(gpc_reg_operand (operands[0], <MODE>mode) || gpc_reg_operand (operands[1], <MODE>mode)) && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)" @@ -9390,8 +9408,8 @@ ;; reloading. (define_insn "*mov<mode>_hardfloat32" - [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,wv,Z,wa,wa,Y,r,!r,!r,!r,!r") - (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,wv,wa,j,r,Y,r,G,H,F"))] + [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,Y,r,!r,!r,!r,!r") + (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,r,Y,r,G,H,F"))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], <MODE>mode) || gpc_reg_operand (operands[1], <MODE>mode))" @@ -9459,8 +9477,8 @@ ; ld/std require word-aligned displacements -> 'Y' constraint. ; List Y->r and r->Y before r->r for reload. (define_insn "*mov<mode>_hardfloat64" - [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,wv,Z,wa,wa,Y,r,!r,*c*l,!r,*h,!r,!r,!r,r,wg,r,wk") - (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,wv,wa,j,r,Y,r,r,h,0,G,H,F,wg,r,wk,r"))] + [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_vsx>,<f64_vsx>,Y,r,!r,*c*l,!r,*h,!r,!r,!r,r,wg,r,<f64_dm>") + (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,<f64_vsx>,j,r,Y,r,r,h,0,G,H,F,wg,r,<f64_dm>,r"))] "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], <MODE>mode) || gpc_reg_operand (operands[1], <MODE>mode))" @@ -15714,22 +15732,9 @@ ;; a GPR. The addis instruction must be adjacent to the load, and use the same ;; register that is being loaded. The fused ops must be physically adjacent. -;; We use define_peephole for the actual addis/load, and the register used to -;; hold the addis value must be the same as the register being loaded. We use -;; define_peephole2 to change the register used for addis to be the register -;; being loaded, since we can look at whether it is dead after the load insn. - -(define_peephole - [(set (match_operand:P 0 "base_reg_operand" "") - (match_operand:P 1 "fusion_gpr_addis" "")) - (set (match_operand:INT1 2 "base_reg_operand" "") - (match_operand:INT1 3 "fusion_gpr_mem_load" ""))] - "TARGET_P8_FUSION && fusion_gpr_load_p (operands, false)" -{ - return emit_fusion_gpr_load (operands); -} - [(set_attr "type" "load") - (set_attr "length" "8")]) +;; Find cases where the addis that feeds into a load instruction is either used +;; once or is the same as the target register, and replace it with the fusion +;; insn (define_peephole2 [(set (match_operand:P 0 "base_reg_operand" "") @@ -15737,15 +15742,28 @@ (set (match_operand:INT1 2 "base_reg_operand" "") (match_operand:INT1 3 "fusion_gpr_mem_load" ""))] "TARGET_P8_FUSION - && (REGNO (operands[0]) != REGNO (operands[2]) - || GET_CODE (operands[3]) == SIGN_EXTEND) - && fusion_gpr_load_p (operands, true)" + && fusion_gpr_load_p (operands[0], operands[1], operands[2], + operands[3])" [(const_int 0)] { expand_fusion_gpr_load (operands); DONE; }) +;; Fusion insn, created by the define_peephole2 above (and eventually by +;; reload) + +(define_insn "fusion_gpr_load_<mode>" + [(set (match_operand:INT1 0 "base_reg_operand" "=&b") + (unspec:INT1 [(match_operand:INT1 1 "fusion_gpr_mem_combo" "")] + UNSPEC_FUSION_GPR))] + "TARGET_P8_FUSION" +{ + return emit_fusion_gpr_load (operands[0], operands[1]); +} + [(set_attr "type" "load") + (set_attr "length" "8")]) + ;; Miscellaneous ISA 2.06 (power7) instructions (define_insn "addg6s" |