summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/integrate.c75
2 files changed, 50 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 98b1e03c310..30fc441fb07 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+Wed Jan 13 20:12:37 1999 Richard Henderson <rth@cygnus.com>
+
+ * integrate.c (expand_inline_function): Recognize (mem (addressof))
+ and substitute. Copy the return value from there into a new pseudo.
+
Thu Jan 14 13:52:42 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
* config/c4x/c4x.md (in_annul_slot_3): Correctly allow unarycc
diff --git a/gcc/integrate.c b/gcc/integrate.c
index 943eeaff0d9..e5c716eb678 100644
--- a/gcc/integrate.c
+++ b/gcc/integrate.c
@@ -1709,46 +1709,61 @@ expand_inline_function (fndecl, parms, target, ignore, type,
map->inline_target = 0;
loc = DECL_RTL (DECL_RESULT (fndecl));
+
if (TYPE_MODE (type) == VOIDmode)
/* There is no return value to worry about. */
;
else if (GET_CODE (loc) == MEM)
{
- if (! structure_value_addr || ! aggregate_value_p (DECL_RESULT (fndecl)))
- abort ();
+ if (GET_CODE (XEXP (loc, 0)) == ADDRESSOF)
+ {
+ temp = copy_rtx_and_substitute (loc, map);
+ subst_constants (&temp, NULL_RTX, map);
+ apply_change_group ();
+ target = temp;
+ }
+ else
+ {
+ if (! structure_value_addr
+ || ! aggregate_value_p (DECL_RESULT (fndecl)))
+ abort ();
- /* Pass the function the address in which to return a structure value.
- Note that a constructor can cause someone to call us with
- STRUCTURE_VALUE_ADDR, but the initialization takes place
- via the first parameter, rather than the struct return address.
+ /* Pass the function the address in which to return a structure
+ value. Note that a constructor can cause someone to call us
+ with STRUCTURE_VALUE_ADDR, but the initialization takes place
+ via the first parameter, rather than the struct return address.
- We have two cases: If the address is a simple register indirect,
- use the mapping mechanism to point that register to our structure
- return address. Otherwise, store the structure return value into
- the place that it will be referenced from. */
+ We have two cases: If the address is a simple register
+ indirect, use the mapping mechanism to point that register to
+ our structure return address. Otherwise, store the structure
+ return value into the place that it will be referenced from. */
- if (GET_CODE (XEXP (loc, 0)) == REG)
- {
- temp = force_reg (Pmode,
- force_operand (structure_value_addr, NULL_RTX));
- map->reg_map[REGNO (XEXP (loc, 0))] = temp;
- if ((CONSTANT_P (structure_value_addr)
- || GET_CODE (structure_value_addr) == ADDRESSOF
- || (GET_CODE (structure_value_addr) == PLUS
- && XEXP (structure_value_addr, 0) == virtual_stack_vars_rtx
- && GET_CODE (XEXP (structure_value_addr, 1)) == CONST_INT))
- && REGNO (temp) < map->const_equiv_map_size)
+ if (GET_CODE (XEXP (loc, 0)) == REG)
{
- map->const_equiv_map[REGNO (temp)] = structure_value_addr;
- map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
+ temp = force_operand (structure_value_addr, NULL_RTX);
+ temp = force_reg (Pmode, temp);
+ map->reg_map[REGNO (XEXP (loc, 0))] = temp;
+
+ if ((CONSTANT_P (structure_value_addr)
+ || GET_CODE (structure_value_addr) == ADDRESSOF
+ || (GET_CODE (structure_value_addr) == PLUS
+ && (XEXP (structure_value_addr, 0)
+ == virtual_stack_vars_rtx)
+ && (GET_CODE (XEXP (structure_value_addr, 1))
+ == CONST_INT)))
+ && REGNO (temp) < map->const_equiv_map_size)
+ {
+ map->const_equiv_map[REGNO (temp)] = structure_value_addr;
+ map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
+ }
+ }
+ else
+ {
+ temp = copy_rtx_and_substitute (loc, map);
+ subst_constants (&temp, NULL_RTX, map);
+ apply_change_group ();
+ emit_move_insn (temp, structure_value_addr);
}
- }
- else
- {
- temp = copy_rtx_and_substitute (loc, map);
- subst_constants (&temp, NULL_RTX, map);
- apply_change_group ();
- emit_move_insn (temp, structure_value_addr);
}
}
else if (ignore)