diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-06-17 01:56:31 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-06-17 01:56:31 +0000 |
commit | ab0f6ce81f286df6d0a136abca62553bdeb69e6a (patch) | |
tree | a570b046814dba585fb23c24779f923df7ddb1ed /gcc/emit-rtl.c | |
parent | 371eccf30d95f441a12fef868164ba98886b8a6f (diff) | |
download | gcc-ab0f6ce81f286df6d0a136abca62553bdeb69e6a.tar.gz |
* emit-rtl.c (operand_subword): Tighten checks for when it is safe
to safe to extract a subword out of a REG.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@27564 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r-- | gcc/emit-rtl.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 2aa51aca4da..f1caea7d60d 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) |