summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>2012-06-28 13:58:32 +0000
committergjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>2012-06-28 13:58:32 +0000
commit4d025e72b3cb3539fb3d8c152ab9597f547450d9 (patch)
tree93ac9952fed04490768eb50f6e5eb31421f22b09
parent9184bcae75f69ce9eb976bc5e028dc1d08d880f9 (diff)
downloadgcc-4d025e72b3cb3539fb3d8c152ab9597f547450d9.tar.gz
Backport from 2012-06-28 mainline r189049
PR 53595 * config/avr/avr.c (avr_hard_regno_call_part_clobbered): New. * config/avr/avr-protos.h (avr_hard_regno_call_part_clobbered): New. * config/avr/avr.h (HARD_REGNO_CALL_PART_CLOBBERED): Forward to avr_hard_regno_call_part_clobbered. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@189050 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/avr/avr-protos.h1
-rw-r--r--gcc/config/avr/avr.c22
-rw-r--r--gcc/config/avr/avr.h6
4 files changed, 35 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a4e9daad4a2..ec8c7bc684f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2012-06-28 Georg-Johann Lay <avr@gjlay.de>
+
+ Backport from 2012-06-28 mainline r189049
+
+ PR 53595
+ * config/avr/avr.c (avr_hard_regno_call_part_clobbered): New.
+ * config/avr/avr-protos.h (avr_hard_regno_call_part_clobbered): New.
+ * config/avr/avr.h (HARD_REGNO_CALL_PART_CLOBBERED): Forward to
+ avr_hard_regno_call_part_clobbered.
+
2012-06-28 Richard Guenther <rguenther@suse.de>
PR middle-end/53790
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h
index fa1462ce886..7b9b05effa6 100644
--- a/gcc/config/avr/avr-protos.h
+++ b/gcc/config/avr/avr-protos.h
@@ -47,6 +47,7 @@ extern void init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
#endif /* TREE_CODE */
#ifdef RTX_CODE
+extern int avr_hard_regno_call_part_clobbered (unsigned, enum machine_mode);
extern const char *output_movqi (rtx insn, rtx operands[], int *l);
extern const char *output_movhi (rtx insn, rtx operands[], int *l);
extern const char *output_movsisf (rtx insn, rtx operands[], int *l);
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 2fa12f7bf1f..50682f29690 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -8890,6 +8890,28 @@ avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
}
+/* Implement `HARD_REGNO_CALL_PART_CLOBBERED'. */
+
+int
+avr_hard_regno_call_part_clobbered (unsigned regno, enum machine_mode mode)
+{
+ /* FIXME: This hook gets called with MODE:REGNO combinations that don't
+ represent valid hard registers like, e.g. HI:29. Returning TRUE
+ for such registers can lead to performance degradation as mentioned
+ in PR53595. Thus, report invalid hard registers as FALSE. */
+
+ if (!avr_hard_regno_mode_ok (regno, mode))
+ return 0;
+
+ /* Return true if any of the following boundaries is crossed:
+ 17/18, 27/28 and 29/30. */
+
+ return ((regno < 18 && regno + GET_MODE_SIZE (mode) > 18)
+ || (regno < REG_Y && regno + GET_MODE_SIZE (mode) > REG_Y)
+ || (regno < REG_Z && regno + GET_MODE_SIZE (mode) > REG_Z));
+}
+
+
/* Implement `MODE_CODE_BASE_REG_CLASS'. */
enum reg_class
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index afb247c4616..d5537238217 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -394,10 +394,8 @@ enum reg_class {
#define REGNO_OK_FOR_INDEX_P(NUM) 0
-#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
- (((REGNO) < 18 && (REGNO) + GET_MODE_SIZE (MODE) > 18) \
- || ((REGNO) < REG_Y && (REGNO) + GET_MODE_SIZE (MODE) > REG_Y) \
- || ((REGNO) < REG_Z && (REGNO) + GET_MODE_SIZE (MODE) > REG_Z))
+#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
+ avr_hard_regno_call_part_clobbered (REGNO, MODE)
#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true