void d10v_frame_find_saved_regs PARAMS ((struct frame_info *fi,
struct frame_saved_regs *fsr));
+int
+d10v_frame_chain_valid (chain, frame)
+ CORE_ADDR chain;
+ struct frame_info *frame; /* not used here */
+{
+ return ((chain) != 0 && (frame) != 0 && (frame)->pc > IMEM_START);
+}
+
+
+/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of
+ EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc
+ and TYPE is the type (which is known to be struct, union or array).
+
+ The d10v returns anything less than 8 bytes in size in
+ registers. */
+
+int
+d10v_use_struct_convention (gcc_p, type)
+ int gcc_p;
+ struct type *type;
+{
+ return (TYPE_LENGTH (type) > 8);
+}
+
+
/* Discard from the stack the innermost frame, restoring all saved
registers. */
if (!read_memory_unsigned_integer(fsr.regs[FP_REGNUM], REGISTER_RAW_SIZE(FP_REGNUM)))
return (CORE_ADDR)0;
- return read_memory_unsigned_integer(fsr.regs[FP_REGNUM], REGISTER_RAW_SIZE(FP_REGNUM))| DMEM_START;
+ return D10V_MAKE_DADDR (read_memory_unsigned_integer (fsr.regs[FP_REGNUM], REGISTER_RAW_SIZE (FP_REGNUM)));
}
static int next_addr, uses_frame;
fi->size = -next_addr;
if (!(fp & 0xffff))
- fp = read_register(SP_REGNUM) | DMEM_START;
+ fp = D10V_MAKE_DADDR (read_register(SP_REGNUM));
for (i=0; i<NUM_REGS-1; i++)
if (fsr->regs[i])
}
if (fsr->regs[LR_REGNUM])
- fi->return_pc = (read_memory_unsigned_integer(fsr->regs[LR_REGNUM], REGISTER_RAW_SIZE(LR_REGNUM)) << 2) | IMEM_START;
+ {
+ CORE_ADDR return_pc = read_memory_unsigned_integer (fsr->regs[LR_REGNUM], REGISTER_RAW_SIZE (LR_REGNUM));
+ fi->return_pc = D10V_MAKE_IADDR (return_pc);
+ }
else
- fi->return_pc = (read_register(LR_REGNUM) << 2) | IMEM_START;
+ {
+ fi->return_pc = D10V_MAKE_IADDR (read_register(LR_REGNUM));
+ }
/* th SP is not normally (ever?) saved, but check anyway */
if (!fsr->regs[SP_REGNUM])
char *args;
int from_tty;
{
- LONGEST num1, num2;
+ int a;
printf_filtered ("PC=%04x (0x%x) PSW=%04x RPT_S=%04x RPT_E=%04x RPT_C=%04x\n",
- read_register (PC_REGNUM), (read_register (PC_REGNUM) << 2) + IMEM_START,
+ read_register (PC_REGNUM), D10V_MAKE_IADDR (read_register (PC_REGNUM)),
read_register (PSW_REGNUM),
read_register (24),
read_register (25),
read_register (IMAP0_REGNUM),
read_register (IMAP1_REGNUM),
read_register (DMAP_REGNUM));
- read_register_gen (A0_REGNUM, (char *)&num1);
- read_register_gen (A0_REGNUM+1, (char *)&num2);
- printf_filtered ("A0-A1 %010llx %010llx\n",num1, num2);
-}
-
-static CORE_ADDR
-d10v_xlate_addr (addr)
- int addr;
-{
- int imap;
-
- if (addr < 0x20000)
- imap = (int)read_register(IMAP0_REGNUM);
- else
- imap = (int)read_register(IMAP1_REGNUM);
-
- if (imap & 0x1000)
- return (CORE_ADDR)(addr + 0x1000000);
- return (CORE_ADDR)(addr + (imap & 0xff)*0x20000);
+ printf_filtered ("A0-A1");
+ for (a = A0_REGNUM; a <= A0_REGNUM + 1; a++)
+ {
+ char num[MAX_REGISTER_RAW_SIZE];
+ int i;
+ printf_filtered (" ");
+ read_register_gen (a, (char *)&num);
+ for (i = 0; i < MAX_REGISTER_RAW_SIZE; i++)
+ {
+ printf_filtered ("%02x", (num[i] & 0xff));
+ }
+ }
+ printf_filtered ("\n");
}
-
CORE_ADDR
d10v_read_pc (pid)
int pid;
{
int save_pid;
+ CORE_ADDR pc;
CORE_ADDR retval;
save_pid = inferior_pid;
inferior_pid = pid;
- retval = (int)read_register (PC_REGNUM);
+ pc = (int) read_register (PC_REGNUM);
inferior_pid = save_pid;
- retval = d10v_xlate_addr(retval << 2);
+ retval = D10V_MAKE_IADDR (pc);
return retval;
}
save_pid = inferior_pid;
inferior_pid = pid;
- write_register (PC_REGNUM, (val & 0x3ffff) >> 2);
+ write_register (PC_REGNUM, D10V_CONVERT_IADDR_TO_RAW (val));
inferior_pid = save_pid;
}
CORE_ADDR
d10v_read_sp ()
{
- return (read_register(SP_REGNUM) | DMEM_START);
+ return (D10V_MAKE_DADDR (read_register (SP_REGNUM)));
}
void
d10v_write_sp (val)
CORE_ADDR val;
{
- write_register (SP_REGNUM, (LONGEST)(val & 0xffff));
+ write_register (SP_REGNUM, D10V_CONVERT_DADDR_TO_RAW (val));
}
void
d10v_write_fp (val)
CORE_ADDR val;
{
- write_register (FP_REGNUM, (LONGEST)(val & 0xffff));
+ write_register (FP_REGNUM, D10V_CONVERT_DADDR_TO_RAW (val));
}
CORE_ADDR
d10v_read_fp ()
{
- return (read_register(FP_REGNUM) | DMEM_START);
+ return (D10V_MAKE_DADDR (read_register(FP_REGNUM)));
}
/* Function: push_return_address (pc)
CORE_ADDR pc;
CORE_ADDR sp;
{
- write_register (LR_REGNUM, (CALL_DUMMY_ADDRESS () & 0xffff) >> 2);
+ write_register (LR_REGNUM, D10V_CONVERT_IADDR_TO_RAW (CALL_DUMMY_ADDRESS ()));
return sp;
}
int struct_return;
CORE_ADDR struct_addr;
{
- int i, len;
- int index;
+ int i;
int regnum = ARG1_REGNUM;
- char buffer[4], *contents;
- LONGEST val;
- CORE_ADDR ptrs[10];
-
-
- /* Pass 1. Put all large args on stack, pass pointers */
- index = 0;
- for (i = 0; i < nargs; i++)
- {
- value_ptr arg = args[i];
- struct type *arg_type = check_typedef (VALUE_TYPE (arg));
- len = TYPE_LENGTH (arg_type);
- contents = VALUE_CONTENTS(arg);
- if (len > 4)
- {
- /* put on word aligned stack and pass pointers */
- sp = (sp - len) & ~1;
- write_memory (sp, contents, len);
- ptrs[index++] = sp;
- }
- }
-
- /* Pass 2. Fill in registers and arg lists */
- index = 0;
+
+ /* Fill in registers and arg lists */
for (i = 0; i < nargs; i++)
{
value_ptr arg = args[i];
- struct type *arg_type = check_typedef (VALUE_TYPE (arg));
- len = TYPE_LENGTH (arg_type);
- if (len > 4)
+ struct type *type = check_typedef (VALUE_TYPE (arg));
+ char *contents = VALUE_CONTENTS (arg);
+ int len = TYPE_LENGTH (type);
+ /* printf ("push: type=%d len=%d\n", type->code, len); */
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
{
- /* pass pointer to previously saved data */
+ /* pointers require special handling - first convert and
+ then store */
+ long val = extract_signed_integer (contents, len);
+ len = 2;
+ if (TYPE_TARGET_TYPE (type)
+ && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC))
+ {
+ /* function pointer */
+ val = D10V_CONVERT_IADDR_TO_RAW (val);
+ }
+ else if (D10V_IADDR_P (val))
+ {
+ /* also function pointer! */
+ val = D10V_CONVERT_DADDR_TO_RAW (val);
+ }
+ else
+ {
+ /* data pointer */
+ val &= 0xFFFF;
+ }
if (regnum <= ARGN_REGNUM)
- write_register (regnum++, ptrs[index++]);
+ write_register (regnum++, val & 0xffff);
else
{
- /* no more registers available. put it on the stack */
+ char ptr[2];
sp -= 2;
- store_address (buffer, 2, ptrs[index++]);
- write_memory (sp, buffer, 2);
+ store_address (ptr, val & 0xffff, 2);
+ write_memory (sp, ptr, 2);
}
}
else
{
- int even_regnum = (regnum + 1) & ~1;
- contents = VALUE_CONTENTS(arg);
- val = extract_signed_integer (contents, len);
- /* printf("push: type=%d len=%d val=0x%x\n",arg_type->code,len,val); */
- if (arg_type->code == TYPE_CODE_PTR)
+ int aligned_regnum = (regnum + 1) & ~1;
+ if (len <= 2 && regnum <= ARGN_REGNUM)
+ /* fits in a single register, do not align */
{
- if ( (val & 0x3000000) == 0x1000000)
+ long val = extract_unsigned_integer (contents, len);
+ write_register (regnum++, val);
+ }
+ else if (len <= (ARGN_REGNUM - aligned_regnum + 1) * 2)
+ /* value fits in remaining registers, store keeping left
+ aligned */
+ {
+ int b;
+ regnum = aligned_regnum;
+ for (b = 0; b < (len & ~1); b += 2)
{
- /* function pointer */
- val = (val & 0x3FFFF) >> 2;
- len = 2;
+ long val = extract_unsigned_integer (&contents[b], 2);
+ write_register (regnum++, val);
}
- else
+ if (b < len)
{
- /* data pointer */
- val &= 0xFFFF;
- len = 2;
+ long val = extract_unsigned_integer (&contents[b], 1);
+ write_register (regnum++, (val << 8));
}
}
-
- if (regnum <= ARGN_REGNUM && len == 1)
- {
- write_register (regnum++, val & 0xff);
- }
- if (regnum <= ARGN_REGNUM && len == 2)
- {
- write_register (regnum++, val & 0xffff);
- }
- else if (even_regnum <= ARGN_REGNUM - 1 && len == 3)
- {
- /* next even reg and space for two */
- /* TARGET_BYTE_ORDER == BIG_ENDIAN */
- regnum = even_regnum;
- write_register (regnum++, (val >> 8) & 0xffff);
- write_register (regnum++, (val & 0xff) << 8);
- }
- else if (even_regnum <= ARGN_REGNUM - 1 && len == 4)
- {
- /* next even reg and space for two */
- /* TARGET_BYTE_ORDER == BIG_ENDIAN */
- regnum = even_regnum;
- write_register (regnum++, (val >> 16) & 0xffff);
- write_register (regnum++, val & 0xffff);
- }
else
{
+ /* arg goes straight on stack */
regnum = ARGN_REGNUM + 1;
sp = (sp - len) & ~1;
write_memory (sp, contents, len);
unsigned short c = extract_unsigned_integer (regbuf + REGISTER_BYTE (RET1_REGNUM), REGISTER_RAW_SIZE (RET1_REGNUM));
store_unsigned_integer (valbuf, 1, c);
}
- else
+ else if ((len & 1) == 0)
memcpy (valbuf, regbuf + REGISTER_BYTE (RET1_REGNUM), len);
+ else
+ {
+ /* For return values of odd size, the first byte is in the
+ least significant part of the first register. The
+ remaining bytes in remaining registers. Interestingly,
+ when such values are passed in, the last byte is in the
+ most significant byte of that same register - wierd. */
+ memcpy (valbuf, regbuf + REGISTER_BYTE (RET1_REGNUM) + 1, len);
+ }
}
}