aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1992-10-18 05:09:47 +0000
committerRichard Stallman <rms@gnu.org>1992-10-18 05:09:47 +0000
commit5c4d7cfb47ccf707b4398c7cb5dd51d4a4b260d5 (patch)
tree4df0c71d95980ba972b1302abdb3f8c788809750 /gcc
parentca3e4a2f2dba408a1706736ff1ec9cb8942edb38 (diff)
downloadgcc-5c4d7cfb47ccf707b4398c7cb5dd51d4a4b260d5.zip
gcc-5c4d7cfb47ccf707b4398c7cb5dd51d4a4b260d5.tar.gz
gcc-5c4d7cfb47ccf707b4398c7cb5dd51d4a4b260d5.tar.bz2
(store_field): If signed bitfield and want value, sign extend.
From-SVN: r2504
Diffstat (limited to 'gcc')
-rw-r--r--gcc/expr.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index a9c6ff1..db911c8 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2702,7 +2702,16 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
/* If possible, avoid refetching from the bitfield itself. */
if (width_mask != 0
&& ! (GET_CODE (target) == MEM && MEM_VOLATILE_P (target)))
- return expand_and (temp, GEN_INT (width_mask), NULL_RTX);
+ {
+ rtx count;
+ enum machine_mode tmode;
+ if (unsignedp)
+ return expand_and (temp, GEN_INT (width_mask), NULL_RTX);
+ tmode = GET_MODE (temp);
+ count = build_int_2 (GET_MODE_BITSIZE (tmode) - bitsize, 0);
+ temp = expand_shift (LSHIFT_EXPR, tmode, temp, count, 0, 0);
+ return expand_shift (RSHIFT_EXPR, tmode, temp, count, 0, 0);
+ }
return extract_bit_field (target, bitsize, bitpos, unsignedp,
NULL_RTX, value_mode, 0, align,
total_size);