From: Andreas Krebbel Date: Tue, 27 Jan 2015 14:59:48 +0000 (+0000) Subject: s390.c (s390_register_move_cost): Increase costs for FPR->GPR moves. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f954fb25aab2262d2eab0c602019810d19a8023a;p=gcc.git s390.c (s390_register_move_cost): Increase costs for FPR->GPR moves. 2015-01-27 Andreas Krebbel * config/s390/s390.c (s390_register_move_cost): Increase costs for FPR->GPR moves. From-SVN: r220168 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a4efbafb852..2ed7e80912f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2015-01-27 Andreas Krebbel + + * config/s390/s390.c (s390_register_move_cost): Increase costs for + FPR->GPR moves. + 2015-01-27 Richard Biener * tree-vrp.c (update_value_range): Intersect the range with diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 6985fb77675..1cc4e4affe6 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -2407,16 +2407,29 @@ s390_float_const_zero_p (rtx value) /* Implement TARGET_REGISTER_MOVE_COST. */ static int -s390_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED, +s390_register_move_cost (machine_mode mode, reg_class_t from, reg_class_t to) { - /* On s390, copy between fprs and gprs is expensive as long as no - ldgr/lgdr can be used. */ - if ((!TARGET_Z10 || GET_MODE_SIZE (mode) != 8) - && ((reg_classes_intersect_p (from, GENERAL_REGS) - && reg_classes_intersect_p (to, FP_REGS)) - || (reg_classes_intersect_p (from, FP_REGS) - && reg_classes_intersect_p (to, GENERAL_REGS)))) + /* On s390, copy between fprs and gprs is expensive. */ + + /* It becomes somewhat faster having ldgr/lgdr. */ + if (TARGET_Z10 && GET_MODE_SIZE (mode) == 8) + { + /* ldgr is single cycle. */ + if (reg_classes_intersect_p (from, GENERAL_REGS) + && reg_classes_intersect_p (to, FP_REGS)) + return 1; + /* lgdr needs 3 cycles. */ + if (reg_classes_intersect_p (to, GENERAL_REGS) + && reg_classes_intersect_p (from, FP_REGS)) + return 3; + } + + /* Otherwise copying is done via memory. */ + if ((reg_classes_intersect_p (from, GENERAL_REGS) + && reg_classes_intersect_p (to, FP_REGS)) + || (reg_classes_intersect_p (from, FP_REGS) + && reg_classes_intersect_p (to, GENERAL_REGS))) return 10; return 1;