Wed Nov 4 18:46:47 1998 Dave Brolley <brolley@cygnus.com>
[deliverable/binutils-gdb.git] / gdb / tic80-tdep.c
index 5d1cc64e3a803c480c5298789e245541b7808f54..4a9883b7d2a40dd78b7b3feb379605790c4f992d 100644 (file)
@@ -176,7 +176,10 @@ tic80_init_extra_frame_info (fi)
   if (fi->next)
     fi->pc = FRAME_SAVED_PC (fi->next);
 
-  memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs);
+  /* Because zero is a valid register offset relative to SP, we initialize
+     the offsets to -1 to indicate unused entries.  */
+  for (reg = 0; reg < NUM_REGS; reg++)
+    fi->fsr.regs[reg] = -1;
 
   if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
     {
@@ -194,12 +197,18 @@ tic80_init_extra_frame_info (fi)
       if (!fi->next)                   /* this is the innermost frame? */
        fi->frame = read_register (fi->framereg);
       else                             /* not the innermost frame */
-       if (fi->framereg == FP_REGNUM)              /* we have an FP */
-         if (fi->next->fsr.regs[FP_REGNUM] != 0)   /* caller saved our FP */
-           fi->frame = read_memory_integer (fi->next->fsr.regs[FP_REGNUM], 4);
+       /* If this function uses FP as the frame register, and the function
+          it called saved the FP, get the saved FP.  */
+       if (fi->framereg == FP_REGNUM &&
+           fi->next->fsr.regs[FP_REGNUM] != (unsigned) -1)
+         fi->frame = read_memory_integer (fi->next->fsr.regs[FP_REGNUM], 4);
+
+      /* Convert SP-relative offsets of saved registers to real addresses.  */
       for (reg = 0; reg < NUM_REGS; reg++)
-       if (fi->fsr.regs[reg] != 0)
-         fi->fsr.regs[reg] += fi->frame - fi->frameoffset;
+       if (fi->fsr.regs[reg] == (unsigned) -1)
+           fi->fsr.regs[reg] = 0;      /* unused entry */
+         else
+           fi->fsr.regs[reg] += fi->frame - fi->frameoffset;
     }
 }
 
@@ -297,7 +306,7 @@ tic80_frame_saved_pc (fi)
      struct frame_info *fi;
 {
   if (PC_IN_CALL_DUMMY(fi->pc, fi->frame, fi->frame))
-    return generic_read_register_dummy(fi->pc, fi->frame, PC_REGNUM);
+    return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
   else
     return tic80_find_callers_reg (fi, LR_REGNUM);
 }
@@ -371,6 +380,7 @@ tic80_push_arguments (nargs, args, sp, struct_return, struct_addr)
   char valbuf[4];
   int len;
   int odd_sized_struct;
+  int is_struct;
 
   /* first force sp to a 4-byte alignment */
   sp = sp & ~3;
@@ -396,30 +406,41 @@ tic80_push_arguments (nargs, args, sp, struct_return, struct_addr)
     {
       type = VALUE_TYPE (args[argnum]);
       len  = TYPE_LENGTH (type);
-      memset(valbuf, 0, sizeof(valbuf));
+      memset (valbuf, 0, sizeof (valbuf));
       val = (char *) VALUE_CONTENTS (args[argnum]);
-      if (len < 4)
-        { /* value gets right-justified in the register or stack word */
-          memcpy(valbuf + (4 - len), val, len);
-          val = valbuf;
-        }
  
 /* FIXME -- tic80 can take doubleword arguments in register pairs */
-      if (len > 4 && (len & 3) != 0)
-        odd_sized_struct = 1;           /* such structs go entirely on stack */
+      is_struct = (type->code == TYPE_CODE_STRUCT);
+      odd_sized_struct = 0;
+
+      if (! is_struct)
+       {
+         if (len < 4)
+           { /* value gets right-justified in the register or stack word */
+             memcpy (valbuf + (4 - len), val, len);
+             val = valbuf;
+           }
+         if (len > 4 && (len & 3) != 0)
+           odd_sized_struct = 1;     /* such structs go entirely on stack */
+       }
       else
-        odd_sized_struct = 0;
+       {
+         /* Structs are always passed by reference. */
+         write_register (argreg, sp + stack_offset);
+         argreg ++;
+       }
+
       while (len > 0)
         {
-          if (argreg > ARGLAST_REGNUM || odd_sized_struct)
+          if (is_struct || argreg > ARGLAST_REGNUM || odd_sized_struct)
             {                          /* must go on the stack */
               write_memory (sp + stack_offset, val, 4);
               stack_offset += 4;
             }
           /* NOTE WELL!!!!!  This is not an "else if" clause!!!
-             That's because some *&^%$ things get passed on the stack
+             That's because some things get passed on the stack
              AND in the registers!   */
-          if (argreg <= ARGLAST_REGNUM)
+          if (!is_struct && argreg <= ARGLAST_REGNUM)
             {                          /* there's room in a register */
               regval = extract_address (val, REGISTER_RAW_SIZE(argreg));
               write_register (argreg, regval);
This page took 0.037482 seconds and 4 git commands to generate.