[avr] Fix argument passing for call

Message ID 20160301110937.GA3892@CHELT0346
State New, archived
Headers

Commit Message

Pitchumani Sivanupandi March 1, 2016, 11:09 a.m. UTC
  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.

Attached a patch fix this issue. This patch includes the fix discussed
here: https://sourceware.org/ml/gdb-patches/2016-02/msg00884.html
(Both fixes are in same function and the earlier is not committed)

Ran the tests for avr-gdb with internal simulators. No new regressions.

If ok, could someone commit please? I do not have commit access.

Regards,
Pitchumani

gdb/ChangeLog

2016-03-01  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.
  

Comments

Denis Chertykov March 5, 2016, 12:20 p.m. UTC | #1
2016-03-01 14:09 GMT+03:00 Pitchumani Sivanupandi <pitchumani.s@atmel.com>:
> 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.
>
> Attached a patch fix this issue. This patch includes the fix discussed
> here: https://sourceware.org/ml/gdb-patches/2016-02/msg00884.html
> (Both fixes are in same function and the earlier is not committed)
>
> Ran the tests for avr-gdb with internal simulators. No new regressions.
>
> If ok, could someone commit please? I do not have commit access.
>
> Regards,
> Pitchumani
>
> gdb/ChangeLog
>
> 2016-03-01  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.

Committed.

Denis.
  

Patch

diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c
index 597cfb4..088fe51 100644
--- a/gdb/avr-tdep.c
+++ b/gdb/avr-tdep.c
@@ -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