mirror of
https://git.freebsd.org/ports.git
synced 2025-06-15 01:30:33 -04:00
Completely reorganize the patches for this port. Patches for new devices are now synchronized with the Atmel AVR tools. The main difference is the naming scheme, as FreeBSD patches start with "patch-", while the Atmel AVR Tools patches end up in ".patch".
102 lines
3.4 KiB
Text
102 lines
3.4 KiB
Text
--- gcc/config/avr/avr.c.orig 2011-09-30 16:19:47.000000000 +0200
|
|
+++ gcc/config/avr/avr.c 2011-09-30 16:23:26.000000000 +0200
|
|
@@ -1155,8 +1155,7 @@
|
|
true_regnum (XEXP (x, 0)));
|
|
debug_rtx (x);
|
|
}
|
|
- if (!strict && GET_CODE (x) == SUBREG)
|
|
- x = SUBREG_REG (x);
|
|
+
|
|
if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
|
|
: REG_OK_FOR_BASE_NOSTRICT_P (x)))
|
|
r = POINTER_REGS;
|
|
@@ -7135,26 +7134,30 @@
|
|
int
|
|
avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
|
|
{
|
|
- /* Disallow QImode in stack pointer regs. */
|
|
- if ((regno == REG_SP || regno == (REG_SP + 1)) && mode == QImode)
|
|
- return 0;
|
|
-
|
|
- /* The only thing that can go into registers r28:r29 is a Pmode. */
|
|
- if (regno == REG_Y && mode == Pmode)
|
|
- return 1;
|
|
-
|
|
- /* Otherwise disallow all regno/mode combinations that span r28:r29. */
|
|
- if (regno <= (REG_Y + 1) && (regno + GET_MODE_SIZE (mode)) >= (REG_Y + 1))
|
|
- return 0;
|
|
-
|
|
- if (mode == QImode)
|
|
+ /* NOTE: 8-bit values must not be disallowed for R28 or R29.
|
|
+ Disallowing QI et al. in these regs might lead to code like
|
|
+ (set (subreg:QI (reg:HI 28) n) ...)
|
|
+ which will result in wrong code because reload does not
|
|
+ handle SUBREGs of hard regsisters like this.
|
|
+ This could be fixed in reload. However, it appears
|
|
+ that fixing reload is not wanted by reload people. */
|
|
+
|
|
+ /* Any GENERAL_REGS register can hold 8-bit values. */
|
|
+
|
|
+ if (GET_MODE_SIZE (mode) == 1)
|
|
return 1;
|
|
|
|
- /* Modes larger than QImode occupy consecutive registers. */
|
|
- if (regno + GET_MODE_SIZE (mode) > FIRST_PSEUDO_REGISTER)
|
|
+ /* FIXME: Ideally, the following test is not needed.
|
|
+ However, it turned out that it can reduce the number
|
|
+ of spill fails. AVR and it's poor endowment with
|
|
+ address registers is extreme stress test for reload. */
|
|
+
|
|
+ if (GET_MODE_SIZE (mode) >= 4
|
|
+ && regno >= REG_X)
|
|
return 0;
|
|
|
|
- /* All modes larger than QImode should start in an even register. */
|
|
+ /* All modes larger than 8 bits should start in an even register. */
|
|
+
|
|
return !(regno & 1);
|
|
}
|
|
|
|
@@ -7281,13 +7284,23 @@
|
|
&& !df_regs_ever_live_p (regno))
|
|
return false;
|
|
|
|
+ /* Don't allow hard registers that might be part of the frame pointer.
|
|
+ Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
|
|
+ and don't care for a frame pointer that spans more than one register. */
|
|
+
|
|
+ if ((!reload_completed || frame_pointer_needed)
|
|
+ && (regno == REG_Y || regno == REG_Y + 1))
|
|
+ {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
return true;
|
|
}
|
|
|
|
/* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
|
|
|
|
int
|
|
-avr_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
|
|
+avr_hard_regno_rename_ok (unsigned int old_reg,
|
|
unsigned int new_reg)
|
|
{
|
|
/* Interrupt functions can only use registers that have already been
|
|
@@ -7298,6 +7311,17 @@
|
|
&& !df_regs_ever_live_p (new_reg))
|
|
return 0;
|
|
|
|
+ /* Don't allow hard registers that might be part of the frame pointer.
|
|
+ Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
|
|
+ and don't care for a frame pointer that spans more than one register. */
|
|
+
|
|
+ if ((!reload_completed || frame_pointer_needed)
|
|
+ && (old_reg == REG_Y || old_reg == REG_Y + 1
|
|
+ || new_reg == REG_Y || new_reg == REG_Y + 1))
|
|
+ {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
return 1;
|
|
}
|
|
|