From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3297 invoked by alias); 14 May 2003 23:47:52 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 3118 invoked from network); 14 May 2003 23:47:49 -0000 Received: from unknown (HELO touchme.toronto.redhat.com) (207.219.125.105) by sources.redhat.com with SMTP; 14 May 2003 23:47:49 -0000 Received: from redhat.com (toocool.toronto.redhat.com [172.16.14.72]) by touchme.toronto.redhat.com (Postfix) with ESMTP id C0BDA800021 for ; Wed, 14 May 2003 19:47:42 -0400 (EDT) Message-ID: <3EC2D59E.60404@redhat.com> Date: Wed, 14 May 2003 23:47:00 -0000 From: "J. Johnston" Organization: Red Hat Inc. User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.1) Gecko/20020823 Netscape/7.0 X-Accept-Language: en-us, en MIME-Version: 1.0 To: gdb-patches@sources.redhat.com Subject: RFA: ia64 prologue skipping patch Content-Type: multipart/mixed; boundary="------------020303030501000200060404" X-SW-Source: 2003-05/txt/msg00231.txt.bz2 This is a multi-part message in MIME format. --------------020303030501000200060404 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1123 The attached patch revises the ia64 prologue skipping code. It does a number of things: 1. increases the number of instructions to look at in a prologue 2. allows looking in leaf functions 3. recognizes indirect input register references (one level only) 4. attempts to trust the lim_pc value Number 1 was increased to handle some testsuite cases where the number of parameters was quite high (e.g. 9 parameters). No tuning was involved. Number 4 has the biggest effect. The line table info is more accurate except in the case of optimized code. Ok to commit? -- Jeff J. 2003-05-14 Jeff Johnston * ia64-tdep.c: Increase max_skip_non_prologue_insns to 40. (examine_prologue): Support looking through leaf functions, knowing they start with mov r2,r12. Support skipping over indirect stores of the input registers. Upon hitting a non-nop branch instruction or predicated instruction, bail out by setting lim_pc to the current pc value in the loop. At the end, if the lim_pc value is still beyond our calculated value and we have trust_limit set, use the lim_pc value. --------------020303030501000200060404 Content-Type: text/plain; name="ia64-prologue.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ia64-prologue.patch" Content-length: 5928 Index: ia64-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/ia64-tdep.c,v retrieving revision 1.76 diff -u -p -r1.76 ia64-tdep.c --- ia64-tdep.c 13 May 2003 19:27:28 -0000 1.76 +++ ia64-tdep.c 14 May 2003 23:34:29 -0000 @@ -737,7 +737,7 @@ ia64_frame_saved_pc (struct frame_info * /* Limit the number of skipped non-prologue instructions since examining of the prologue is expensive. */ -static int max_skip_non_prologue_insns = 10; +static int max_skip_non_prologue_insns = 40; /* Given PC representing the starting address of a function, and LIM_PC which is the (sloppy) limit to which to scan when looking @@ -825,10 +825,13 @@ examine_prologue (CORE_ADDR pc, CORE_ADD CORE_ADDR spill_addr = 0; char instores[8]; char infpstores[8]; + char reg_contents[256]; int trust_limit; + int frameless = 0; memset (instores, 0, sizeof instores); memset (infpstores, 0, sizeof infpstores); + memset (reg_contents, 0, sizeof reg_contents); if (frame && !get_frame_saved_regs (frame)) { @@ -843,13 +846,14 @@ examine_prologue (CORE_ADDR pc, CORE_ADD return get_frame_extra_info (frame)->after_prologue; lim_pc = refine_prologue_limit (pc, lim_pc, &trust_limit); - - /* Must start with an alloc instruction */ next_pc = fetch_instruction (pc, &it, &instr); + + /* We want to check if we have a recognizable function start before we + look ahead for a prologue. */ if (pc < lim_pc && next_pc && it == M && ((instr & 0x1ee0000003fLL) == 0x02c00000000LL)) { - /* alloc */ + /* alloc - start of a regular function. */ int sor = (int) ((instr & 0x00078000000LL) >> 27); int sol = (int) ((instr & 0x00007f00000LL) >> 20); int sof = (int) ((instr & 0x000000fe000LL) >> 13); @@ -864,9 +868,35 @@ examine_prologue (CORE_ADDR pc, CORE_ADD } else { - pc = lim_pc; /* Frameless: We're done early. */ - if (trust_limit) - last_prologue_pc = lim_pc; + /* Look for a leaf routine. */ + if (pc < lim_pc && next_pc + && (it == I || it == M) + && ((instr & 0x1ee00000000LL) == 0x10800000000LL)) + { + /* adds rN = imm14, rM (or mov rN, rM when imm14 is 0) */ + int imm = (int) ((((instr & 0x01000000000LL) ? -1 : 0) << 13) + | ((instr & 0x001f8000000LL) >> 20) + | ((instr & 0x000000fe000LL) >> 13)); + int rM = (int) ((instr & 0x00007f00000LL) >> 20); + int rN = (int) ((instr & 0x00000001fc0LL) >> 6); + int qp = (int) (instr & 0x0000000003fLL); + if (qp == 0 && rN == 2 && imm == 0 && rM == 12 && fp_reg == 0) + { + /* mov r2, r12 - beginning of leaf routine */ + fp_reg = rN; + frameless = 1; + last_prologue_pc = next_pc; + } + } + + /* If we don't recognize a regular function or leaf routine, we are + done. */ + if (!fp_reg) + { + pc = lim_pc; + if (trust_limit) + last_prologue_pc = lim_pc; + } } /* Loop, looking for prologue instructions, keeping track of @@ -882,6 +912,8 @@ examine_prologue (CORE_ADDR pc, CORE_ADD { /* Exit loop upon hitting a non-nop branch instruction or a predicated instruction. */ + if (trust_limit) + lim_pc = pc; break; } else if (it == I && ((instr & 0x1eff8000000LL) == 0x00188000000LL)) @@ -941,6 +973,20 @@ examine_prologue (CORE_ADDR pc, CORE_ADD spill_reg = rN; last_prologue_pc = next_pc; } + else if (qp == 0 && rM >= 32 && rM < 40 && !instores[rM] && + rN < 256 && imm == 0) + { + /* mov rN, rM where rM is an input register */ + reg_contents[rN] = rM; + last_prologue_pc = next_pc; + } + else if (frameless && qp == 0 && rN == fp_reg && imm == 0 && + rM == 2) + { + /* mov r12, r2 */ + last_prologue_pc = next_pc; + break; + } } else if (it == M && ( ((instr & 0x1efc0000000LL) == 0x0eec0000000LL) @@ -1006,6 +1052,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADD int rN = (int) ((instr & 0x00007f00000LL) >> 20); int rM = (int) ((instr & 0x000000fe000LL) >> 13); int qp = (int) (instr & 0x0000000003fLL); + int indirect = rM < 256 ? reg_contents[rM] : 0; if (qp == 0 && rN == spill_reg && spill_addr != 0 && (rM == unat_save_reg || rM == pr_save_reg)) { @@ -1040,6 +1087,13 @@ examine_prologue (CORE_ADDR pc, CORE_ADD instores[rM-32] = 1; last_prologue_pc = next_pc; } + else if (qp == 0 && 32 <= indirect && indirect < 40 && + !instores[indirect-32]) + { + /* Allow an indirect store of an input register. */ + instores[indirect-32] = 1; + last_prologue_pc = next_pc; + } } else if (it == M && ((instr & 0x1ff08000000LL) == 0x08c00000000LL)) { @@ -1054,11 +1108,19 @@ examine_prologue (CORE_ADDR pc, CORE_ADD register is permitted. */ int rM = (int) ((instr & 0x000000fe000LL) >> 13); int qp = (int) (instr & 0x0000000003fLL); + int indirect = rM < 256 ? reg_contents[rM] : 0; if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32]) { instores[rM-32] = 1; last_prologue_pc = next_pc; } + else if (qp == 0 && 32 <= indirect && indirect < 40 && + !instores[indirect-32]) + { + /* Allow an indirect store of an input register. */ + instores[indirect-32] = 1; + last_prologue_pc = next_pc; + } } else if (it == M && ((instr & 0x1ff88000000LL) == 0x0cc80000000LL)) { @@ -1146,6 +1208,10 @@ examine_prologue (CORE_ADDR pc, CORE_ADD get_frame_extra_info (frame)->mem_stack_frame_size = mem_stack_frame_size; get_frame_extra_info (frame)->fp_reg = fp_reg; } + + /* Try and trust the lim_pc value whenever possible. */ + if (trust_limit && lim_pc >= last_prologue_pc) + return lim_pc; return last_prologue_pc; } --------------020303030501000200060404--