diff options
| author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-11-25 14:45:53 +0000 |
|---|---|---|
| committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-11-25 14:45:53 +0000 |
| commit | e72f00109bbd9ceba3a6658bc2df0f8c8725b7b5 (patch) | |
| tree | 559f6dd9e3f8349eba8f4861bdbf6737a188d3ea | |
| parent | 93110716f5c45eeda2b660982dea5b8950c7808a (diff) | |
| download | ppe42-gcc-e72f00109bbd9ceba3a6658bc2df0f8c8725b7b5.tar.gz ppe42-gcc-e72f00109bbd9ceba3a6658bc2df0f8c8725b7b5.zip | |
gcc/
* tree-sra.c (scalarize_use): Adjust the vpos argument to
sra_explode_bitfield_assignment in cases where the type is
wider than the bitfield.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130408 138bc75d-0d04-0410-961f-82ee72b054a4
| -rw-r--r-- | gcc/ChangeLog | 6 | ||||
| -rw-r--r-- | gcc/tree-sra.c | 24 |
2 files changed, 26 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c74de4ffe09..6308dae3e10 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2007-11-25 Richard Sandiford <rsandifo@nildram.co.uk> + + * tree-sra.c (scalarize_use): Adjust the vpos argument to + sra_explode_bitfield_assignment in cases where the type is + wider than the bitfield. + 2007-11-25 Richard Guenther <rguenther@suse.de> * tree.h (struct tree_block): Move locus member next to diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 7060d541eaf..83c5d8a2f09 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -3147,7 +3147,7 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi, if (!elt->use_block_copy) { tree type = TREE_TYPE (bfexpr); - tree var = make_rename_temp (type, "SR"), tmp, st; + tree var = make_rename_temp (type, "SR"), tmp, st, vpos; GIMPLE_STMT_OPERAND (stmt, 0) = var; update = true; @@ -3162,8 +3162,16 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi, var = tmp; } + /* If VAR is wider than BLEN bits, it is padded at the + most-significant end. We want to set VPOS such that + <BIT_FIELD_REF VAR BLEN VPOS> would refer to the + least-significant BLEN bits of VAR. */ + if (BYTES_BIG_ENDIAN) + vpos = size_binop (MINUS_EXPR, TYPE_SIZE (type), blen); + else + vpos = bitsize_int (0); sra_explode_bitfield_assignment - (var, bitsize_int (0), false, &listafter, blen, bpos, elt); + (var, vpos, false, &listafter, blen, bpos, elt); } else sra_sync_for_bitfield_assignment @@ -3199,7 +3207,7 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi, if (!elt->use_block_copy) { tree type = TREE_TYPE (bfexpr); - tree var; + tree var, vpos; if (!TYPE_UNSIGNED (type)) type = unsigned_type_for (type); @@ -3210,8 +3218,16 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi, (var, build_int_cst_wide (type, 0, 0)), &list); + /* If VAR is wider than BLEN bits, it is padded at the + most-significant end. We want to set VPOS such that + <BIT_FIELD_REF VAR BLEN VPOS> would refer to the + least-significant BLEN bits of VAR. */ + if (BYTES_BIG_ENDIAN) + vpos = size_binop (MINUS_EXPR, TYPE_SIZE (type), blen); + else + vpos = bitsize_int (0); sra_explode_bitfield_assignment - (var, bitsize_int (0), true, &list, blen, bpos, elt); + (var, vpos, true, &list, blen, bpos, elt); GIMPLE_STMT_OPERAND (stmt, 1) = var; update = true; |

