[patch, avr] Fix incorrect argument register for push dummy call
Luis Machado
lgustavo@codesourcery.com
Fri Feb 26 14:15:00 GMT 2016
Hi,
On 02/25/2016 09:34 AM, Pitchumani Sivanupandi wrote:
> There are few failures for avr-gdb in callfuncs.exp. These failures are
> due to the incorrect argument passing in case of push dummy call. The
> last argument register is calculated incorrectly that caused this issue.
>
> Attached patch fixes the calculation so that the push dummy call aligns
> with the code generated by avr-gcc.
>
> No new regressions found when tested with internal simulator.
>
> If ok, could someone commit please?
>
> Regards,
> Pitchumani
>
> gdb/ChangeLog
>
> 2016-02-25 Pitchumani Sivanupandi<pitchumani.s@atmel.com>
>
> * avr-tdep.c (AVR_LAST_ARG_REGNUM): Define.
> (avr_push_dummy_call): Correct last needed argument register.
>
>
> avr-last-argument-register-fix.patch
>
>
> diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c
> index 597cfb4..18ecfe4 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,12 +1299,14 @@ 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)
Is that how the code works? It seems a bit confusing, because we want to
start in even-aligned registers, so we'd use r25:r24, r23:r22 etc.
So last_regnum always ends up pointing at an odd-numbered register, so
the code can decrement the odd-numbered register if needed (in case we
have data of length 1/3/...).
/* Skip a register for odd length args. */
if (len & 1)
regnum--;
> + shall be used. So, last needed register will be regnum-1(24). */
> + last_regnum = regnum - (len + (len & 1)) + 1;
>
Isn't this going to be incorrect for, say, data of length 3?
last_regnum = 25 - (3 + (3 & 1)) + 1 -> 25 - (3 + 1) + 1 -> 22
But it should've been 21, because data would occupy registers 25:24 and
23:22 and then we'd need an even-aligned register to start with?
> /* 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;
>
More information about the Gdb-patches
mailing list