1999-01-19 Fernando Nasser <fnasser@totem.to.cygnus.com>
[deliverable/binutils-gdb.git] / gdb / d10v-tdep.c
index 8579e7bb73a2d4807d30edb0eaefba094ced5367..f4b52f62295bb13dd6115dacbffad9fb195c1e21 100644 (file)
@@ -36,6 +36,31 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 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.  */
 
@@ -206,7 +231,7 @@ d10v_frame_chain (frame)
   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;
@@ -353,7 +378,7 @@ d10v_frame_find_saved_regs (fi, fsr)
   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])
@@ -362,9 +387,14 @@ d10v_frame_find_saved_regs (fi, fsr)
       }
 
   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])
@@ -409,9 +439,9 @@ show_regs (args, from_tty)
      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),
@@ -438,40 +468,34 @@ show_regs (args, from_tty)
                    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;
 }
 
@@ -484,34 +508,34 @@ d10v_write_pc (val, pid)
 
   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)
@@ -523,7 +547,7 @@ d10v_push_return_address (pc, sp)
      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;
 }
  
@@ -655,8 +679,17 @@ d10v_extract_return_value (type, regbuf, valbuf)
          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);
+       }
     }
 }
 
This page took 0.025914 seconds and 4 git commands to generate.