From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17864 invoked by alias); 20 Nov 2007 12:00:50 -0000 Received: (qmail 17856 invoked by uid 22791); 20 Nov 2007 12:00:49 -0000 X-Spam-Check-By: sourceware.org Received: from dmz.mips-uk.com (HELO dmz.mips-uk.com) (194.74.144.194) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 20 Nov 2007 12:00:45 +0000 Received: from internal-mx1 ([192.168.192.240] helo=ukservices1.mips.com) by dmz.mips-uk.com with esmtp (Exim 3.35 #1 (Debian)) id 1IuRmU-0004qo-00; Tue, 20 Nov 2007 12:00:42 +0000 Received: from perivale.mips.com ([192.168.192.200]) by ukservices1.mips.com with esmtp (Exim 3.36 #1 (Debian)) id 1IuRmM-0005W0-00; Tue, 20 Nov 2007 12:00:34 +0000 Received: from macro (helo=localhost) by perivale.mips.com with local-esmtp (Exim 4.63) (envelope-from ) id 1IuRmM-0008QA-I0; Tue, 20 Nov 2007 12:00:34 +0000 Date: Tue, 20 Nov 2007 12:00:00 -0000 From: "Maciej W. Rozycki" To: gdb-patches@sourceware.org cc: David Ung , "Maciej W. Rozycki" Subject: mips-tdep.c: Handle the MIPS16e SAVE instruction Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-MIPS-Technologies-UK-MailScanner: Found to be clean X-MIPS-Technologies-UK-MailScanner-From: macro@mips.com Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-11/txt/msg00375.txt.bz2 Hello, The change below adds handling of the MIPS16e SAVE instruction, fixing a few regressions in the GDB test suite when run for MIPS16: FAIL: gdb.base/nodebug.exp: backtrace from inner in nodebug.exp FAIL: gdb.base/nodebug.exp: backtrace from middle in nodebug.exp KFAIL: gdb.base/gdb1250.exp: backtrace from abort (PRMS: gdb/1250) Tested for using the mipsisa32-sde-elf target, with the mips-sim-sde32/-mips16/-EB and mips-sim-sde32/-mips16/-EL boards, fixing the three regressions. 2007-11-20 David Ung Maciej W. Rozycki * mips-tdep.c (mips16_scan_prologue): Handle the MIPS16e SAVE instruction. OK to apply? Maciej 12920.diff Index: gdb/src/gdb/mips-tdep.c =================================================================== --- gdb.orig/src/gdb/mips-tdep.c 2007-11-16 11:21:26.000000000 +0000 +++ gdb/src/gdb/mips-tdep.c 2007-11-20 09:57:28.000000000 +0000 @@ -1500,6 +1500,7 @@ unsigned short prev_inst = 0; /* saved copy of previous instruction */ unsigned inst = 0; /* current instruction */ unsigned entry_inst = 0; /* the entry instruction */ + unsigned save_inst = 0; /* the save instruction */ int reg, offset; int extend_bytes = 0; @@ -1603,6 +1604,12 @@ else if ((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700) /* entry */ entry_inst = inst; /* save for later processing */ + else if ((inst & 0xff80) == 0x6480) /* save */ + { + save_inst = inst; /* save for later processing */ + if (prev_extend_bytes) /* extend */ + save_inst |= prev_inst << 16; + } else if ((inst & 0xf800) == 0x1800) /* jal(x) */ cur_pc += MIPS_INSN16_SIZE; /* 32-bit instruction */ else if ((inst & 0xff1c) == 0x6704) /* move reg,$a0-$a3 */ @@ -1661,6 +1668,101 @@ } } + /* The SAVE instruction is similar to ENTRY, except that defined by the + MIPS16e ASE of the MIPS Architecture. Unlike with ENTRY though, the + size of the frame is specified as an immediate field of instruction + and an extended variation exists which lets additional registers and + frame space to be specified. The instruction always treats registers + as 32-bit so its usefulness for 64-bit ABIs is questionable. */ + if (save_inst != 0 && mips_abi_regsize (gdbarch) == 4) + { + static int args_table[16] = { + 0, 0, 0, 0, 1, 1, 1, 1, + 2, 2, 2, 0, 3, 3, 4, -1, + }; + static int astatic_table[16] = { + 0, 1, 2, 3, 0, 1, 2, 3, + 0, 1, 2, 4, 0, 1, 0, -1, + }; + int aregs = (save_inst >> 16) & 0xf; + int xsregs = (save_inst >> 24) & 0x7; + int args = args_table[aregs]; + int astatic = astatic_table[aregs]; + long frame_size; + + if (args < 0) + { + warning (_("Invalid number of argument registers encoded in SAVE.")); + args = 0; + } + if (astatic < 0) + { + warning (_("Invalid number of static registers encoded in SAVE.")); + astatic = 0; + } + + /* For standard SAVE the frame size of 0 means 128. */ + frame_size = ((save_inst >> 16) & 0xf0) | (save_inst & 0xf); + if (frame_size == 0 && (save_inst >> 16) == 0) + frame_size = 16; + frame_size *= 8; + frame_offset += frame_size; + + /* Now we can calculate what the SP must have been at the + start of the function prologue. */ + sp += frame_offset; + + /* Check if A0-A3 were saved in the caller's argument save area. */ + for (reg = MIPS_A0_REGNUM, offset = 0; reg < args + 4; reg++) + { + set_reg_offset (this_cache, reg, sp + offset); + offset += mips_abi_regsize (gdbarch); + } + + offset = -4; + + /* Check if the RA register was pushed on the stack. */ + if (save_inst & 0x40) + { + set_reg_offset (this_cache, MIPS_RA_REGNUM, sp + offset); + offset -= mips_abi_regsize (gdbarch); + } + + /* Check if the S8 register was pushed on the stack. */ + if (xsregs > 6) + { + set_reg_offset (this_cache, 30, sp + offset); + offset -= mips_abi_regsize (gdbarch); + xsregs--; + } + /* Check if S2-S7 were pushed on the stack. */ + for (reg = 18 + xsregs - 1; reg > 18 - 1; reg--) + { + set_reg_offset (this_cache, reg, sp + offset); + offset -= mips_abi_regsize (gdbarch); + } + + /* Check if the S1 register was pushed on the stack. */ + if (save_inst & 0x10) + { + set_reg_offset (this_cache, 17, sp + offset); + offset -= mips_abi_regsize (gdbarch); + } + /* Check if the S0 register was pushed on the stack. */ + if (save_inst & 0x20) + { + set_reg_offset (this_cache, 16, sp + offset); + offset -= mips_abi_regsize (gdbarch); + } + + /* Check if A0-A3 were pushed on the stack. */ + for (reg = MIPS_A0_REGNUM + 3; reg > MIPS_A0_REGNUM + 3 - astatic; reg--) + { + set_reg_offset (this_cache, reg, sp + offset); + offset -= mips_abi_regsize (gdbarch); + } + } + if (this_cache != NULL) { this_cache->base =