This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [patch, avr] Fix incorrect argument register for push dummy call
- From: Luis Machado <lgustavo at codesourcery dot com>
- To: Pitchumani Sivanupandi <pitchumani dot s at atmel dot com>, <gdb-patches at sourceware dot org>
- Date: Fri, 26 Feb 2016 11:15:35 -0300
- Subject: Re: [patch, avr] Fix incorrect argument register for push dummy call
- Authentication-results: sourceware.org; auth=none
- References: <20160225123448 dot GA10608 at CHELT0346>
- Reply-to: Luis Machado <lgustavo at codesourcery dot com>
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;