diff options
author | Jeffrey A Law <law@cygnus.com> | 1999-06-17 01:56:31 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1999-06-16 19:56:31 -0600 |
commit | 227d6ce040d7ac43962ab3610f50cbda3dbed544 (patch) | |
tree | a570b046814dba585fb23c24779f923df7ddb1ed | |
parent | ff77e80cf8aed5b75c76ac943c58e5cb9958b120 (diff) | |
download | gcc-227d6ce040d7ac43962ab3610f50cbda3dbed544.zip gcc-227d6ce040d7ac43962ab3610f50cbda3dbed544.tar.gz gcc-227d6ce040d7ac43962ab3610f50cbda3dbed544.tar.bz2 |
emit-rtl.c (operand_subword): Tighten checks for when it is safe to safe to extract a subword out of a REG.
* emit-rtl.c (operand_subword): Tighten checks for when it is safe
to safe to extract a subword out of a REG.
From-SVN: r27564
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 29 |
2 files changed, 31 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 73fd4f9..f0608fc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +Thu Jun 17 02:54:30 1999 Jeffrey A Law (law@cygnus.com) + + * emit-rtl.c (operand_subword): Tighten checks for when it is safe + to safe to extract a subword out of a REG. + Thu Jun 17 01:45:24 1999 J"orn Rennecke <amylaar@cygnus.co.uk> * sh.md (mulsi3): Don't add a no-op move at the end. diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 2aa51ac..f1caea7 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1196,10 +1196,33 @@ operand_subword (op, i, validate_address, mode) /* If OP is a REG or SUBREG, we can handle it very simply. */ if (GET_CODE (op) == REG) { - /* If the register is not valid for MODE, return 0. If we don't - do this, there is no way to fix up the resulting REG later. */ + /* ??? There is a potential problem with this code. It does not + properly handle extractions of a subword from a hard register + that is larger than word_mode. Presumably the check for + HARD_REGNO_MODE_OK catches these most of these cases. */ + + /* If OP is a hard register, but OP + I is not a hard register, + then extracting a subword is impossible. + + For example, consider if OP is the last hard register and it is + larger than word_mode. If we wanted word N (for N > 0) because a + part of that hard register was known to contain a useful value, + then OP + I would refer to a pseudo, not the hard register we + actually wanted. */ + if (REGNO (op) < FIRST_PSEUDO_REGISTER + && REGNO (op) + i >= FIRST_PSEUDO_REGISTER) + return 0; + + /* If the register is not valid for MODE, return 0. Note we + have to check both OP and OP + I since they may refer to + different parts of the register file. + + Consider if OP refers to the last 96bit FP register and we want + subword 3 because that subword is known to contain a value we + needed. */ if (REGNO (op) < FIRST_PSEUDO_REGISTER - && ! HARD_REGNO_MODE_OK (REGNO (op) + i, word_mode)) + && (! HARD_REGNO_MODE_OK (REGNO (op), word_mode) + || ! HARD_REGNO_MODE_OK (REGNO (op) + i, word_mode))) return 0; else if (REGNO (op) >= FIRST_PSEUDO_REGISTER || (REG_FUNCTION_VALUE_P (op) |