aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1997-01-04 22:12:25 -0500
committerRichard Kenner <kenner@gcc.gnu.org>1997-01-04 22:12:25 -0500
commit86b5812c1817f234a0f3e283e587f14c70fa90ba (patch)
tree9a19f78e3d5993d87592752ce470da3a948e1393
parentac01eace31d7c08ffb77c1f732258c1a93eb972f (diff)
downloadgcc-86b5812c1817f234a0f3e283e587f14c70fa90ba.zip
gcc-86b5812c1817f234a0f3e283e587f14c70fa90ba.tar.gz
gcc-86b5812c1817f234a0f3e283e587f14c70fa90ba.tar.bz2
(expand_expr, case COMPONENT_REF): If taking value from a CONSTRUCTOR,
must mask/sign-extend if bitfield. (expand_builtin, case BUILT_IN_LONGJMP): Pass type, not IDENTIFIER, to send arg of RETURN_POPS_ARGS. From-SVN: r13373
-rw-r--r--gcc/expr.c48
1 files changed, 44 insertions, 4 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index cbd813b..e4c6609 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -5467,8 +5467,46 @@ expand_expr (exp, target, tmode, modifier)
for (elt = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0)); elt;
elt = TREE_CHAIN (elt))
- if (TREE_PURPOSE (elt) == TREE_OPERAND (exp, 1))
- return expand_expr (TREE_VALUE (elt), target, tmode, modifier);
+ if (TREE_PURPOSE (elt) == TREE_OPERAND (exp, 1)
+ /* We can normally use the value of the field in the
+ CONSTRUCTOR. However, if this is a bitfield in
+ an integral mode that we can fit in a HOST_WIDE_INT,
+ we must mask only the number of bits in the bitfield,
+ since this is done implicitly by the constructor. If
+ the bitfield does not meet either of those conditions,
+ we can't do this optimization. */
+ && (! DECL_BIT_FIELD (TREE_PURPOSE (elt))
+ || ((GET_MODE_CLASS (DECL_MODE (TREE_PURPOSE (elt)))
+ == MODE_INT)
+ && (GET_MODE_BITSIZE (DECL_MODE (TREE_PURPOSE (elt)))
+ <= HOST_BITS_PER_WIDE_INT))))
+ {
+ op0 = expand_expr (TREE_VALUE (elt), target, tmode, modifier);
+ if (DECL_BIT_FIELD (TREE_PURPOSE (elt)))
+ {
+ int bitsize = DECL_FIELD_SIZE (TREE_PURPOSE (elt));
+ enum machine_mode imode
+ = TYPE_MODE (TREE_TYPE (TREE_PURPOSE (elt)));
+
+ if (TREE_UNSIGNED (TREE_TYPE (TREE_PURPOSE (elt))))
+ {
+ op1 = GEN_INT (((HOST_WIDE_INT) 1 << bitsize) - 1);
+ op0 = expand_and (op0, op1, target);
+ }
+ else
+ {
+ tree count
+ = build_int_2 (imode - bitsize, 0);
+
+ op0 = expand_shift (LSHIFT_EXPR, imode, op0, count,
+ target, 0);
+ op0 = expand_shift (RSHIFT_EXPR, imode, op0, count,
+ target, 0);
+ }
+ }
+
+ return op0;
+ }
}
{
@@ -8838,8 +8876,10 @@ expand_builtin (exp, target, subtarget, mode, ignore)
enum machine_mode sa_mode = Pmode;
rtx stack_save;
int old_inhibit_defer_pop = inhibit_defer_pop;
- int return_pops = RETURN_POPS_ARGS (get_identifier ("__dummy"),
- get_identifier ("__dummy"), 0);
+ int return_pops
+ = RETURN_POPS_ARGS (get_identifier ("__dummy"),
+ build_function_type (void_type_node, NULL_TREE),
+ 0);
rtx next_arg_reg;
CUMULATIVE_ARGS args_so_far;
int i;