From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19522 invoked by alias); 15 Sep 2003 19:39:03 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 19513 invoked from network); 15 Sep 2003 19:39:01 -0000 Received: from unknown (HELO hydra.ubicom.com) (4.20.168.98) by sources.redhat.com with SMTP; 15 Sep 2003 19:39:01 -0000 Received: FROM fenway.scenix.com BY hydra.ubicom.com ; Mon Sep 15 12:38:59 2003 -0700 Received: from nkelseyxp2 (NKELSEY-XP2 [192.168.1.187]) by fenway.scenix.com with SMTP (Microsoft Exchange Internet Mail Service Version 5.5.2656.59) id STJ25DAX; Mon, 15 Sep 2003 12:38:59 -0700 Message-ID: <03a701c37bc1$037ca1f0$0502a8c0@scenix.com> From: "Jafa" To: Subject: ip2k port Date: Mon, 15 Sep 2003 19:39:00 -0000 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_03A4_01C37B86.5705FC30" X-Priority: 3 X-MSMail-Priority: Normal X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165 X-SW-Source: 2003-09/txt/msg00196.txt.bz2 This is a multi-part message in MIME format. ------=_NextPart_000_03A4_01C37B86.5705FC30 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-length: 358 Hi all, Our internal QA has closed all remaining bugs that were files against the ip2k port of GDB so I would like to get a first-pass review, heading towards formally submitting the port. One issue is the IGNORE_HELPER_CALL (used by the MIPS port as well) which is currently a define rather a registerable function. I welcome any feedback. Thanks Nick ------=_NextPart_000_03A4_01C37B86.5705FC30 Content-Type: application/octet-stream; name="ip2k-tdep.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="ip2k-tdep.c" Content-length: 41523 /* Target-dependent code for Ubicom IP2K, for GDB.=0A= Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.=0A= =0A= This file is part of GDB.=0A= =0A= This program is free software; you can redistribute it and/or modify=0A= it under the terms of the GNU General Public License as published by=0A= the Free Software Foundation; either version 2 of the License, or=0A= (at your option) any later version.=0A= =0A= This program is distributed in the hope that it will be useful,=0A= but WITHOUT ANY WARRANTY; without even the implied warranty of=0A= MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the=0A= GNU General Public License for more details.=0A= =0A= You should have received a copy of the GNU General Public License=0A= along with this program; if not, write to the Free Software=0A= Foundation, Inc., 59 Temple Place - Suite 330,=0A= Boston, MA 02111-1307, USA. */=0A= =0A= #include "defs.h"=0A= #include "frame.h"=0A= #include "frame-unwind.h"=0A= #include "frame-base.h"=0A= #include "trad-frame.h"=0A= #include "gdbcore.h"=0A= #include "inferior.h"=0A= #include "symfile.h"=0A= #include "arch-utils.h"=0A= #include "regcache.h"=0A= #include "gdb_string.h"=0A= =0A= /* Threads. */=0A= #define IP2K_ISR_THREAD 1=0A= #define IP2K_MAIN_THREAD 2=0A= #define IP2K_VM_THREAD 3=0A= =0A= /* Registers. */=0A= #define IP2K_NUM_NATIVE_REGS 256=0A= #define IP2K_NUM_PSEUDO_REGS 5=0A= =0A= #define IP2K_IPH_REGNUM 0x0004=0A= #define IP2K_IPL_REGNUM 0x0005=0A= #define IP2K_SPH_REGNUM 0x0006=0A= #define IP2K_SPL_REGNUM 0x0007=0A= #define IP2K_PCH_REGNUM 0x0008=0A= #define IP2K_PCL_REGNUM 0x0009=0A= #define IP2K_DPH_REGNUM 0x000C=0A= #define IP2K_DPL_REGNUM 0x000D=0A= #define IP2K_CALLH_REGNUM 0x007E=0A= #define IP2K_CALLL_REGNUM 0x007F=0A= #define IP2K_RETVAL_REGNUM 0x0080=0A= =0A= #define IP2K_PC_REGNUM (IP2K_NUM_NATIVE_REGS + 0)=0A= #define IP2K_SP_REGNUM (IP2K_NUM_NATIVE_REGS + 1)=0A= #define IP2K_DP_REGNUM (IP2K_NUM_NATIVE_REGS + 2)=0A= #define IP2K_IP_REGNUM (IP2K_NUM_NATIVE_REGS + 3)=0A= #define IP2K_CALL_REGNUM (IP2K_NUM_NATIVE_REGS + 4)=0A= =0A= char *ip2k_register_names[] =3D=0A= {=0A= " ", " ", "addrsel", "addrx",=0A= "iph", "ipl", "sph", "spl",=0A= "pch", "pcl", "wreg", "status",=0A= "dph", "dpl", "spdreg", "mulh",=0A= =0A= "addrh", "addrl", "datah", "datal",=0A= "intvech", "intvecl", "intspd", "intf",=0A= "inte", "inted", "fcfg", "tctrl",=0A= "xcfg", "emcfg", "ipch", "ipcl",=0A= =0A= "rain", "raout", "radir", "lfsrh",=0A= "rbin", "rbout", "rbdir", "lfsrl",=0A= "rcin", "rcout", "rcdir", "lfsra",=0A= "rdin", "rdout", "rddir", " ",=0A= =0A= "rein", "reout", "redir", " ",=0A= "rfin", "rfout", "rfdir", " ",=0A= " ", "rgout", "rgdir", " ",=0A= " ", " ", " ", " ",=0A= =0A= "rttmr", "rtcfg", "t0tmr", "t0cfg",=0A= "t1cnth", "t1cntl", "t1cap1h", "t1cap1l",=0A= "t1cap2h", "t1cap2l", "t1cmp1h", "t1cmp1l",=0A= "t1cfg1h", "t1cfg1l", "t1cfg2h", "t1cfg2l",=0A= =0A= "adch", "adcl", "adccfg", "adctmr",=0A= "t2cnth", "t2cntl", "t2cap1h", "t2cap1l",=0A= "t2cap2h", "t2cap2l", "t2cmp1h", "t2cmp1l",=0A= "t2cfg1h", "t2cfg1l", "t2cfg2h", "t2cfg2l",=0A= =0A= "s1tmrh", "s1tmrl", "s1tbufh", "s1tbufl",=0A= "s1tcfg", "s1rcnt", "s1rbufh", "s1rbufl",=0A= "s1rcfg", "s1rsync", "s1intf", "s1inte",=0A= "s1mode", "s1smask", "pspcfg", "cmpcfg",=0A= =0A= "s2tmrh", "s2tmrl", "s2tbufh", "s2tbufl",=0A= "s2tcfg", "s2rcnt", "s2rbufh", "s2rbufl",=0A= "s2rcfg", "s2rsync", "s2intf", "s2inte",=0A= "s2mode", "s2smask", "callh", "calll",=0A= =0A= "r80", "r81", "r82", "r83", "r84", "r85", "r86", "r87",=0A= "r88", "r89", "r8A", "r8B", "r8C", "r8D", "r8E", "r8F",=0A= "r90", "r91", "r92", "r93", "r94", "r95", "r96", "r97",=0A= "r98", "r99", "r9A", "r9B", "r9C", "r9D", "r9E", "r9F",=0A= =0A= "rA0", "rA1", "rA2", "rA3", "rA4", "rA5", "rA6", "rA7",=0A= "rA8", "rA9", "rAA", "rAB", "rAC", "rAD", "rAE", "rAF",=0A= "rB0", "rB1", "rB2", "rB3", "rB4", "rB5", "rB6", "rB7",=0A= "rB8", "rB9", "rBA", "rBB", "rBC", "rBD", "rBE", "rBF",=0A= =0A= "rC0", "rC1", "rC2", "rC3", "rC4", "rC5", "rC6", "rC7",=0A= "rC8", "rC9", "rCA", "rCB", "rCC", "rCD", "rCE", "rCF",=0A= "rD0", "rD1", "rD2", "rD3", "rD4", "rD5", "rD6", "rD7",=0A= "rD8", "rD9", "rDA", "rDB", "rDC", "rDD", "rDE", "rDF",=0A= =0A= "rE0", "rE1", "rE2", "rE3", "rE4", "rE5", "rE6", "rE7",=0A= "rE8", "rE9", "rEA", "rEB", "rEC", "rED", "rEE", "rEF",=0A= "rF0", "rF1", "rF2", "rF3", "rF4", "rF5", "rF6", "rF7",=0A= "rF8", "rF9", "rFA", "rFB", "rFC", "rFD", "rFE", "rFF",=0A= =0A= "pc", "sp", "dp", "ip", "call"=0A= };=0A= =0A= enum ip2k_func_type=0A= {=0A= ip2k_func_type_normal =3D 0,=0A= ip2k_func_type_libgcc_stub,=0A= ip2k_func_type_libgcc_epilogue,=0A= ip2k_func_type_libgcc_indcall=0A= };=0A= =0A= /* Debug. */=0A= #define DEBUG_NONE 0=0A= #define DEBUG_NORMAL 1=0A= #define DEBUG_EXTRA 2=0A= #define DEBUG_MAX 3=0A= #define DEBUG_FRAME DEBUG_MAX=0A= static int debug_level =3D DEBUG_NORMAL;=0A= =0A= /* Frame info. */=0A= struct ip2k_unwind_cache=0A= {=0A= CORE_ADDR entry_pc;=0A= CORE_ADDR current_pc;=0A= CORE_ADDR return_pc;=0A= CORE_ADDR entry_sp;=0A= CORE_ADDR normal_sp;=0A= CORE_ADDR current_sp;=0A= /* Table indicating the location of each and every register. */=0A= struct trad_frame_saved_reg *saved_regs;=0A= };=0A= =0A= /* Prologue instructions - return address.=0A= push CALLL (0x447f)=0A= push CALLH (0x447e) */=0A= static unsigned char ip2k_call_prologue_insns[] =3D { 0x44, 0x7f, 0x44, 0x7= e };=0A= =0A= /* Prologue instructions - frame pointer.=0A= push $fe (0x44fe)=0A= mov W,SPL (0x2007)=0A= mov $fe,W (0x02fe)=0A= mov W,SPH (0x2006)=0A= push $fd (0x44fd)=0A= mov $fd,W (0x02fd) */=0A= static unsigned char ip2k_fp_prologue_insns[] =3D=0A= { 0x44, 0xfe, 0x20, 0x07, 0x02, 0xfe, 0x20, 0x06, 0x44, 0xfd, 0x02, 0xfd = };=0A= =0A= /* Prologue instructions - local variables (single).=0A= dec spl (0x0e07) */=0A= static unsigned char ip2k_local_1_prologue_insns[] =3D { 0x0e, 0x07 };=0A= =0A= /* Prologue - local variables (multiple).=0A= mov W,#$xx (0x7cxx)=0A= sub SPL,W (0x0a07) */=0A= static unsigned char ip2k_local_n_prologue_insns[] =3D=0A= { 0x7c, 0x00, 0x0a, 0x07 };=0A= =0A= =0A= /* ip2k_try_pc_function_start. */=0A= static CORE_ADDR=0A= ip2k_try_pc_function_start (CORE_ADDR pc)=0A= {=0A= CORE_ADDR temp =3D get_pc_function_start (pc);=0A= if (temp !=3D 0)=0A= return temp;=0A= =0A= printf_filtered ("warning: unable to find start of function of pc: 0x%08l= x\n", pc);=0A= return pc;=0A= }=0A= =0A= /* ip2k_dptr_to_addr. */=0A= static CORE_ADDR=0A= ip2k_dptr_to_addr (CORE_ADDR addr)=0A= {=0A= if (addr =3D=3D 0)=0A= return 0;=0A= =0A= if (addr & 0xFFFF0000)=0A= {=0A= warning ("invalid raw data pointer: 0x%08lx", addr);=0A= return 0;=0A= }=0A= if (ptid_get_pid (inferior_ptid) =3D=3D IP2K_VM_THREAD)=0A= return (0x01400000 | (addr & 0x0000FFFF));=0A= else=0A= return (0x01000000 | (addr & 0x0000FFFF));=0A= }=0A= =0A= /* ip2k_iptr_to_addr. */=0A= static CORE_ADDR=0A= ip2k_iptr_to_addr (CORE_ADDR addr)=0A= {=0A= /* Note: 0 is a valid address! */=0A= if (addr & 0xFFFF0000)=0A= {=0A= warning ("invalid raw instruction pointer: 0x%08lx", addr);=0A= return 0;=0A= }=0A= =0A= if (ptid_get_pid (inferior_ptid) =3D=3D IP2K_VM_THREAD)=0A= return (0x02400000 | ((addr & 0x0000FFFF) << 1));=0A= else=0A= return (0x02000000 | ((addr & 0x0000FFFF) << 1));=0A= }=0A= =0A= /* ip2k_addr_to_dptr. */=0A= static CORE_ADDR=0A= ip2k_addr_to_dptr (CORE_ADDR addr)=0A= {=0A= if (addr =3D=3D 0)=0A= return 0;=0A= =0A= if ((addr & 0xFF000000) !=3D 0x01000000)=0A= {=0A= warning ("invalid data pointer: 0x%08lx", addr);=0A= return 0;=0A= }=0A= =0A= return (addr & 0x0000FFFF);=0A= }=0A= =0A= /* ip2k_addr_to_iptr. */=0A= static CORE_ADDR=0A= ip2k_addr_to_iptr (CORE_ADDR addr)=0A= {=0A= if (addr =3D=3D 0)=0A= return 0;=0A= =0A= if ((addr & 0xFF000000) !=3D 0x02000000)=0A= {=0A= warning ("invalid instruction pointer: 0x%08lx", addr);=0A= return 0;=0A= }=0A= =0A= return ((addr >> 1) & 0x0000FFFF);=0A= }=0A= =0A= /* ip2k_pointer_to_address. */=0A= static CORE_ADDR=0A= ip2k_pointer_to_address (struct type *type, const void *buf)=0A= {=0A= enum type_code target =3D TYPE_CODE (TYPE_TARGET_TYPE (type));=0A= CORE_ADDR addr =3D extract_unsigned_integer (buf, TYPE_LENGTH (type));=0A= =0A= if (debug_level >=3D DEBUG_MAX)=0A= printf_filtered ("ip2k_pointer_to_address\n");=0A= =0A= if ((target =3D=3D TYPE_CODE_FUNC) || (target =3D=3D TYPE_CODE_METHOD))= =0A= addr =3D ip2k_iptr_to_addr (addr);=0A= else=0A= addr =3D ip2k_dptr_to_addr (addr);=0A= =0A= return addr;=0A= }=0A= =0A= /* ip2k_address_to_pointer. */=0A= static void=0A= ip2k_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr)=0A= {=0A= enum type_code target =3D TYPE_CODE (TYPE_TARGET_TYPE (type));=0A= =0A= if (debug_level >=3D DEBUG_MAX)=0A= printf_filtered ("ip2k_address_to_pointer\n");=0A= =0A= if ((target =3D=3D TYPE_CODE_FUNC) || (target =3D=3D TYPE_CODE_METHOD))= =0A= addr =3D ip2k_addr_to_iptr (addr);=0A= else=0A= addr =3D ip2k_addr_to_dptr (addr);=0A= =0A= store_unsigned_integer (buf, TYPE_LENGTH (type), addr);=0A= }=0A= =0A= /* ip2k_read_pc. */=0A= static CORE_ADDR=0A= ip2k_read_pc (ptid_t ptid)=0A= {=0A= ptid_t save_ptid;=0A= CORE_ADDR val;=0A= =0A= save_ptid =3D inferior_ptid;=0A= inferior_ptid =3D ptid;=0A= val =3D read_register (IP2K_PC_REGNUM);=0A= inferior_ptid =3D save_ptid;=0A= =0A= if (debug_level >=3D DEBUG_MAX)=0A= printf_filtered ("ip2k_read_pc (0x%08lx)\n", ip2k_iptr_to_addr (val));= =0A= =0A= return ip2k_iptr_to_addr (val);=0A= }=0A= =0A= /* ip2k_write_pc. */=0A= static void=0A= ip2k_write_pc (CORE_ADDR val, ptid_t ptid)=0A= {=0A= ptid_t save_ptid;=0A= =0A= if (debug_level >=3D DEBUG_MAX)=0A= printf_filtered ("ip2k_write_pc\n");=0A= =0A= save_ptid =3D inferior_ptid;=0A= inferior_ptid =3D ptid;=0A= write_register (IP2K_PC_REGNUM, ip2k_addr_to_iptr (val));=0A= inferior_ptid =3D save_ptid;=0A= }=0A= =0A= /* ip2k_unwind_pc. */=0A= static CORE_ADDR=0A= ip2k_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)=0A= {=0A= ULONGEST pc;=0A= frame_unwind_unsigned_register (next_frame, IP2K_PC_REGNUM, &pc);=0A= return ip2k_iptr_to_addr (pc);=0A= }=0A= =0A= /* ip2k_unwind_sp. */=0A= static CORE_ADDR=0A= ip2k_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)=0A= {=0A= ULONGEST sp;=0A= frame_unwind_unsigned_register (next_frame, IP2K_SP_REGNUM, &sp);=0A= return ip2k_dptr_to_addr (sp);=0A= }=0A= =0A= /* ip2k_register_name.=0A= Given a register index, return the name of the corresponding register. = */=0A= static const char *=0A= ip2k_register_name (int regnum)=0A= {=0A= if ((regnum < 0) || (regnum >=3D IP2K_NUM_NATIVE_REGS + IP2K_NUM_PSEUDO_R= EGS))=0A= {=0A= warning ("internal error: ip2k_register_name: invalid register: 0x%08= x", regnum);=0A= return (NULL);=0A= }=0A= =0A= return (ip2k_register_names[regnum]);=0A= }=0A= =0A= /* Return the GDB type object for the "standard" data type=0A= of data in register N. */=0A= static struct type *=0A= ip2k_register_type (struct gdbarch *gdbarch, int reg_nr)=0A= {=0A= switch (reg_nr)=0A= {=0A= case IP2K_SP_REGNUM:=0A= case IP2K_DP_REGNUM:=0A= case IP2K_IP_REGNUM:=0A= return builtin_type_void_data_ptr;=0A= case IP2K_PC_REGNUM:=0A= case IP2K_CALL_REGNUM:=0A= return builtin_type_void_func_ptr;=0A= default:=0A= return builtin_type_uint8;=0A= }=0A= }=0A= =0A= /* ip2k_get_function_type_internal. */=0A= static inline enum ip2k_func_type=0A= ip2k_get_function_type_internal (char *name)=0A= {=0A= if (!strstr (name, "libgcc"))=0A= return ip2k_func_type_normal;=0A= =0A= if (strstr (name, "indcall"))=0A= return ip2k_func_type_libgcc_indcall;=0A= =0A= if (strstr (name, "add_sp"))=0A= return ip2k_func_type_libgcc_epilogue;=0A= =0A= return ip2k_func_type_libgcc_stub;=0A= }=0A= =0A= /* ip2k_get_function_type. */=0A= static enum ip2k_func_type=0A= ip2k_get_function_type (CORE_ADDR pc, char *name)=0A= {=0A= enum ip2k_func_type type;=0A= =0A= if (!name)=0A= find_pc_partial_function (pc, &name, NULL, NULL);=0A= =20=20=0A= if (name)=0A= type =3D ip2k_get_function_type_internal(name);=0A= else=0A= type =3D ip2k_func_type_normal;=0A= =0A= if (debug_level >=3D DEBUG_FRAME)=0A= {=0A= char *typestr;=0A= switch (type)=0A= {=0A= case ip2k_func_type_normal:=0A= typestr =3D "normal";=0A= break;=0A= case ip2k_func_type_libgcc_stub:=0A= typestr =3D "libgcc stub";=0A= break;=0A= case ip2k_func_type_libgcc_epilogue:=0A= typestr =3D "libgcc epilogue";=0A= break;=0A= case ip2k_func_type_libgcc_indcall:=0A= typestr =3D "libgcc indcall";=0A= break;=0A= default:=0A= typestr =3D "internal error!";=0A= break;=0A= }=0A= printf_filtered("ip2k_get_function_type: %s (%s)\n", typestr, name);= =0A= }=0A= =0A= return type;=0A= }=0A= =0A= /* ip2k_pseudo_register_read. */=0A= static void=0A= ip2k_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcac= he,=0A= int regnum, void *buf)=0A= {=0A= unsigned char *data =3D (unsigned char *) buf;=0A= =0A= if (debug_level >=3D DEBUG_MAX)=0A= printf_filtered ("ip2k_pseudo_register_read: %04x\n", regnum);=0A= =0A= switch (regnum)=0A= {=0A= case IP2K_PC_REGNUM:=0A= regcache_raw_read (regcache, IP2K_PCH_REGNUM, data++);=0A= regcache_raw_read (regcache, IP2K_PCL_REGNUM, data++);=0A= break;=0A= case IP2K_SP_REGNUM:=0A= regcache_raw_read (regcache, IP2K_SPH_REGNUM, data++);=0A= regcache_raw_read (regcache, IP2K_SPL_REGNUM, data++);=0A= break;=0A= case IP2K_DP_REGNUM:=0A= regcache_raw_read (regcache, IP2K_DPH_REGNUM, data++);=0A= regcache_raw_read (regcache, IP2K_DPL_REGNUM, data++);=0A= break;=0A= case IP2K_IP_REGNUM:=0A= regcache_raw_read (regcache, IP2K_IPH_REGNUM, data++);=0A= regcache_raw_read (regcache, IP2K_IPL_REGNUM, data++);=0A= break;=0A= case IP2K_CALL_REGNUM:=0A= regcache_raw_read (regcache, IP2K_CALLH_REGNUM, data++);=0A= regcache_raw_read (regcache, IP2K_CALLL_REGNUM, data++);=0A= break;=0A= default:=0A= warning ("internal error: ip2k_pseudo_register_read: invalid register= : 0x%08x", regnum);=0A= }=0A= }=0A= =0A= /* ip2k_pseudo_register_write. */=0A= static void=0A= ip2k_pseudo_register_write (struct gdbarch *gdbarch,=0A= struct regcache *regcache, int regnum,=0A= const void *buf)=0A= {=0A= unsigned char *data =3D (unsigned char *) buf;=0A= =0A= if (debug_level >=3D DEBUG_MAX)=0A= printf_filtered ("ip2k_pseudo_register_write\n");=0A= =0A= switch (regnum)=0A= {=0A= case IP2K_PC_REGNUM:=0A= regcache_raw_write (regcache, IP2K_PCH_REGNUM, data++);=0A= regcache_raw_write (regcache, IP2K_PCL_REGNUM, data++);=0A= break;=0A= case IP2K_SP_REGNUM:=0A= regcache_raw_write (regcache, IP2K_SPH_REGNUM, data++);=0A= regcache_raw_write (regcache, IP2K_SPL_REGNUM, data++);=0A= break;=0A= case IP2K_DP_REGNUM:=0A= regcache_raw_write (regcache, IP2K_DPH_REGNUM, data++);=0A= regcache_raw_write (regcache, IP2K_DPL_REGNUM, data++);=0A= break;=0A= case IP2K_IP_REGNUM:=0A= regcache_raw_write (regcache, IP2K_IPH_REGNUM, data++);=0A= regcache_raw_write (regcache, IP2K_IPL_REGNUM, data++);=0A= break;=0A= case IP2K_CALL_REGNUM:=0A= regcache_raw_write (regcache, IP2K_CALLH_REGNUM, data++);=0A= regcache_raw_write (regcache, IP2K_CALLL_REGNUM, data++);=0A= break;=0A= default:=0A= warning ("internal error: ip2k_pseudo_register_write: invalid registe= r: 0x%08x", regnum);=0A= }=0A= }=0A= =0A= /* ip2k_extract_return_value.=0A= Extract from an array REGBUF containing the (raw) register state=0A= a function return value of type TYPE, and copy that, in virtual format,= =0A= into VALBUF. */=0A= static void=0A= ip2k_extract_return_value (struct type *type, struct regcache *regcache,=0A= void *valbuf)=0A= {=0A= int type_len, i;=0A= =0A= if (debug_level >=3D DEBUG_MAX)=0A= printf_filtered ("ip2k_extract_return_value\n");=0A= =0A= type_len =3D TYPE_LENGTH (type);=0A= if (type_len > 8)=0A= {=0A= printf_unfiltered ("Error: Return values longer than 8 bytes are not = supported.\n");=0A= memset (valbuf, 0, type_len);=0A= return;=0A= }=0A= =0A= if (type_len =3D=3D 1)=0A= regcache_raw_read (regcache, IP2K_RETVAL_REGNUM + 1, valbuf);=0A= else=0A= {=0A= for (i =3D 0; i < type_len; i++)=0A= {=0A= regcache_raw_read (regcache, IP2K_RETVAL_REGNUM + i,=0A= ((char *) valbuf)++);=0A= }=0A= }=0A= }=0A= =0A= /* ip2k_store_return_value.=0A= Write into appropriate registers a function return value=0A= of type TYPE, given in virtual format. */=0A= static void=0A= ip2k_store_return_value (struct type *type, struct regcache *regcache,=0A= const void *valbuf)=0A= {=0A= int type_len, i;=0A= =0A= if (debug_level >=3D DEBUG_MAX)=0A= printf_filtered ("ip2k_store_return_value\n");=0A= =0A= type_len =3D TYPE_LENGTH (type);=0A= if (type_len > 8)=0A= {=0A= printf_unfiltered ("Error: Return values longer than 8 bytes are not = supported.\n");=0A= return;=0A= }=0A= =0A= if (type_len =3D=3D 1)=0A= {=0A= unsigned char zero =3D 0;=0A= regcache_raw_write (regcache, IP2K_RETVAL_REGNUM + 0, &zero);=0A= regcache_raw_write (regcache, IP2K_RETVAL_REGNUM + 1, valbuf);=0A= }=0A= else=0A= {=0A= for (i =3D 0; i < type_len; i++)=0A= {=0A= regcache_raw_write (regcache, IP2K_RETVAL_REGNUM + i,=0A= ((char *) valbuf)++);=0A= }=0A= }=0A= }=0A= =0A= /* ip2k_use_struct_convention=0A= =0A= Return 1 if we should we use EXTRACT_STRUCT_VALUE_ADDRESS to=0A= extract the return value.=0A= =0A= Return 0 if we should use EXTRACT_RETURN_VALUE.=0A= =0A= GCC_P is true if compiled with GCC and TYPE is the type=0A= (which is known to be a struct, union, or array).=0A= =0A= For the ip2k, gcc is the only compiler and anything=0A= 8 bytes or smaller in size is returned in registers. */=0A= =0A= static int=0A= ip2k_use_struct_convention (int gcc_p, struct type *type)=0A= {=0A= if (debug_level >=3D DEBUG_MAX)=0A= printf_filtered ("ip2k_use_struct_convention\n");=0A= =0A= return (TYPE_LENGTH (type) > 8);=0A= }=0A= =0A= /* ip2k_extract_struct_value_address=0A= Extract from an array REGBUF containing the (raw) register state=0A= the address in which a function should return its structure value,=0A= as a CORE_ADDR (or an expression that can be used as one). */=0A= static CORE_ADDR=0A= ip2k_extract_struct_value_address (struct regcache *regcache)=0A= {=0A= CORE_ADDR sp;=0A= =0A= if (debug_level >=3D DEBUG_MAX)=0A= printf_filtered ("ip2k_extract_struct_value_address\n");=0A= =0A= /* The called function has returned...=0A= =0A= And the place to store the structure return value was stored on=0A= the stack as a "hidden" first argument to the function called...=0A= =0A= All stack adjustments made by the called function should have been=0A= undone already, and the first argument should therefore be located=0A= at sp+1,sp+2. */=0A= =0A= sp =3D ip2k_dptr_to_addr (read_register (IP2K_SP_REGNUM));=0A= return ip2k_dptr_to_addr (read_memory_unsigned_integer (sp + 1, 2));=0A= }=0A= =0A= /* ip2k_breakpoint_from_pc. */=0A= static const unsigned char *=0A= ip2k_breakpoint_from_pc (CORE_ADDR * pc, int *len)=0A= {=0A= static unsigned char break_insn[] =3D { 0x00, 0x01 };=0A= static unsigned char breakx_insn[] =3D { 0x00, 0x05 };=0A= unsigned short insn;=0A= =0A= if (debug_level >=3D DEBUG_MAX)=0A= printf_filtered ("ip2k_breakpoint_from_pc\n");=0A= =0A= insn =3D read_memory_unsigned_integer (*pc, 2);=0A= if (((insn & 0xFF00) =3D=3D 0x7000) ||=0A= ((insn & 0xFF00) =3D=3D 0x7100) || ((insn & 0xFFF8) =3D=3D 0x0010))= =0A= {=0A= *len =3D sizeof (breakx_insn);=0A= return breakx_insn;=0A= }=0A= else=0A= {=0A= *len =3D sizeof (break_insn);=0A= return break_insn;=0A= }=0A= }=0A= =0A= /* ip2k_ignore_helper.=0A= Return non-zero if the PC is in a library helper function that should=0A= be ignored. This implements the IGNORE_HELPER_CALL macro. */=0A= int=0A= ip2k_ignore_helper (CORE_ADDR pc)=0A= {=0A= enum ip2k_func_type type;=0A= =0A= if (debug_level >=3D DEBUG_FRAME)=0A= printf_filtered ("ip2k_ignore_helper\n");=0A= =0A= type =3D ip2k_get_function_type (pc, 0);=0A= switch (type)=0A= {=0A= case ip2k_func_type_libgcc_stub:=0A= case ip2k_func_type_libgcc_epilogue:=0A= return 1;=0A= case ip2k_func_type_normal:=0A= case ip2k_func_type_libgcc_indcall:=0A= default:=0A= return 0;=0A= }=0A= }=0A= =0A= /* ip2k_in_call_trampoline. */=0A= static int=0A= ip2k_in_call_trampoline (CORE_ADDR pc, char *name)=0A= {=0A= if (debug_level >=3D DEBUG_FRAME)=0A= printf_filtered ("ip2k_in_call_trampoline\n");=0A= =0A= if (ip2k_get_function_type (pc, name) =3D=3D ip2k_func_type_libgcc_indcal= l)=0A= return 1;=0A= =20=20=20=20=0A= return 0;=0A= }=0A= =0A= /* ip2k_in_return_trampoline. */=0A= static int=0A= ip2k_in_return_trampoline (CORE_ADDR pc, char *name)=0A= {=0A= if (debug_level >=3D DEBUG_FRAME)=0A= printf_filtered ("ip2k_in_return_trampoline\n");=0A= =0A= if (ip2k_get_function_type (pc, name) =3D=3D ip2k_func_type_libgcc_epilog= ue)=0A= return 1;=0A= =20=20=20=20=0A= return 0;=0A= }=0A= =0A= /* ip2k_skip_trampoline. */=0A= static CORE_ADDR=0A= ip2k_skip_trampoline (CORE_ADDR pc)=0A= {=0A= enum ip2k_func_type type;=0A= unsigned short insn;=0A= =0A= if (debug_level >=3D DEBUG_FRAME)=0A= printf_filtered ("ip2k_skip_trampoline\n");=0A= =0A= type =3D ip2k_get_function_type (pc, 0);=0A= if ((type !=3D ip2k_func_type_libgcc_indcall) && (type !=3D ip2k_func_typ= e_libgcc_epilogue))=0A= return 0;=0A= =0A= /* If we are at a ret instruction then the destination address can be fou= nd in=0A= CALLH/CALLL. */=0A= insn =3D read_memory_unsigned_integer (pc, 2);=0A= if (insn =3D=3D 0x0007)=0A= return ip2k_iptr_to_addr (read_register (IP2K_CALL_REGNUM));=0A= =20=20=20=20=0A= /* We are not at a ret instuction so CALLH/CALLL may not be valid...=0A= search for the ret instruction and lie and say that the pc of the ret= =0A= instruction is the way out. When it stops again it will recheck and=0A= discover that we are stil in the trampoline but by then CALLH/CALLL=0A= will be valid. */=0A= while (1)=0A= {=0A= pc +=3D 2;=0A= insn =3D read_memory_unsigned_integer (pc, 2);=0A= if (insn =3D=3D 0x0007)=0A= /* Return pc of ret instruction */=0A= return pc;=0A= }=0A= }=0A= =0A= /* ip2k_skip_prologue.=0A= Analyze instructions to find the end of the prologue, return the pc=0A= of the end of the prologue */=0A= static CORE_ADDR=0A= ip2k_skip_prologue (CORE_ADDR pc)=0A= {=0A= unsigned char buf[20];=0A= unsigned char *pos =3D buf;=0A= CORE_ADDR start_pc;=0A= int length;=0A= =0A= if (debug_level >=3D DEBUG_MAX)=0A= printf_filtered ("ip2k_skip_prologue\n");=0A= =0A= /* Find entry_pc. */=0A= start_pc =3D ip2k_try_pc_function_start (pc);=0A= =0A= /* Read prologue. */=0A= if (target_read_memory (start_pc, buf, sizeof (buf)) !=3D 0)=0A= memset (buf, 0, sizeof (buf));=0A= =0A= /* push CALLH/L will always be first (if present). */=0A= if (memcmp (buf, ip2k_call_prologue_insns, sizeof (ip2k_call_prologue_ins= ns)) =3D=3D 0)=0A= {=0A= start_pc +=3D sizeof (ip2k_call_prologue_insns);=0A= pos +=3D sizeof (ip2k_call_prologue_insns);=0A= }=0A= =0A= /* FP code will be next (if present). */=0A= if (memcmp (buf, ip2k_fp_prologue_insns, sizeof (ip2k_fp_prologue_insns))= =3D=3D 0)=0A= {=0A= start_pc +=3D sizeof (ip2k_fp_prologue_insns);=0A= pos +=3D sizeof (ip2k_fp_prologue_insns);=0A= }=0A= =0A= /* Local variable code will be next (if present). */=0A= if (memcmp (buf, ip2k_local_1_prologue_insns, sizeof (ip2k_local_1_prolog= ue_insns)) =3D=3D 0)=0A= {=0A= start_pc +=3D sizeof (ip2k_local_1_prologue_insns);=0A= pos +=3D sizeof (ip2k_local_1_prologue_insns);=0A= }=0A= buf[1] =3D 0x00;=0A= if (memcmp (buf, ip2k_local_n_prologue_insns, sizeof (ip2k_local_n_prolog= ue_insns)) =3D=3D 0)=0A= {=0A= start_pc +=3D sizeof (ip2k_local_n_prologue_insns);=0A= pos +=3D sizeof (ip2k_local_n_prologue_insns);=0A= }=0A= =0A= return start_pc;=0A= }=0A= =0A= /* ip2k_frame_unwind_cache. */=0A= struct ip2k_unwind_cache *=0A= ip2k_frame_unwind_cache (struct frame_info *next_frame,=0A= void **this_prologue_cache)=0A= {=0A= struct ip2k_unwind_cache *info;=0A= CORE_ADDR return_pc, return_verify, temp_sp, addr;=0A= enum ip2k_func_type type;=0A= unsigned short insn;=0A= unsigned char buf[20];=0A= unsigned char *pos =3D buf;=0A= int local_stack =3D 0;=0A= int executed_stack =3D 0;=0A= int ret_saved =3D 0;=0A= int position, temp;=0A= =0A= if ((*this_prologue_cache))=0A= return (*this_prologue_cache);=0A= =0A= if (debug_level >=3D DEBUG_FRAME)=0A= printf_filtered ("ip2k_frame_unwind_cache:\n");=0A= =20=20=20=20=0A= info =3D FRAME_OBSTACK_ZALLOC (struct ip2k_unwind_cache);=0A= (*this_prologue_cache) =3D info;=0A= info->saved_regs =3D trad_frame_alloc_saved_regs (next_frame);=0A= =0A= /* Starting point. */=0A= info->current_pc =3D frame_pc_unwind (next_frame);=0A= info->entry_pc =3D frame_func_unwind (next_frame);=0A= info->return_pc =3D 0;=0A= info->entry_sp =3D 0;=0A= info->normal_sp =3D 0;=0A= info->current_sp =3D frame_sp_unwind (next_frame);=0A= type =3D ip2k_get_function_type (info->current_pc, 0);=0A= =0A= /* Read prologue. */=0A= position =3D (info->current_pc - info->entry_pc) / 2;=0A= if (target_read_memory (info->entry_pc, buf, sizeof (buf)) !=3D 0)=0A= memset (buf, 0, sizeof (buf));=0A= =0A= /* push CALLL (0x447f)=0A= push CALLH (0x447e) */=0A= if (memcmp (pos, ip2k_call_prologue_insns, sizeof (ip2k_call_prologue_ins= ns)) =3D=3D 0)=0A= {=0A= ret_saved =3D 1;=0A= local_stack +=3D 2;=0A= if (position >=3D 2)=0A= executed_stack +=3D 2;=0A= else if (position >=3D 1)=0A= executed_stack +=3D 1;=0A= pos +=3D sizeof (ip2k_call_prologue_insns);=0A= position -=3D sizeof (ip2k_call_prologue_insns) / 2;=0A= }=0A= =0A= /* push $fe (0x44fe)=0A= mov W,SPL (0x2007)=0A= mov $fe,W (0x02fe)=0A= mov W,SPH (0x2006)=0A= push $fd (0x44fd)=0A= mov $fd,W (0x02fd) */=0A= if (memcmp (pos, ip2k_fp_prologue_insns, sizeof (ip2k_fp_prologue_insns))= =3D=3D 0)=0A= {=0A= local_stack +=3D 2;=0A= if (position >=3D 5)=0A= executed_stack +=3D 2;=0A= else if (position >=3D 1)=0A= executed_stack +=3D 1;=0A= pos +=3D sizeof (ip2k_fp_prologue_insns);=0A= position -=3D sizeof (ip2k_fp_prologue_insns) / 2;=0A= }=0A= =0A= /* mov W,#$xx (0x7cxx)=0A= sub SPL,W (0x0a07) */=0A= temp =3D pos[1];=0A= pos[1] =3D 0x00;=0A= if (memcmp (pos, ip2k_local_n_prologue_insns, sizeof (ip2k_local_n_prolog= ue_insns)) =3D=3D 0)=0A= {=0A= local_stack +=3D temp;=0A= if (position >=3D 2)=0A= executed_stack +=3D temp;=0A= pos +=3D sizeof (ip2k_local_n_prologue_insns);=0A= position -=3D sizeof (ip2k_local_n_prologue_insns) / 2;=0A= }=0A= =0A= /* Special handling if we are in the middle of the prologue. */=0A= if (position < 0)=0A= {=0A= info->return_pc =3D ip2k_iptr_to_addr (read_register (IP2K_CALL_REGNU= M));=0A= info->entry_sp =3D info->current_sp + executed_stack;=0A= info->normal_sp =3D info->entry_sp - local_stack;=0A= goto finish;=0A= }=0A= =0A= /* Apply stack estimate. */=0A= info->normal_sp =3D info->current_sp;=0A= info->entry_sp =3D info->current_sp + local_stack;=0A= =20=20=0A= /* Impossible to search for adjust if this is a leaf function. */=0A= if ((ret_saved =3D=3D 0) && (type !=3D ip2k_func_type_libgcc_epilogue))= =0A= {=0A= info->return_pc =3D ip2k_iptr_to_addr (read_register (IP2K_CALL_REGNU= M));=0A= goto finish;=0A= }=0A= =0A= /* Check to see if we are in a critical part of an epilogue. */=0A= insn =3D read_memory_unsigned_integer (info->current_pc, 2);=0A= if (insn =3D=3D 0x0007)=0A= {=0A= printf_filtered ("\tepilogue (ret)\n");=0A= info->return_pc =3D ip2k_iptr_to_addr (read_register (IP2K_CALL_REGNU= M));=0A= if (debug_level >=3D DEBUG_FRAME)=0A= goto finish;=0A= }=0A= if (insn =3D=3D 0x467f)=0A= {=0A= printf_filtered ("\tepilogue (pop calll)\n");=0A= if (target_read_memory (info->current_sp + 1, buf, 1) !=3D 0)=0A= {=0A= if (debug_level >=3D DEBUG_FRAME)=0A= printf_filtered ("\tnot found on stack (invalid sp in epilogue)= !\n");=0A= goto finish;=0A= }=0A= info->return_pc =3D ip2k_iptr_to_addr(=0A= (read_register (IP2K_CALL_REGNUM) & 0x0000FF00)=0A= | (buf[0] & 0x0FF));=0A= info->entry_sp++;=0A= goto finish;=0A= }=0A= =0A= /* Search for frame on stack.=0A= Return address should be at entry_sp-2 (+1 for actual read as 1(SP)=0A= points to stack). */=0A= temp_sp =3D info->entry_sp - 2;=0A= while (1)=0A= {=0A= /* Limit back search to 128 bytes. */=0A= if (temp_sp > info->entry_sp + 128)=0A= {=0A= if (debug_level >=3D DEBUG_FRAME)=0A= printf_filtered ("\tnot found on stack (too far)!\n");=0A= break;=0A= }=0A= =0A= /* Read memory the manual way so that we can handle it=0A= nicely when it fails. */=0A= if (target_read_memory (temp_sp + 1, buf, 2) !=3D 0)=0A= /* reached/exceeded stack memory. */=0A= {=0A= if (debug_level >=3D DEBUG_FRAME)=0A= printf_filtered ("\tnot found on stack (mem err)!\n");=0A= break;=0A= }=0A= =0A= /* Increment temp_sp now so that continues can work. */=0A= temp_sp +=3D 1;=0A= =0A= /* Process potential return pc value from stack. */=0A= return_pc =3D extract_unsigned_integer (buf, 2);=0A= if (return_pc < 4)=0A= continue;=0A= return_pc =3D ip2k_iptr_to_addr (return_pc);=0A= if (target_read_memory (return_pc - 4, buf, 4) !=3D 0)=0A= continue;=0A= =0A= /* Verify instruction at return_pc is a call instruction. */=0A= insn =3D extract_unsigned_integer (buf + 2, 2);=0A= if ((insn & 0xE000) !=3D 0xC000)=0A= continue;=0A= =0A= /* Found a possible call instruction. */=0A= return_verify =3D insn & 0x1FFF;=0A= insn =3D extract_unsigned_integer (buf + 0, 2);=0A= if ((insn & 0xFFF8) =3D=3D 0x0010)=0A= return_verify |=3D (insn << 13) & 0x0E000;=0A= else=0A= return_verify |=3D ip2k_addr_to_iptr(return_pc) & 0x0E000;=0A= return_verify =3D ip2k_iptr_to_addr(return_verify);=0A= =09=09=20=20=0A= /* Verify that this is the expected call instruction. */=0A= if ((return_verify !=3D info->entry_pc)=0A= && (type !=3D ip2k_func_type_libgcc_epilogue)=0A= && (ip2k_get_function_type (return_verify, 0) !=3D ip2k_func_type_l= ibgcc_indcall))=0A= continue;=0A= =0A= /* Found! */=0A= info->return_pc =3D return_pc;=0A= =0A= /* Apply stack adjust. */=0A= temp_sp +=3D 2 - 1;=0A= if (temp_sp !=3D info->entry_sp)=0A= {=0A= if (debug_level >=3D DEBUG_FRAME)=0A= printf_filtered ("\tcorrection of %ld applied\n", temp_sp - inf= o->entry_sp);=0A= info->normal_sp +=3D (temp_sp - info->entry_sp);=0A= info->entry_sp =3D temp_sp;=0A= }=0A= else=0A= {=0A= if (debug_level >=3D DEBUG_FRAME)=0A= printf_filtered ("\tno correction needed\n");=0A= }=0A= break;=0A= }=0A= =0A= finish:=0A= =20=20=0A= if (info->return_pc =3D=3D 0)=0A= info->entry_sp =3D 0;=0A= =0A= addr =3D ip2k_addr_to_dptr(info->entry_sp);=0A= trad_frame_register_value (info->saved_regs, IP2K_SP_REGNUM, addr);=0A= trad_frame_register_value (info->saved_regs, IP2K_SPH_REGNUM, addr >> 8);= =0A= trad_frame_register_value (info->saved_regs, IP2K_SPL_REGNUM, addr & 0x0F= F);=0A= =0A= addr =3D ip2k_addr_to_iptr(info->return_pc);=0A= trad_frame_register_value (info->saved_regs, IP2K_PC_REGNUM, addr);=0A= trad_frame_register_value (info->saved_regs, IP2K_PCH_REGNUM, addr >> 8);= =0A= trad_frame_register_value (info->saved_regs, IP2K_PCL_REGNUM, addr & 0x0F= F);=0A= =0A= if (debug_level >=3D DEBUG_FRAME)=0A= {=0A= printf_filtered ("\tentry_pc =3D 0x%08lx\n", info->entry_pc);=0A= printf_filtered ("\tcurrent_pc =3D 0x%08lx\n", info->current_pc);=0A= printf_filtered ("\treturn_pc =3D 0x%08lx\n", info->return_pc);=0A= printf_filtered ("\tentry_sp =3D 0x%08lx\n", info->entry_sp);=0A= printf_filtered ("\tnormal_sp =3D 0x%08lx\n", info->normal_sp);=0A= printf_filtered ("\tcurrent_sp =3D 0x%08lx\n", info->current_sp);=0A= }=0A= =0A= return info;=0A= }=0A= =0A= /* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that=0A= dummy frame. The frame ID's base needs to match the TOS value=0A= saved by save_dummy_frame_tos(), and the PC match the dummy frame's=0A= breakpoint. */=0A= static struct frame_id=0A= ip2k_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_fram= e)=0A= {=0A= ULONGEST base;=0A= =0A= if (debug_level >=3D DEBUG_FRAME)=0A= printf_filtered ("ip2k_unwind_dummy_id\n");=0A= =0A= frame_unwind_unsigned_register (next_frame, IP2K_SP_REGNUM, &base);=0A= return frame_id_build (ip2k_dptr_to_addr(base), frame_pc_unwind (next_fra= me));=0A= }=0A= =0A= /* Given a GDB frame, determine the address of the calling function's=0A= frame. This will be used to create a new GDB frame struct. */=0A= static void=0A= ip2k_frame_this_id (struct frame_info *next_frame,=0A= void **this_prologue_cache,=0A= struct frame_id *this_id)=0A= {=0A= struct ip2k_unwind_cache *info;=0A= CORE_ADDR base;=0A= CORE_ADDR func;=0A= struct frame_id id;=0A= =0A= if (debug_level >=3D DEBUG_FRAME)=0A= printf_filtered ("ip2k_frame_this_id\n");=0A= =0A= info =3D ip2k_frame_unwind_cache (next_frame, this_prologue_cache);=0A= =0A= /* The FUNC is easy. */=0A= func =3D frame_func_unwind (next_frame);=0A= =0A= /* This is meant to halt the backtrace at "_start". Make sure we=0A= don't halt it at a generic dummy frame. */=0A= if (inside_entry_file (func))=0A= return;=0A= =0A= base =3D info->normal_sp;=0A= if (base =3D=3D 0)=0A= return;=0A= =0A= id =3D frame_id_build (base, func);=0A= =0A= /* Check that we're not going round in circles with the same frame=0A= ID (but avoid applying the test to sentinel frames which do go=0A= round in circles). Can't use frame_id_eq() as that doesn't yet=0A= compare the frame's PC value. */=0A= if (frame_relative_level (next_frame) >=3D 0=0A= && get_frame_type (next_frame) !=3D DUMMY_FRAME=0A= && frame_id_eq (get_frame_id (next_frame), id))=0A= {=0A= if (debug_level >=3D DEBUG_FRAME)=0A= printf_filtered ("ip2k_frame_this_id: circular\n");=0A= return;=0A= }=0A= =0A= (*this_id) =3D id;=0A= }=0A= =0A= static void=0A= ip2k_frame_prev_register (struct frame_info *next_frame,=0A= void **this_prologue_cache,=0A= int regnum, int *optimizedp,=0A= enum lval_type *lvalp, CORE_ADDR *addrp,=0A= int *realnump, void *bufferp)=0A= {=0A= struct ip2k_unwind_cache *info=0A= =3D ip2k_frame_unwind_cache (next_frame, this_prologue_cache);=0A= trad_frame_prev_register (next_frame, info->saved_regs, regnum,=0A= optimizedp, lvalp, addrp, realnump, bufferp);=0A= }=0A= =0A= static CORE_ADDR=0A= ip2k_frame_base_address (struct frame_info *next_frame, void **this_cache)= =0A= {=0A= struct ip2k_unwind_cache *info;=0A= =0A= if (debug_level >=3D DEBUG_FRAME)=0A= printf_filtered ("ip2k_frame_base_address\n");=0A= =0A= info =3D ip2k_frame_unwind_cache (next_frame, this_cache);=0A= /* Note that gcc provides all debug information relative to the=0A= post-locals SP, not the entry_sp! */=0A= return info->normal_sp;=0A= }=0A= =0A= static const struct frame_unwind ip2k_frame_unwind =3D {=0A= NORMAL_FRAME,=0A= ip2k_frame_this_id,=0A= ip2k_frame_prev_register=0A= };=0A= =0A= static const struct frame_base ip2k_frame_base =3D {=0A= &ip2k_frame_unwind,=0A= ip2k_frame_base_address,=0A= ip2k_frame_base_address,=0A= ip2k_frame_base_address=0A= };=0A= =0A= static const struct frame_unwind *=0A= ip2k_frame_p (CORE_ADDR pc)=0A= {=0A= return &ip2k_frame_unwind;=0A= }=0A= =0A= /* ip2k_gdbarch_init. */=0A= static struct gdbarch *=0A= ip2k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)= =0A= {=0A= struct gdbarch *gdbarch;=0A= =0A= /* Find a candidate among the list of pre-declared architectures. */=0A= arches =3D gdbarch_list_lookup_by_info (arches, &info);=0A= if (arches !=3D NULL)=0A= return (arches->gdbarch);=0A= =0A= /* No architecture found, create one. */=0A= gdbarch =3D gdbarch_alloc (&info, 0);=0A= =0A= /* Integer types. */=0A= set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);=0A= set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);=0A= set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);=0A= set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);=0A= =0A= /* Floating point types (not supported). */=0A= set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);=0A= set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);=0A= set_gdbarch_long_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);=0A= set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);=0A= set_gdbarch_double_format (gdbarch, &floatformat_ieee_single_little);=0A= set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_single_little)= ;=0A= =0A= /* Pointers types - pointers on target are 16-bits but addresses in GDB a= re 32-bits. */=0A= set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);=0A= set_gdbarch_addr_bit (gdbarch, 32);=0A= set_gdbarch_address_to_pointer (gdbarch, ip2k_address_to_pointer);=0A= set_gdbarch_pointer_to_address (gdbarch, ip2k_pointer_to_address);=0A= =0A= /* Core register functions. */=0A= set_gdbarch_read_pc (gdbarch, ip2k_read_pc);=0A= set_gdbarch_write_pc (gdbarch, ip2k_write_pc);=0A= set_gdbarch_unwind_pc (gdbarch, ip2k_unwind_pc);=0A= set_gdbarch_unwind_sp (gdbarch, ip2k_unwind_sp);=0A= =0A= /* General register functions. */=0A= set_gdbarch_num_regs (gdbarch, IP2K_NUM_NATIVE_REGS);=0A= set_gdbarch_num_pseudo_regs (gdbarch, IP2K_NUM_PSEUDO_REGS);=0A= set_gdbarch_register_name (gdbarch, ip2k_register_name);=0A= set_gdbarch_register_type (gdbarch, ip2k_register_type);=0A= set_gdbarch_pseudo_register_read (gdbarch, ip2k_pseudo_register_read);=0A= set_gdbarch_pseudo_register_write (gdbarch, ip2k_pseudo_register_write);= =0A= =0A= /* C data. */=0A= set_gdbarch_extract_return_value (gdbarch, ip2k_extract_return_value);=0A= set_gdbarch_store_return_value (gdbarch, ip2k_store_return_value);=0A= set_gdbarch_use_struct_convention (gdbarch, ip2k_use_struct_convention);= =0A= set_gdbarch_extract_struct_value_address (gdbarch,=0A= ip2k_extract_struct_value_address);=0A= =0A= /* Code. */=0A= set_gdbarch_print_insn (gdbarch, print_insn_ip2k);=0A= set_gdbarch_call_dummy_address (gdbarch, entry_point_address);=0A= // set_gdbarch_push_dummy_call (gdbarch, ip2k_push_dummy_call);=0A= =0A= set_gdbarch_decr_pc_after_break (gdbarch, 0);=0A= set_gdbarch_function_start_offset (gdbarch, 0);=0A= set_gdbarch_breakpoint_from_pc (gdbarch, ip2k_breakpoint_from_pc);=0A= =0A= set_gdbarch_in_solib_call_trampoline (gdbarch, ip2k_in_call_trampoline);= =0A= set_gdbarch_in_solib_return_trampoline (gdbarch, ip2k_in_return_trampolin= e);=0A= set_gdbarch_skip_trampoline_code (gdbarch, ip2k_skip_trampoline);=0A= set_gdbarch_skip_prologue (gdbarch, ip2k_skip_prologue);=0A= set_gdbarch_inner_than (gdbarch, core_addr_lessthan);=0A= set_gdbarch_frame_args_skip (gdbarch, 0);=0A= set_gdbarch_frameless_function_invocation (gdbarch,=0A= frameless_look_for_prologue);=0A= =0A= set_gdbarch_unwind_dummy_id (gdbarch, ip2k_unwind_dummy_id);=0A= frame_unwind_append_predicate (gdbarch, ip2k_frame_p);=0A= frame_base_set_default (gdbarch, &ip2k_frame_base);=0A= =0A= set_gdbarch_print_insn (gdbarch, print_insn_ip2k);=0A= =0A= /* Complete. */=0A= return (gdbarch);=0A= }=0A= =0A= /* _initialize_ip2k_tdep. */=0A= void=0A= _initialize_ip2k_tdep (void)=0A= {=0A= register_gdbarch_init (bfd_arch_ip2k, ip2k_gdbarch_init);=0A= }=0A= ------=_NextPart_000_03A4_01C37B86.5705FC30 Content-Type: application/octet-stream; name="tm-ip2k.h" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="tm-ip2k.h" Content-length: 1385 /* Target-specific definition for the Ubicom IP2K=0A= Copyright (C) 2000, 2001 Free Software Foundation, Inc.=0A= =0A= This file is part of GDB.=0A= =0A= This program is free software; you can redistribute it and/or modify=0A= it under the terms of the GNU General Public License as published by=0A= the Free Software Foundation; either version 2 of the License, or=0A= (at your option) any later version.=0A= =0A= This program is distributed in the hope that it will be useful,=0A= but WITHOUT ANY WARRANTY; without even the implied warranty of=0A= MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the=0A= GNU General Public License for more details.=0A= =0A= You should have received a copy of the GNU General Public License=0A= along with this program; if not, write to the Free Software=0A= Foundation, Inc., 59 Temple Place - Suite 330,=0A= Boston, MA 02111-1307, USA. */=0A= =0A= #ifndef TM_IP2K_H=0A= #define TM_IP2K_H=0A= =0A= #ifndef GDB_MULTI_ARCH=0A= #define GDB_MULTI_ARCH 1=0A= #endif=0A= =0A= /* Define the bit, byte, and word ordering of the machine. */=0A= #define TARGET_BYTE_ORDER BFD_ENDIAN_BIG=0A= =0A= /* Functions for dealing with epilogue call and return stubs. */=0A= #define IGNORE_HELPER_CALL(pc) ip2k_ignore_helper (pc)=0A= extern int ip2k_ignore_helper (CORE_ADDR pc);=0A= =0A= #endif /* TM_IP2K_H */=0A= ------=_NextPart_000_03A4_01C37B86.5705FC30--