Fix argument passing for call
authorDenis Chertykov <chertykov@gmail.com>
Sat, 5 Mar 2016 12:17:15 +0000 (15:17 +0300)
committerDenis Chertykov <chertykov@gmail.com>
Sat, 5 Mar 2016 12:17:15 +0000 (15:17 +0300)
When calling function with argument of size more than 8 bytes fails with
an error "That operation is not available on integers of more than 8 bytes.".
avr-gdb considers only 8 bytes (sizeof(long long)) in case of passing the
argument in registers. When the argument is of size more than 8 byte
then the utility function to extract bytes failed with the above error.

    gdb/
* avr-tdep.c (AVR_LAST_ARG_REGNUM): Define.
        (avr_push_dummy_call): Correct last needed argument register.
        Write MSB of argument into register and subsequent bytes into
        other registers in decreasing order.

gdb/ChangeLog
gdb/avr-tdep.c

index 7f37014..b84326c 100644 (file)
@@ -1,3 +1,10 @@
+2016-03-05  Pitchumani Sivanupandi  <pitchumani.s@atmel.com>
+
+       * avr-tdep.c (AVR_LAST_ARG_REGNUM): Define.
+       (avr_push_dummy_call): Correct last needed argument register.
+       Write MSB of argument into register and subsequent bytes into
+       other registers in decreasing order.
+
 2016-03-04  Yao Qi  <yao.qi@linaro.org>
 
        * arm-tdep.c (arm_record_vdata_transfer_insn): Simplify the
index 597cfb4..088fe51 100644 (file)
@@ -111,6 +111,7 @@ enum
 
   AVR_ARG1_REGNUM = 24,         /* Single byte argument */
   AVR_ARGN_REGNUM = 25,         /* Multi byte argments */
+  AVR_LAST_ARG_REGNUM = 8,      /* Last argument register */
 
   AVR_RET1_REGNUM = 24,         /* Single byte return value */
   AVR_RETN_REGNUM = 25,         /* Multi byte return value */
@@ -1298,23 +1299,24 @@ avr_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       const bfd_byte *contents = value_contents (arg);
       int len = TYPE_LENGTH (type);
 
-      /* Calculate the potential last register needed.  */
-      last_regnum = regnum - (len + (len & 1));
+      /* Calculate the potential last register needed.
+         E.g. For length 2, registers regnum and regnum-1 (say 25 and 24)
+         shall be used. So, last needed register will be regnum-1(24).  */
+      last_regnum = regnum - (len + (len & 1)) + 1;
 
       /* If there are registers available, use them.  Once we start putting
          stuff on the stack, all subsequent args go on stack.  */
-      if ((si == NULL) && (last_regnum >= 8))
+      if ((si == NULL) && (last_regnum >= AVR_LAST_ARG_REGNUM))
         {
-          ULONGEST val;
-
           /* Skip a register for odd length args.  */
           if (len & 1)
             regnum--;
 
-          val = extract_unsigned_integer (contents, len, byte_order);
+          /* Write MSB of argument into register and subsequent bytes in
+             decreasing register numbers.  */
           for (j = 0; j < len; j++)
             regcache_cooked_write_unsigned
-              (regcache, regnum--, val >> (8 * (len - j - 1)));
+              (regcache, regnum--, contents[len - j - 1]);
         }
       /* No registers available, push the args onto the stack.  */
       else