+2000-09-06 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * m68hc11-tdep.c (m68hc11_store_return_value): Store the value
+ in D and X if it's larger than 16-bits.
+ (m68hc11_extract_return_value): Fix extractions for 1 and 3 bytes
+ return.
+ (m68hc11_push_return_address): Use CALL_DUMMY_ADDRESS for the
+ return address.
+ (m68hc11_use_struct_convention): Check for struct and union.
+ (m68hc11_return_value_on_stack): Use the struct convention.
+ (m68hc11_call_dummy_address): Use the entry point address.
+ (m68hc11_push_arguments): Fix alignment and padding.
+ (m68hc11_stack_align): New function.
+ (m68hc11_gdbarch_init): Register it.
+
2000-09-06 Scott Bambrough <scottb@netwinder.org>
* arm-linux-tdep.c (arm_linux_skip_solib_resolver):
printf_filtered ("\n");
}
+static CORE_ADDR
+m68hc11_stack_align (CORE_ADDR addr)
+{
+ return ((addr + 1) & -2);
+}
+
static CORE_ADDR
m68hc11_push_arguments (int nargs,
value_ptr *args,
for (argnum = first_stack_argnum; argnum < nargs; argnum++)
{
type = VALUE_TYPE (args[argnum]);
- stack_alloc += (TYPE_LENGTH (type) + 1) & ~2;
+ stack_alloc += (TYPE_LENGTH (type) + 1) & -2;
}
sp -= stack_alloc;
val = (char*) VALUE_CONTENTS (args[argnum]);
write_memory (sp + stack_offset, val, len);
stack_offset += len;
+ if (len & 1)
+ {
+ static char zero = 0;
+
+ write_memory (sp + stack_offset, &zero, 1);
+ stack_offset++;
+ }
}
return sp;
}
CORE_ADDR
m68hc11_call_dummy_address (void)
{
- return (CORE_ADDR) read_register (HARD_PC_REGNUM);
+ return entry_point_address ();
}
static struct type *
static void
m68hc11_store_return_value (struct type *type, char *valbuf)
{
- write_register_bytes (REGISTER_BYTE (HARD_D_REGNUM),
- valbuf, TYPE_LENGTH (type));
+ int len;
+
+ len = TYPE_LENGTH (type);
+
+ /* First argument is passed in D and X registers. */
+ if (len <= 4)
+ {
+ LONGEST v = extract_unsigned_integer (valbuf, len);
+
+ write_register (HARD_D_REGNUM, v);
+ if (len > 2)
+ {
+ v >>= 16;
+ write_register (HARD_X_REGNUM, v);
+ }
+ }
+ else
+ error ("return of value > 4 is not supported.");
}
{
int len = TYPE_LENGTH (type);
- if (len <= 2)
- {
- memcpy (valbuf, ®buf[2], len);
- }
- else if (len <= 4)
- {
- memcpy (valbuf, regbuf, len);
- }
- else
+ switch (len)
{
+ case 1:
+ memcpy (valbuf, ®buf[HARD_D_REGNUM * 2 + 1], len);
+ break;
+
+ case 2:
+ memcpy (valbuf, ®buf[HARD_D_REGNUM * 2], len);
+ break;
+
+ case 3:
+ memcpy (&valbuf[0], ®buf[HARD_X_REGNUM * 2 + 1], 1);
+ memcpy (&valbuf[1], ®buf[HARD_D_REGNUM * 2], 2);
+ break;
+
+ case 4:
+ memcpy (&valbuf[0], ®buf[HARD_X_REGNUM * 2], 2);
+ memcpy (&valbuf[2], ®buf[HARD_D_REGNUM * 2], 2);
+ break;
+
+ default:
error ("bad size for return value");
}
}
static int
m68hc11_use_struct_convention (int gcc_p, struct type *type)
{
- return (TYPE_LENGTH (type) > 4);
+ return (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION
+ || TYPE_LENGTH (type) > 4);
}
static int
m68hc11_return_value_on_stack (struct type *type)
{
- return m68hc11_use_struct_convention (1, type);
+ return TYPE_LENGTH (type) > 4;
}
/* Extract from an array REGBUF containing the (raw) register state
{
char valbuf[2];
- pc = read_register (HARD_PC_REGNUM);
+ pc = CALL_DUMMY_ADDRESS ();
sp -= 2;
store_unsigned_integer (valbuf, 2, pc);
write_memory (sp + stack_correction, valbuf, 2);
set_gdbarch_decr_pc_after_break (gdbarch, 0);
set_gdbarch_function_start_offset (gdbarch, 0);
set_gdbarch_breakpoint_from_pc (gdbarch, m68hc11_breakpoint_from_pc);
+ set_gdbarch_stack_align (gdbarch, m68hc11_stack_align);
set_gdbarch_believe_pcc_promotion (gdbarch, 1);
set_gdbarch_ieee_float (gdbarch, 1);