diff options
Diffstat (limited to 'gdb/m68hc11-tdep.c')
-rw-r--r-- | gdb/m68hc11-tdep.c | 75 |
1 files changed, 59 insertions, 16 deletions
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c index 611fb3e..e059796 100644 --- a/gdb/m68hc11-tdep.c +++ b/gdb/m68hc11-tdep.c @@ -750,6 +750,12 @@ show_regs (char *args, int from_tty) } static CORE_ADDR +m68hc11_stack_align (CORE_ADDR addr) +{ + return ((addr + 1) & -2); +} + +static CORE_ADDR m68hc11_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp, @@ -794,7 +800,7 @@ m68hc11_push_arguments (int nargs, 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; @@ -807,6 +813,13 @@ m68hc11_push_arguments (int nargs, 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; } @@ -817,7 +830,7 @@ m68hc11_push_arguments (int nargs, CORE_ADDR m68hc11_call_dummy_address (void) { - return (CORE_ADDR) read_register (HARD_PC_REGNUM); + return entry_point_address (); } static struct type * @@ -838,8 +851,24 @@ m68hc11_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) 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."); } @@ -853,16 +882,27 @@ m68hc11_extract_return_value (struct type *type, { 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"); } } @@ -871,13 +911,15 @@ m68hc11_extract_return_value (struct type *type, 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 @@ -899,7 +941,7 @@ m68hc11_push_return_address (CORE_ADDR pc, CORE_ADDR sp) { 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); @@ -1042,6 +1084,7 @@ m68hc11_gdbarch_init (struct gdbarch_info info, 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); |