GDB (API)
/home/stan/gdb/src/gdb/m68hc11-tdep.c
Go to the documentation of this file.
00001 /* Target-dependent code for Motorola 68HC11 & 68HC12
00002 
00003    Copyright (C) 1999-2013 Free Software Foundation, Inc.
00004 
00005    Contributed by Stephane Carrez, stcarrez@nerim.fr
00006 
00007    This file is part of GDB.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 3 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00021 
00022 
00023 #include "defs.h"
00024 #include "frame.h"
00025 #include "frame-unwind.h"
00026 #include "frame-base.h"
00027 #include "dwarf2-frame.h"
00028 #include "trad-frame.h"
00029 #include "symtab.h"
00030 #include "gdbtypes.h"
00031 #include "gdbcmd.h"
00032 #include "gdbcore.h"
00033 #include "gdb_string.h"
00034 #include "value.h"
00035 #include "inferior.h"
00036 #include "dis-asm.h"  
00037 #include "symfile.h"
00038 #include "objfiles.h"
00039 #include "arch-utils.h"
00040 #include "regcache.h"
00041 #include "reggroups.h"
00042 
00043 #include "target.h"
00044 #include "opcode/m68hc11.h"
00045 #include "elf/m68hc11.h"
00046 #include "elf-bfd.h"
00047 
00048 /* Macros for setting and testing a bit in a minimal symbol.
00049    For 68HC11/68HC12 we have two flags that tell which return
00050    type the function is using.  This is used for prologue and frame
00051    analysis to compute correct stack frame layout.
00052    
00053    The MSB of the minimal symbol's "info" field is used for this purpose.
00054 
00055    MSYMBOL_SET_RTC      Actually sets the "RTC" bit.
00056    MSYMBOL_SET_RTI      Actually sets the "RTI" bit.
00057    MSYMBOL_IS_RTC       Tests the "RTC" bit in a minimal symbol.
00058    MSYMBOL_IS_RTI       Tests the "RTC" bit in a minimal symbol.  */
00059 
00060 #define MSYMBOL_SET_RTC(msym)                           \
00061         MSYMBOL_TARGET_FLAG_1 (msym) = 1
00062 
00063 #define MSYMBOL_SET_RTI(msym)                           \
00064         MSYMBOL_TARGET_FLAG_2 (msym) = 1
00065 
00066 #define MSYMBOL_IS_RTC(msym)                            \
00067         MSYMBOL_TARGET_FLAG_1 (msym)
00068 
00069 #define MSYMBOL_IS_RTI(msym)                            \
00070         MSYMBOL_TARGET_FLAG_2 (msym)
00071 
00072 enum insn_return_kind {
00073   RETURN_RTS,
00074   RETURN_RTC,
00075   RETURN_RTI
00076 };
00077 
00078   
00079 /* Register numbers of various important registers.  */
00080 
00081 #define HARD_X_REGNUM   0
00082 #define HARD_D_REGNUM   1
00083 #define HARD_Y_REGNUM   2
00084 #define HARD_SP_REGNUM  3
00085 #define HARD_PC_REGNUM  4
00086 
00087 #define HARD_A_REGNUM   5
00088 #define HARD_B_REGNUM   6
00089 #define HARD_CCR_REGNUM 7
00090 
00091 /* 68HC12 page number register.
00092    Note: to keep a compatibility with gcc register naming, we must
00093    not have to rename FP and other soft registers.  The page register
00094    is a real hard register and must therefore be counted by gdbarch_num_regs.
00095    For this it has the same number as Z register (which is not used).  */
00096 #define HARD_PAGE_REGNUM 8
00097 #define M68HC11_LAST_HARD_REG (HARD_PAGE_REGNUM)
00098 
00099 /* Z is replaced by X or Y by gcc during machine reorg.
00100    ??? There is no way to get it and even know whether
00101    it's in X or Y or in ZS.  */
00102 #define SOFT_Z_REGNUM        8
00103 
00104 /* Soft registers.  These registers are special.  There are treated
00105    like normal hard registers by gcc and gdb (ie, within dwarf2 info).
00106    They are physically located in memory.  */
00107 #define SOFT_FP_REGNUM       9
00108 #define SOFT_TMP_REGNUM     10
00109 #define SOFT_ZS_REGNUM      11
00110 #define SOFT_XY_REGNUM      12
00111 #define SOFT_UNUSED_REGNUM  13
00112 #define SOFT_D1_REGNUM      14
00113 #define SOFT_D32_REGNUM     (SOFT_D1_REGNUM+31)
00114 #define M68HC11_MAX_SOFT_REGS 32
00115 
00116 #define M68HC11_NUM_REGS        (8)
00117 #define M68HC11_NUM_PSEUDO_REGS (M68HC11_MAX_SOFT_REGS+5)
00118 #define M68HC11_ALL_REGS        (M68HC11_NUM_REGS+M68HC11_NUM_PSEUDO_REGS)
00119 
00120 #define M68HC11_REG_SIZE    (2)
00121 
00122 #define M68HC12_NUM_REGS        (9)
00123 #define M68HC12_NUM_PSEUDO_REGS ((M68HC11_MAX_SOFT_REGS+5)+1-1)
00124 #define M68HC12_HARD_PC_REGNUM  (SOFT_D32_REGNUM+1)
00125 
00126 struct insn_sequence;
00127 struct gdbarch_tdep
00128   {
00129     /* Stack pointer correction value.  For 68hc11, the stack pointer points
00130        to the next push location.  An offset of 1 must be applied to obtain
00131        the address where the last value is saved.  For 68hc12, the stack
00132        pointer points to the last value pushed.  No offset is necessary.  */
00133     int stack_correction;
00134 
00135     /* Description of instructions in the prologue.  */
00136     struct insn_sequence *prologue;
00137 
00138     /* True if the page memory bank register is available
00139        and must be used.  */
00140     int use_page_register;
00141 
00142     /* ELF flags for ABI.  */
00143     int elf_flags;
00144   };
00145 
00146 #define STACK_CORRECTION(gdbarch) (gdbarch_tdep (gdbarch)->stack_correction)
00147 #define USE_PAGE_REGISTER(gdbarch) (gdbarch_tdep (gdbarch)->use_page_register)
00148 
00149 struct m68hc11_unwind_cache
00150 {
00151   /* The previous frame's inner most stack address.  Used as this
00152      frame ID's stack_addr.  */
00153   CORE_ADDR prev_sp;
00154   /* The frame's base, optionally used by the high-level debug info.  */
00155   CORE_ADDR base;
00156   CORE_ADDR pc;
00157   int size;
00158   int prologue_type;
00159   CORE_ADDR return_pc;
00160   CORE_ADDR sp_offset;
00161   int frameless;
00162   enum insn_return_kind return_kind;
00163 
00164   /* Table indicating the location of each and every register.  */
00165   struct trad_frame_saved_reg *saved_regs;
00166 };
00167 
00168 /* Table of registers for 68HC11.  This includes the hard registers
00169    and the soft registers used by GCC.  */
00170 static char *
00171 m68hc11_register_names[] =
00172 {
00173   "x",    "d",    "y",    "sp",   "pc",   "a",    "b",
00174   "ccr",  "page", "frame","tmp",  "zs",   "xy",   0,
00175   "d1",   "d2",   "d3",   "d4",   "d5",   "d6",   "d7",
00176   "d8",   "d9",   "d10",  "d11",  "d12",  "d13",  "d14",
00177   "d15",  "d16",  "d17",  "d18",  "d19",  "d20",  "d21",
00178   "d22",  "d23",  "d24",  "d25",  "d26",  "d27",  "d28",
00179   "d29",  "d30",  "d31",  "d32"
00180 };
00181 
00182 struct m68hc11_soft_reg 
00183 {
00184   const char *name;
00185   CORE_ADDR   addr;
00186 };
00187 
00188 static struct m68hc11_soft_reg soft_regs[M68HC11_ALL_REGS];
00189 
00190 #define M68HC11_FP_ADDR soft_regs[SOFT_FP_REGNUM].addr
00191 
00192 static int soft_min_addr;
00193 static int soft_max_addr;
00194 static int soft_reg_initialized = 0;
00195 
00196 /* Look in the symbol table for the address of a pseudo register
00197    in memory.  If we don't find it, pretend the register is not used
00198    and not available.  */
00199 static void
00200 m68hc11_get_register_info (struct m68hc11_soft_reg *reg, const char *name)
00201 {
00202   struct minimal_symbol *msymbol;
00203 
00204   msymbol = lookup_minimal_symbol (name, NULL, NULL);
00205   if (msymbol)
00206     {
00207       reg->addr = SYMBOL_VALUE_ADDRESS (msymbol);
00208       reg->name = xstrdup (name);
00209 
00210       /* Keep track of the address range for soft registers.  */
00211       if (reg->addr < (CORE_ADDR) soft_min_addr)
00212         soft_min_addr = reg->addr;
00213       if (reg->addr > (CORE_ADDR) soft_max_addr)
00214         soft_max_addr = reg->addr;
00215     }
00216   else
00217     {
00218       reg->name = 0;
00219       reg->addr = 0;
00220     }
00221 }
00222 
00223 /* Initialize the table of soft register addresses according
00224    to the symbol table.  */
00225   static void
00226 m68hc11_initialize_register_info (void)
00227 {
00228   int i;
00229 
00230   if (soft_reg_initialized)
00231     return;
00232   
00233   soft_min_addr = INT_MAX;
00234   soft_max_addr = 0;
00235   for (i = 0; i < M68HC11_ALL_REGS; i++)
00236     {
00237       soft_regs[i].name = 0;
00238     }
00239   
00240   m68hc11_get_register_info (&soft_regs[SOFT_FP_REGNUM], "_.frame");
00241   m68hc11_get_register_info (&soft_regs[SOFT_TMP_REGNUM], "_.tmp");
00242   m68hc11_get_register_info (&soft_regs[SOFT_ZS_REGNUM], "_.z");
00243   soft_regs[SOFT_Z_REGNUM] = soft_regs[SOFT_ZS_REGNUM];
00244   m68hc11_get_register_info (&soft_regs[SOFT_XY_REGNUM], "_.xy");
00245 
00246   for (i = SOFT_D1_REGNUM; i < M68HC11_MAX_SOFT_REGS; i++)
00247     {
00248       char buf[10];
00249 
00250       xsnprintf (buf, sizeof (buf), "_.d%d", i - SOFT_D1_REGNUM + 1);
00251       m68hc11_get_register_info (&soft_regs[i], buf);
00252     }
00253 
00254   if (soft_regs[SOFT_FP_REGNUM].name == 0)
00255     warning (_("No frame soft register found in the symbol table.\n"
00256                "Stack backtrace will not work."));
00257   soft_reg_initialized = 1;
00258 }
00259 
00260 /* Given an address in memory, return the soft register number if
00261    that address corresponds to a soft register.  Returns -1 if not.  */
00262 static int
00263 m68hc11_which_soft_register (CORE_ADDR addr)
00264 {
00265   int i;
00266   
00267   if (addr < soft_min_addr || addr > soft_max_addr)
00268     return -1;
00269   
00270   for (i = SOFT_FP_REGNUM; i < M68HC11_ALL_REGS; i++)
00271     {
00272       if (soft_regs[i].name && soft_regs[i].addr == addr)
00273         return i;
00274     }
00275   return -1;
00276 }
00277 
00278 /* Fetch a pseudo register.  The 68hc11 soft registers are treated like
00279    pseudo registers.  They are located in memory.  Translate the register
00280    fetch into a memory read.  */
00281 static enum register_status
00282 m68hc11_pseudo_register_read (struct gdbarch *gdbarch,
00283                               struct regcache *regcache,
00284                               int regno, gdb_byte *buf)
00285 {
00286   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
00287 
00288   /* The PC is a pseudo reg only for 68HC12 with the memory bank
00289      addressing mode.  */
00290   if (regno == M68HC12_HARD_PC_REGNUM)
00291     {
00292       ULONGEST pc;
00293       const int regsize = 4;
00294       enum register_status status;
00295 
00296       status = regcache_cooked_read_unsigned (regcache, HARD_PC_REGNUM, &pc);
00297       if (status != REG_VALID)
00298         return status;
00299       if (pc >= 0x8000 && pc < 0xc000)
00300         {
00301           ULONGEST page;
00302 
00303           regcache_cooked_read_unsigned (regcache, HARD_PAGE_REGNUM, &page);
00304           pc -= 0x8000;
00305           pc += (page << 14);
00306           pc += 0x1000000;
00307         }
00308       store_unsigned_integer (buf, regsize, byte_order, pc);
00309       return REG_VALID;
00310     }
00311 
00312   m68hc11_initialize_register_info ();
00313   
00314   /* Fetch a soft register: translate into a memory read.  */
00315   if (soft_regs[regno].name)
00316     {
00317       target_read_memory (soft_regs[regno].addr, buf, 2);
00318     }
00319   else
00320     {
00321       memset (buf, 0, 2);
00322     }
00323 
00324   return REG_VALID;
00325 }
00326 
00327 /* Store a pseudo register.  Translate the register store
00328    into a memory write.  */
00329 static void
00330 m68hc11_pseudo_register_write (struct gdbarch *gdbarch,
00331                                struct regcache *regcache,
00332                                int regno, const gdb_byte *buf)
00333 {
00334   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
00335 
00336   /* The PC is a pseudo reg only for 68HC12 with the memory bank
00337      addressing mode.  */
00338   if (regno == M68HC12_HARD_PC_REGNUM)
00339     {
00340       const int regsize = 4;
00341       gdb_byte *tmp = alloca (regsize);
00342       CORE_ADDR pc;
00343 
00344       memcpy (tmp, buf, regsize);
00345       pc = extract_unsigned_integer (tmp, regsize, byte_order);
00346       if (pc >= 0x1000000)
00347         {
00348           pc -= 0x1000000;
00349           regcache_cooked_write_unsigned (regcache, HARD_PAGE_REGNUM,
00350                                           (pc >> 14) & 0x0ff);
00351           pc &= 0x03fff;
00352           regcache_cooked_write_unsigned (regcache, HARD_PC_REGNUM,
00353                                           pc + 0x8000);
00354         }
00355       else
00356         regcache_cooked_write_unsigned (regcache, HARD_PC_REGNUM, pc);
00357       return;
00358     }
00359   
00360   m68hc11_initialize_register_info ();
00361 
00362   /* Store a soft register: translate into a memory write.  */
00363   if (soft_regs[regno].name)
00364     {
00365       const int regsize = 2;
00366       gdb_byte *tmp = alloca (regsize);
00367       memcpy (tmp, buf, regsize);
00368       target_write_memory (soft_regs[regno].addr, tmp, regsize);
00369     }
00370 }
00371 
00372 static const char *
00373 m68hc11_register_name (struct gdbarch *gdbarch, int reg_nr)
00374 {
00375   if (reg_nr == M68HC12_HARD_PC_REGNUM && USE_PAGE_REGISTER (gdbarch))
00376     return "pc";
00377   if (reg_nr == HARD_PC_REGNUM && USE_PAGE_REGISTER (gdbarch))
00378     return "ppc";
00379   
00380   if (reg_nr < 0)
00381     return NULL;
00382   if (reg_nr >= M68HC11_ALL_REGS)
00383     return NULL;
00384 
00385   m68hc11_initialize_register_info ();
00386 
00387   /* If we don't know the address of a soft register, pretend it
00388      does not exist.  */
00389   if (reg_nr > M68HC11_LAST_HARD_REG && soft_regs[reg_nr].name == 0)
00390     return NULL;
00391   return m68hc11_register_names[reg_nr];
00392 }
00393 
00394 static const unsigned char *
00395 m68hc11_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
00396                             int *lenptr)
00397 {
00398   static unsigned char breakpoint[] = {0x0};
00399 
00400   *lenptr = sizeof (breakpoint);
00401   return breakpoint;
00402 }
00403 
00404 
00405 /* 68HC11 & 68HC12 prologue analysis.  */
00406 
00407 #define MAX_CODES 12
00408 
00409 /* 68HC11 opcodes.  */
00410 #undef M6811_OP_PAGE2
00411 #define M6811_OP_PAGE2   (0x18)
00412 #define M6811_OP_LDX     (0xde)
00413 #define M6811_OP_LDX_EXT (0xfe)
00414 #define M6811_OP_PSHX    (0x3c)
00415 #define M6811_OP_STS     (0x9f)
00416 #define M6811_OP_STS_EXT (0xbf)
00417 #define M6811_OP_TSX     (0x30)
00418 #define M6811_OP_XGDX    (0x8f)
00419 #define M6811_OP_ADDD    (0xc3)
00420 #define M6811_OP_TXS     (0x35)
00421 #define M6811_OP_DES     (0x34)
00422 
00423 /* 68HC12 opcodes.  */
00424 #define M6812_OP_PAGE2   (0x18)
00425 #define M6812_OP_MOVW    (0x01)
00426 #define M6812_PB_PSHW    (0xae)
00427 #define M6812_OP_STS     (0x5f)
00428 #define M6812_OP_STS_EXT (0x7f)
00429 #define M6812_OP_LEAS    (0x1b)
00430 #define M6812_OP_PSHX    (0x34)
00431 #define M6812_OP_PSHY    (0x35)
00432 
00433 /* Operand extraction.  */
00434 #define OP_DIRECT      (0x100) /* 8-byte direct addressing.  */
00435 #define OP_IMM_LOW     (0x200) /* Low part of 16-bit constant/address.  */
00436 #define OP_IMM_HIGH    (0x300) /* High part of 16-bit constant/address.  */
00437 #define OP_PBYTE       (0x400) /* 68HC12 indexed operand.  */
00438 
00439 /* Identification of the sequence.  */
00440 enum m6811_seq_type
00441 {
00442   P_LAST = 0,
00443   P_SAVE_REG,  /* Save a register on the stack.  */
00444   P_SET_FRAME, /* Setup the frame pointer.  */
00445   P_LOCAL_1,   /* Allocate 1 byte for locals.  */
00446   P_LOCAL_2,   /* Allocate 2 bytes for locals.  */
00447   P_LOCAL_N    /* Allocate N bytes for locals.  */
00448 };
00449 
00450 struct insn_sequence {
00451   enum m6811_seq_type type;
00452   unsigned length;
00453   unsigned short code[MAX_CODES];
00454 };
00455 
00456 /* Sequence of instructions in the 68HC11 function prologue.  */
00457 static struct insn_sequence m6811_prologue[] = {
00458   /* Sequences to save a soft-register.  */
00459   { P_SAVE_REG, 3, { M6811_OP_LDX, OP_DIRECT,
00460                      M6811_OP_PSHX } },
00461   { P_SAVE_REG, 5, { M6811_OP_PAGE2, M6811_OP_LDX, OP_DIRECT,
00462                      M6811_OP_PAGE2, M6811_OP_PSHX } },
00463   { P_SAVE_REG, 4, { M6811_OP_LDX_EXT, OP_IMM_HIGH, OP_IMM_LOW,
00464                      M6811_OP_PSHX } },
00465   { P_SAVE_REG, 6, { M6811_OP_PAGE2, M6811_OP_LDX_EXT, OP_IMM_HIGH, OP_IMM_LOW,
00466                      M6811_OP_PAGE2, M6811_OP_PSHX } },
00467 
00468   /* Sequences to allocate local variables.  */
00469   { P_LOCAL_N,  7, { M6811_OP_TSX,
00470                      M6811_OP_XGDX,
00471                      M6811_OP_ADDD, OP_IMM_HIGH, OP_IMM_LOW,
00472                      M6811_OP_XGDX,
00473                      M6811_OP_TXS } },
00474   { P_LOCAL_N, 11, { M6811_OP_PAGE2, M6811_OP_TSX,
00475                      M6811_OP_PAGE2, M6811_OP_XGDX,
00476                      M6811_OP_ADDD, OP_IMM_HIGH, OP_IMM_LOW,
00477                      M6811_OP_PAGE2, M6811_OP_XGDX,
00478                      M6811_OP_PAGE2, M6811_OP_TXS } },
00479   { P_LOCAL_1,  1, { M6811_OP_DES } },
00480   { P_LOCAL_2,  1, { M6811_OP_PSHX } },
00481   { P_LOCAL_2,  2, { M6811_OP_PAGE2, M6811_OP_PSHX } },
00482 
00483   /* Initialize the frame pointer.  */
00484   { P_SET_FRAME, 2, { M6811_OP_STS, OP_DIRECT } },
00485   { P_SET_FRAME, 3, { M6811_OP_STS_EXT, OP_IMM_HIGH, OP_IMM_LOW } },
00486   { P_LAST, 0, { 0 } }
00487 };
00488 
00489 
00490 /* Sequence of instructions in the 68HC12 function prologue.  */
00491 static struct insn_sequence m6812_prologue[] = {  
00492   { P_SAVE_REG,  5, { M6812_OP_PAGE2, M6812_OP_MOVW, M6812_PB_PSHW,
00493                       OP_IMM_HIGH, OP_IMM_LOW } },
00494   { P_SET_FRAME, 2, { M6812_OP_STS, OP_DIRECT } },
00495   { P_SET_FRAME, 3, { M6812_OP_STS_EXT, OP_IMM_HIGH, OP_IMM_LOW } },
00496   { P_LOCAL_N,   2, { M6812_OP_LEAS, OP_PBYTE } },
00497   { P_LOCAL_2,   1, { M6812_OP_PSHX } },
00498   { P_LOCAL_2,   1, { M6812_OP_PSHY } },
00499   { P_LAST, 0 }
00500 };
00501 
00502 
00503 /* Analyze the sequence of instructions starting at the given address.
00504    Returns a pointer to the sequence when it is recognized and
00505    the optional value (constant/address) associated with it.  */
00506 static struct insn_sequence *
00507 m68hc11_analyze_instruction (struct gdbarch *gdbarch,
00508                              struct insn_sequence *seq, CORE_ADDR pc,
00509                              CORE_ADDR *val)
00510 {
00511   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
00512   unsigned char buffer[MAX_CODES];
00513   unsigned bufsize;
00514   unsigned j;
00515   CORE_ADDR cur_val;
00516   short v = 0;
00517 
00518   bufsize = 0;
00519   for (; seq->type != P_LAST; seq++)
00520     {
00521       cur_val = 0;
00522       for (j = 0; j < seq->length; j++)
00523         {
00524           if (bufsize < j + 1)
00525             {
00526               buffer[bufsize] = read_memory_unsigned_integer (pc + bufsize,
00527                                                               1, byte_order);
00528               bufsize++;
00529             }
00530           /* Continue while we match the opcode.  */
00531           if (seq->code[j] == buffer[j])
00532             continue;
00533           
00534           if ((seq->code[j] & 0xf00) == 0)
00535             break;
00536           
00537           /* Extract a sequence parameter (address or constant).  */
00538           switch (seq->code[j])
00539             {
00540             case OP_DIRECT:
00541               cur_val = (CORE_ADDR) buffer[j];
00542               break;
00543 
00544             case OP_IMM_HIGH:
00545               cur_val = cur_val & 0x0ff;
00546               cur_val |= (buffer[j] << 8);
00547               break;
00548 
00549             case OP_IMM_LOW:
00550               cur_val &= 0x0ff00;
00551               cur_val |= buffer[j];
00552               break;
00553 
00554             case OP_PBYTE:
00555               if ((buffer[j] & 0xE0) == 0x80)
00556                 {
00557                   v = buffer[j] & 0x1f;
00558                   if (v & 0x10)
00559                     v |= 0xfff0;
00560                 }
00561               else if ((buffer[j] & 0xfe) == 0xf0)
00562                 {
00563                   v = read_memory_unsigned_integer (pc + j + 1, 1, byte_order);
00564                   if (buffer[j] & 1)
00565                     v |= 0xff00;
00566                 }
00567               else if (buffer[j] == 0xf2)
00568                 {
00569                   v = read_memory_unsigned_integer (pc + j + 1, 2, byte_order);
00570                 }
00571               cur_val = v;
00572               break;
00573             }
00574         }
00575 
00576       /* We have a full match.  */
00577       if (j == seq->length)
00578         {
00579           *val = cur_val;
00580           return seq;
00581         }
00582     }
00583   return 0;
00584 }
00585 
00586 /* Return the instruction that the function at the PC is using.  */
00587 static enum insn_return_kind
00588 m68hc11_get_return_insn (CORE_ADDR pc)
00589 {
00590   struct bound_minimal_symbol sym;
00591 
00592   /* A flag indicating that this is a STO_M68HC12_FAR or STO_M68HC12_INTERRUPT
00593      function is stored by elfread.c in the high bit of the info field.
00594      Use this to decide which instruction the function uses to return.  */
00595   sym = lookup_minimal_symbol_by_pc (pc);
00596   if (sym.minsym == 0)
00597     return RETURN_RTS;
00598 
00599   if (MSYMBOL_IS_RTC (sym.minsym))
00600     return RETURN_RTC;
00601   else if (MSYMBOL_IS_RTI (sym.minsym))
00602     return RETURN_RTI;
00603   else
00604     return RETURN_RTS;
00605 }
00606 
00607 /* Analyze the function prologue to find some information
00608    about the function:
00609     - the PC of the first line (for m68hc11_skip_prologue)
00610     - the offset of the previous frame saved address (from current frame)
00611     - the soft registers which are pushed.  */
00612 static CORE_ADDR
00613 m68hc11_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
00614                        CORE_ADDR current_pc, struct m68hc11_unwind_cache *info)
00615 {
00616   LONGEST save_addr;
00617   CORE_ADDR func_end;
00618   int size;
00619   int found_frame_point;
00620   int saved_reg;
00621   int done = 0;
00622   struct insn_sequence *seq_table;
00623 
00624   info->size = 0;
00625   info->sp_offset = 0;
00626   if (pc >= current_pc)
00627     return current_pc;
00628 
00629   size = 0;
00630 
00631   m68hc11_initialize_register_info ();
00632   if (pc == 0)
00633     {
00634       info->size = 0;
00635       return pc;
00636     }
00637 
00638   seq_table = gdbarch_tdep (gdbarch)->prologue;
00639   
00640   /* The 68hc11 stack is as follows:
00641 
00642 
00643      |           |
00644      +-----------+
00645      |           |
00646      | args      |
00647      |           |
00648      +-----------+
00649      | PC-return |
00650      +-----------+
00651      | Old frame |
00652      +-----------+
00653      |           |
00654      | Locals    |
00655      |           |
00656      +-----------+ <--- current frame
00657      |           |
00658 
00659      With most processors (like 68K) the previous frame can be computed
00660      easily because it is always at a fixed offset (see link/unlink).
00661      That is, locals are accessed with negative offsets, arguments are
00662      accessed with positive ones.  Since 68hc11 only supports offsets
00663      in the range [0..255], the frame is defined at the bottom of
00664      locals (see picture).
00665 
00666      The purpose of the analysis made here is to find out the size
00667      of locals in this function.  An alternative to this is to use
00668      DWARF2 info.  This would be better but I don't know how to
00669      access dwarf2 debug from this function.
00670      
00671      Walk from the function entry point to the point where we save
00672      the frame.  While walking instructions, compute the size of bytes
00673      which are pushed.  This gives us the index to access the previous
00674      frame.
00675 
00676      We limit the search to 128 bytes so that the algorithm is bounded
00677      in case of random and wrong code.  We also stop and abort if
00678      we find an instruction which is not supposed to appear in the
00679      prologue (as generated by gcc 2.95, 2.96).  */
00680 
00681   func_end = pc + 128;
00682   found_frame_point = 0;
00683   info->size = 0;
00684   save_addr = 0;
00685   while (!done && pc + 2 < func_end)
00686     {
00687       struct insn_sequence *seq;
00688       CORE_ADDR val;
00689 
00690       seq = m68hc11_analyze_instruction (gdbarch, seq_table, pc, &val);
00691       if (seq == 0)
00692         break;
00693 
00694       /* If we are within the instruction group, we can't advance the
00695          pc nor the stack offset.  Otherwise the caller's stack computed
00696          from the current stack can be wrong.  */
00697       if (pc + seq->length > current_pc)
00698         break;
00699 
00700       pc = pc + seq->length;
00701       if (seq->type == P_SAVE_REG)
00702         {
00703           if (found_frame_point)
00704             {
00705               saved_reg = m68hc11_which_soft_register (val);
00706               if (saved_reg < 0)
00707                 break;
00708 
00709               save_addr -= 2;
00710               if (info->saved_regs)
00711                 info->saved_regs[saved_reg].addr = save_addr;
00712             }
00713           else
00714             {
00715               size += 2;
00716             }
00717         }
00718       else if (seq->type == P_SET_FRAME)
00719         {
00720           found_frame_point = 1;
00721           info->size = size;
00722         }
00723       else if (seq->type == P_LOCAL_1)
00724         {
00725           size += 1;
00726         }
00727       else if (seq->type == P_LOCAL_2)
00728         {
00729           size += 2;
00730         }
00731       else if (seq->type == P_LOCAL_N)
00732         {
00733           /* Stack pointer is decremented for the allocation.  */
00734           if (val & 0x8000)
00735             size -= (int) (val) | 0xffff0000;
00736           else
00737             size -= val;
00738         }
00739     }
00740   if (found_frame_point == 0)
00741     info->sp_offset = size;
00742   else
00743     info->sp_offset = -1;
00744   return pc;
00745 }
00746 
00747 static CORE_ADDR
00748 m68hc11_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
00749 {
00750   CORE_ADDR func_addr, func_end;
00751   struct symtab_and_line sal;
00752   struct m68hc11_unwind_cache tmp_cache = { 0 };
00753 
00754   /* If we have line debugging information, then the end of the
00755      prologue should be the first assembly instruction of the
00756      first source line.  */
00757   if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
00758     {
00759       sal = find_pc_line (func_addr, 0);
00760       if (sal.end && sal.end < func_end)
00761         return sal.end;
00762     }
00763 
00764   pc = m68hc11_scan_prologue (gdbarch, pc, (CORE_ADDR) -1, &tmp_cache);
00765   return pc;
00766 }
00767 
00768 static CORE_ADDR
00769 m68hc11_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
00770 {
00771   ULONGEST pc;
00772 
00773   pc = frame_unwind_register_unsigned (next_frame,
00774                                        gdbarch_pc_regnum (gdbarch));
00775   return pc;
00776 }
00777 
00778 /* Put here the code to store, into fi->saved_regs, the addresses of
00779    the saved registers of frame described by FRAME_INFO.  This
00780    includes special registers such as pc and fp saved in special ways
00781    in the stack frame.  sp is even more special: the address we return
00782    for it IS the sp for the next frame.  */
00783 
00784 static struct m68hc11_unwind_cache *
00785 m68hc11_frame_unwind_cache (struct frame_info *this_frame,
00786                             void **this_prologue_cache)
00787 {
00788   struct gdbarch *gdbarch = get_frame_arch (this_frame);
00789   ULONGEST prev_sp;
00790   ULONGEST this_base;
00791   struct m68hc11_unwind_cache *info;
00792   CORE_ADDR current_pc;
00793   int i;
00794 
00795   if ((*this_prologue_cache))
00796     return (*this_prologue_cache);
00797 
00798   info = FRAME_OBSTACK_ZALLOC (struct m68hc11_unwind_cache);
00799   (*this_prologue_cache) = info;
00800   info->saved_regs = trad_frame_alloc_saved_regs (this_frame);
00801 
00802   info->pc = get_frame_func (this_frame);
00803 
00804   info->size = 0;
00805   info->return_kind = m68hc11_get_return_insn (info->pc);
00806 
00807   /* The SP was moved to the FP.  This indicates that a new frame
00808      was created.  Get THIS frame's FP value by unwinding it from
00809      the next frame.  */
00810   this_base = get_frame_register_unsigned (this_frame, SOFT_FP_REGNUM);
00811   if (this_base == 0)
00812     {
00813       info->base = 0;
00814       return info;
00815     }
00816 
00817   current_pc = get_frame_pc (this_frame);
00818   if (info->pc != 0)
00819     m68hc11_scan_prologue (gdbarch, info->pc, current_pc, info);
00820 
00821   info->saved_regs[HARD_PC_REGNUM].addr = info->size;
00822 
00823   if (info->sp_offset != (CORE_ADDR) -1)
00824     {
00825       info->saved_regs[HARD_PC_REGNUM].addr = info->sp_offset;
00826       this_base = get_frame_register_unsigned (this_frame, HARD_SP_REGNUM);
00827       prev_sp = this_base + info->sp_offset + 2;
00828       this_base += STACK_CORRECTION (gdbarch);
00829     }
00830   else
00831     {
00832       /* The FP points at the last saved register.  Adjust the FP back
00833          to before the first saved register giving the SP.  */
00834       prev_sp = this_base + info->size + 2;
00835 
00836       this_base += STACK_CORRECTION (gdbarch);
00837       if (soft_regs[SOFT_FP_REGNUM].name)
00838         info->saved_regs[SOFT_FP_REGNUM].addr = info->size - 2;
00839    }
00840 
00841   if (info->return_kind == RETURN_RTC)
00842     {
00843       prev_sp += 1;
00844       info->saved_regs[HARD_PAGE_REGNUM].addr = info->size;
00845       info->saved_regs[HARD_PC_REGNUM].addr = info->size + 1;
00846     }
00847   else if (info->return_kind == RETURN_RTI)
00848     {
00849       prev_sp += 7;
00850       info->saved_regs[HARD_CCR_REGNUM].addr = info->size;
00851       info->saved_regs[HARD_D_REGNUM].addr = info->size + 1;
00852       info->saved_regs[HARD_X_REGNUM].addr = info->size + 3;
00853       info->saved_regs[HARD_Y_REGNUM].addr = info->size + 5;
00854       info->saved_regs[HARD_PC_REGNUM].addr = info->size + 7;
00855     }
00856 
00857   /* Add 1 here to adjust for the post-decrement nature of the push
00858      instruction.  */
00859   info->prev_sp = prev_sp;
00860 
00861   info->base = this_base;
00862 
00863   /* Adjust all the saved registers so that they contain addresses and not
00864      offsets.  */
00865   for (i = 0;
00866        i < gdbarch_num_regs (gdbarch)
00867            + gdbarch_num_pseudo_regs (gdbarch) - 1;
00868        i++)
00869     if (trad_frame_addr_p (info->saved_regs, i))
00870       {
00871         info->saved_regs[i].addr += this_base;
00872       }
00873 
00874   /* The previous frame's SP needed to be computed.  Save the computed
00875      value.  */
00876   trad_frame_set_value (info->saved_regs, HARD_SP_REGNUM, info->prev_sp);
00877 
00878   return info;
00879 }
00880 
00881 /* Given a GDB frame, determine the address of the calling function's
00882    frame.  This will be used to create a new GDB frame struct.  */
00883 
00884 static void
00885 m68hc11_frame_this_id (struct frame_info *this_frame,
00886                        void **this_prologue_cache,
00887                        struct frame_id *this_id)
00888 {
00889   struct m68hc11_unwind_cache *info
00890     = m68hc11_frame_unwind_cache (this_frame, this_prologue_cache);
00891   CORE_ADDR base;
00892   CORE_ADDR func;
00893   struct frame_id id;
00894 
00895   /* The FUNC is easy.  */
00896   func = get_frame_func (this_frame);
00897 
00898   /* Hopefully the prologue analysis either correctly determined the
00899      frame's base (which is the SP from the previous frame), or set
00900      that base to "NULL".  */
00901   base = info->prev_sp;
00902   if (base == 0)
00903     return;
00904 
00905   id = frame_id_build (base, func);
00906   (*this_id) = id;
00907 }
00908 
00909 static struct value *
00910 m68hc11_frame_prev_register (struct frame_info *this_frame,
00911                              void **this_prologue_cache, int regnum)
00912 {
00913   struct value *value;
00914   struct m68hc11_unwind_cache *info
00915     = m68hc11_frame_unwind_cache (this_frame, this_prologue_cache);
00916 
00917   value = trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
00918 
00919   /* Take into account the 68HC12 specific call (PC + page).  */
00920   if (regnum == HARD_PC_REGNUM
00921       && info->return_kind == RETURN_RTC
00922       && USE_PAGE_REGISTER (get_frame_arch (this_frame)))
00923     {
00924       CORE_ADDR pc = value_as_long (value);
00925       if (pc >= 0x08000 && pc < 0x0c000)
00926         {
00927           CORE_ADDR page;
00928 
00929           release_value (value);
00930           value_free (value);
00931 
00932           value = trad_frame_get_prev_register (this_frame, info->saved_regs,
00933                                                 HARD_PAGE_REGNUM);
00934           page = value_as_long (value);
00935           release_value (value);
00936           value_free (value);
00937 
00938           pc -= 0x08000;
00939           pc += ((page & 0x0ff) << 14);
00940           pc += 0x1000000;
00941 
00942           return frame_unwind_got_constant (this_frame, regnum, pc);
00943         }
00944     }
00945 
00946   return value;
00947 }
00948 
00949 static const struct frame_unwind m68hc11_frame_unwind = {
00950   NORMAL_FRAME,
00951   default_frame_unwind_stop_reason,
00952   m68hc11_frame_this_id,
00953   m68hc11_frame_prev_register,
00954   NULL,
00955   default_frame_sniffer
00956 };
00957 
00958 static CORE_ADDR
00959 m68hc11_frame_base_address (struct frame_info *this_frame, void **this_cache)
00960 {
00961   struct m68hc11_unwind_cache *info
00962     = m68hc11_frame_unwind_cache (this_frame, this_cache);
00963 
00964   return info->base;
00965 }
00966 
00967 static CORE_ADDR
00968 m68hc11_frame_args_address (struct frame_info *this_frame, void **this_cache)
00969 {
00970   CORE_ADDR addr;
00971   struct m68hc11_unwind_cache *info
00972     = m68hc11_frame_unwind_cache (this_frame, this_cache);
00973 
00974   addr = info->base + info->size;
00975   if (info->return_kind == RETURN_RTC)
00976     addr += 1;
00977   else if (info->return_kind == RETURN_RTI)
00978     addr += 7;
00979 
00980   return addr;
00981 }
00982 
00983 static const struct frame_base m68hc11_frame_base = {
00984   &m68hc11_frame_unwind,
00985   m68hc11_frame_base_address,
00986   m68hc11_frame_base_address,
00987   m68hc11_frame_args_address
00988 };
00989 
00990 static CORE_ADDR
00991 m68hc11_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
00992 {
00993   ULONGEST sp;
00994   sp = frame_unwind_register_unsigned (next_frame, HARD_SP_REGNUM);
00995   return sp;
00996 }
00997 
00998 /* Assuming THIS_FRAME is a dummy, return the frame ID of that dummy
00999    frame.  The frame ID's base needs to match the TOS value saved by
01000    save_dummy_frame_tos(), and the PC match the dummy frame's breakpoint.  */
01001 
01002 static struct frame_id
01003 m68hc11_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
01004 {
01005   ULONGEST tos;
01006   CORE_ADDR pc = get_frame_pc (this_frame);
01007 
01008   tos = get_frame_register_unsigned (this_frame, SOFT_FP_REGNUM);
01009   tos += 2;
01010   return frame_id_build (tos, pc);
01011 }
01012 
01013 
01014 /* Get and print the register from the given frame.  */
01015 static void
01016 m68hc11_print_register (struct gdbarch *gdbarch, struct ui_file *file,
01017                         struct frame_info *frame, int regno)
01018 {
01019   LONGEST rval;
01020 
01021   if (regno == HARD_PC_REGNUM || regno == HARD_SP_REGNUM
01022       || regno == SOFT_FP_REGNUM || regno == M68HC12_HARD_PC_REGNUM)
01023     rval = get_frame_register_unsigned (frame, regno);
01024   else
01025     rval = get_frame_register_signed (frame, regno);
01026 
01027   if (regno == HARD_A_REGNUM || regno == HARD_B_REGNUM
01028       || regno == HARD_CCR_REGNUM || regno == HARD_PAGE_REGNUM)
01029     {
01030       fprintf_filtered (file, "0x%02x   ", (unsigned char) rval);
01031       if (regno != HARD_CCR_REGNUM)
01032         print_longest (file, 'd', 1, rval);
01033     }
01034   else
01035     {
01036       if (regno == HARD_PC_REGNUM && gdbarch_tdep (gdbarch)->use_page_register)
01037         {
01038           ULONGEST page;
01039 
01040           page = get_frame_register_unsigned (frame, HARD_PAGE_REGNUM);
01041           fprintf_filtered (file, "0x%02x:%04x ", (unsigned) page,
01042                             (unsigned) rval);
01043         }
01044       else
01045         {
01046           fprintf_filtered (file, "0x%04x ", (unsigned) rval);
01047           if (regno != HARD_PC_REGNUM && regno != HARD_SP_REGNUM
01048               && regno != SOFT_FP_REGNUM && regno != M68HC12_HARD_PC_REGNUM)
01049             print_longest (file, 'd', 1, rval);
01050         }
01051     }
01052 
01053   if (regno == HARD_CCR_REGNUM)
01054     {
01055       /* CCR register */
01056       int C, Z, N, V;
01057       unsigned char l = rval & 0xff;
01058 
01059       fprintf_filtered (file, "%c%c%c%c%c%c%c%c   ",
01060                         l & M6811_S_BIT ? 'S' : '-',
01061                         l & M6811_X_BIT ? 'X' : '-',
01062                         l & M6811_H_BIT ? 'H' : '-',
01063                         l & M6811_I_BIT ? 'I' : '-',
01064                         l & M6811_N_BIT ? 'N' : '-',
01065                         l & M6811_Z_BIT ? 'Z' : '-',
01066                         l & M6811_V_BIT ? 'V' : '-',
01067                         l & M6811_C_BIT ? 'C' : '-');
01068       N = (l & M6811_N_BIT) != 0;
01069       Z = (l & M6811_Z_BIT) != 0;
01070       V = (l & M6811_V_BIT) != 0;
01071       C = (l & M6811_C_BIT) != 0;
01072 
01073       /* Print flags following the h8300.  */
01074       if ((C | Z) == 0)
01075         fprintf_filtered (file, "u> ");
01076       else if ((C | Z) == 1)
01077         fprintf_filtered (file, "u<= ");
01078       else if (C == 0)
01079         fprintf_filtered (file, "u< ");
01080 
01081       if (Z == 0)
01082         fprintf_filtered (file, "!= ");
01083       else
01084         fprintf_filtered (file, "== ");
01085 
01086       if ((N ^ V) == 0)
01087         fprintf_filtered (file, ">= ");
01088       else
01089         fprintf_filtered (file, "< ");
01090 
01091       if ((Z | (N ^ V)) == 0)
01092         fprintf_filtered (file, "> ");
01093       else
01094         fprintf_filtered (file, "<= ");
01095     }
01096 }
01097 
01098 /* Same as 'info reg' but prints the registers in a different way.  */
01099 static void
01100 m68hc11_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
01101                               struct frame_info *frame, int regno, int cpregs)
01102 {
01103   if (regno >= 0)
01104     {
01105       const char *name = gdbarch_register_name (gdbarch, regno);
01106 
01107       if (!name || !*name)
01108         return;
01109 
01110       fprintf_filtered (file, "%-10s ", name);
01111       m68hc11_print_register (gdbarch, file, frame, regno);
01112       fprintf_filtered (file, "\n");
01113     }
01114   else
01115     {
01116       int i, nr;
01117 
01118       fprintf_filtered (file, "PC=");
01119       m68hc11_print_register (gdbarch, file, frame, HARD_PC_REGNUM);
01120 
01121       fprintf_filtered (file, " SP=");
01122       m68hc11_print_register (gdbarch, file, frame, HARD_SP_REGNUM);
01123 
01124       fprintf_filtered (file, " FP=");
01125       m68hc11_print_register (gdbarch, file, frame, SOFT_FP_REGNUM);
01126 
01127       fprintf_filtered (file, "\nCCR=");
01128       m68hc11_print_register (gdbarch, file, frame, HARD_CCR_REGNUM);
01129       
01130       fprintf_filtered (file, "\nD=");
01131       m68hc11_print_register (gdbarch, file, frame, HARD_D_REGNUM);
01132 
01133       fprintf_filtered (file, " X=");
01134       m68hc11_print_register (gdbarch, file, frame, HARD_X_REGNUM);
01135 
01136       fprintf_filtered (file, " Y=");
01137       m68hc11_print_register (gdbarch, file, frame, HARD_Y_REGNUM);
01138   
01139       if (gdbarch_tdep (gdbarch)->use_page_register)
01140         {
01141           fprintf_filtered (file, "\nPage=");
01142           m68hc11_print_register (gdbarch, file, frame, HARD_PAGE_REGNUM);
01143         }
01144       fprintf_filtered (file, "\n");
01145 
01146       nr = 0;
01147       for (i = SOFT_D1_REGNUM; i < M68HC11_ALL_REGS; i++)
01148         {
01149           /* Skip registers which are not defined in the symbol table.  */
01150           if (soft_regs[i].name == 0)
01151             continue;
01152           
01153           fprintf_filtered (file, "D%d=", i - SOFT_D1_REGNUM + 1);
01154           m68hc11_print_register (gdbarch, file, frame, i);
01155           nr++;
01156           if ((nr % 8) == 7)
01157             fprintf_filtered (file, "\n");
01158           else
01159             fprintf_filtered (file, " ");
01160         }
01161       if (nr && (nr % 8) != 7)
01162         fprintf_filtered (file, "\n");
01163     }
01164 }
01165 
01166 static CORE_ADDR
01167 m68hc11_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
01168                          struct regcache *regcache, CORE_ADDR bp_addr,
01169                          int nargs, struct value **args, CORE_ADDR sp,
01170                          int struct_return, CORE_ADDR struct_addr)
01171 {
01172   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
01173   int argnum;
01174   int first_stack_argnum;
01175   struct type *type;
01176   const gdb_byte *val;
01177   gdb_byte buf[2];
01178   
01179   first_stack_argnum = 0;
01180   if (struct_return)
01181     {
01182       regcache_cooked_write_unsigned (regcache, HARD_D_REGNUM, struct_addr);
01183     }
01184   else if (nargs > 0)
01185     {
01186       type = value_type (args[0]);
01187 
01188       /* First argument is passed in D and X registers.  */
01189       if (TYPE_LENGTH (type) <= 4)
01190         {
01191           ULONGEST v;
01192 
01193           v = extract_unsigned_integer (value_contents (args[0]),
01194                                         TYPE_LENGTH (type), byte_order);
01195           first_stack_argnum = 1;
01196 
01197           regcache_cooked_write_unsigned (regcache, HARD_D_REGNUM, v);
01198           if (TYPE_LENGTH (type) > 2)
01199             {
01200               v >>= 16;
01201               regcache_cooked_write_unsigned (regcache, HARD_X_REGNUM, v);
01202             }
01203         }
01204     }
01205 
01206   for (argnum = nargs - 1; argnum >= first_stack_argnum; argnum--)
01207     {
01208       type = value_type (args[argnum]);
01209 
01210       if (TYPE_LENGTH (type) & 1)
01211         {
01212           static gdb_byte zero = 0;
01213 
01214           sp--;
01215           write_memory (sp, &zero, 1);
01216         }
01217       val = value_contents (args[argnum]);
01218       sp -= TYPE_LENGTH (type);
01219       write_memory (sp, val, TYPE_LENGTH (type));
01220     }
01221 
01222   /* Store return address.  */
01223   sp -= 2;
01224   store_unsigned_integer (buf, 2, byte_order, bp_addr);
01225   write_memory (sp, buf, 2);
01226 
01227   /* Finally, update the stack pointer...  */
01228   sp -= STACK_CORRECTION (gdbarch);
01229   regcache_cooked_write_unsigned (regcache, HARD_SP_REGNUM, sp);
01230 
01231   /* ...and fake a frame pointer.  */
01232   regcache_cooked_write_unsigned (regcache, SOFT_FP_REGNUM, sp);
01233 
01234   /* DWARF2/GCC uses the stack address *before* the function call as a
01235      frame's CFA.  */
01236   return sp + 2;
01237 }
01238 
01239 
01240 /* Return the GDB type object for the "standard" data type
01241    of data in register N.  */
01242 
01243 static struct type *
01244 m68hc11_register_type (struct gdbarch *gdbarch, int reg_nr)
01245 {
01246   switch (reg_nr)
01247     {
01248     case HARD_PAGE_REGNUM:
01249     case HARD_A_REGNUM:
01250     case HARD_B_REGNUM:
01251     case HARD_CCR_REGNUM:
01252       return builtin_type (gdbarch)->builtin_uint8;
01253 
01254     case M68HC12_HARD_PC_REGNUM:
01255       return builtin_type (gdbarch)->builtin_uint32;
01256 
01257     default:
01258       return builtin_type (gdbarch)->builtin_uint16;
01259     }
01260 }
01261 
01262 static void
01263 m68hc11_store_return_value (struct type *type, struct regcache *regcache,
01264                             const gdb_byte *valbuf)
01265 {
01266   int len;
01267 
01268   len = TYPE_LENGTH (type);
01269 
01270   /* First argument is passed in D and X registers.  */
01271   if (len <= 2)
01272     regcache_raw_write_part (regcache, HARD_D_REGNUM, 2 - len, len, valbuf);
01273   else if (len <= 4)
01274     {
01275       regcache_raw_write_part (regcache, HARD_X_REGNUM, 4 - len,
01276                                len - 2, valbuf);
01277       regcache_raw_write (regcache, HARD_D_REGNUM, valbuf + (len - 2));
01278     }
01279   else
01280     error (_("return of value > 4 is not supported."));
01281 }
01282 
01283 
01284 /* Given a return value in `regcache' with a type `type', 
01285    extract and copy its value into `valbuf'.  */
01286 
01287 static void
01288 m68hc11_extract_return_value (struct type *type, struct regcache *regcache,
01289                               void *valbuf)
01290 {
01291   gdb_byte buf[M68HC11_REG_SIZE];
01292 
01293   regcache_raw_read (regcache, HARD_D_REGNUM, buf);
01294   switch (TYPE_LENGTH (type))
01295     {
01296     case 1:
01297       memcpy (valbuf, buf + 1, 1);
01298       break;
01299 
01300     case 2:
01301       memcpy (valbuf, buf, 2);
01302       break;
01303 
01304     case 3:
01305       memcpy ((char*) valbuf + 1, buf, 2);
01306       regcache_raw_read (regcache, HARD_X_REGNUM, buf);
01307       memcpy (valbuf, buf + 1, 1);
01308       break;
01309 
01310     case 4:
01311       memcpy ((char*) valbuf + 2, buf, 2);
01312       regcache_raw_read (regcache, HARD_X_REGNUM, buf);
01313       memcpy (valbuf, buf, 2);
01314       break;
01315 
01316     default:
01317       error (_("bad size for return value"));
01318     }
01319 }
01320 
01321 static enum return_value_convention
01322 m68hc11_return_value (struct gdbarch *gdbarch, struct value *function,
01323                       struct type *valtype, struct regcache *regcache,
01324                       gdb_byte *readbuf, const gdb_byte *writebuf)
01325 {
01326   if (TYPE_CODE (valtype) == TYPE_CODE_STRUCT
01327       || TYPE_CODE (valtype) == TYPE_CODE_UNION
01328       || TYPE_CODE (valtype) == TYPE_CODE_ARRAY 
01329       || TYPE_LENGTH (valtype) > 4)
01330     return RETURN_VALUE_STRUCT_CONVENTION;
01331   else
01332     {
01333       if (readbuf != NULL)
01334         m68hc11_extract_return_value (valtype, regcache, readbuf);
01335       if (writebuf != NULL)
01336         m68hc11_store_return_value (valtype, regcache, writebuf);
01337       return RETURN_VALUE_REGISTER_CONVENTION;
01338     }
01339 }
01340 
01341 /* Test whether the ELF symbol corresponds to a function using rtc or
01342    rti to return.  */
01343    
01344 static void
01345 m68hc11_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
01346 {
01347   unsigned char flags;
01348 
01349   flags = ((elf_symbol_type *)sym)->internal_elf_sym.st_other;
01350   if (flags & STO_M68HC12_FAR)
01351     MSYMBOL_SET_RTC (msym);
01352   if (flags & STO_M68HC12_INTERRUPT)
01353     MSYMBOL_SET_RTI (msym);
01354 }
01355 
01356 static int
01357 gdb_print_insn_m68hc11 (bfd_vma memaddr, disassemble_info *info)
01358 {
01359   if (info->arch == bfd_arch_m68hc11)
01360     return print_insn_m68hc11 (memaddr, info);
01361   else
01362     return print_insn_m68hc12 (memaddr, info);
01363 }
01364 
01365 
01366 
01367 /* 68HC11/68HC12 register groups.
01368    Identify real hard registers and soft registers used by gcc.  */
01369 
01370 static struct reggroup *m68hc11_soft_reggroup;
01371 static struct reggroup *m68hc11_hard_reggroup;
01372 
01373 static void
01374 m68hc11_init_reggroups (void)
01375 {
01376   m68hc11_hard_reggroup = reggroup_new ("hard", USER_REGGROUP);
01377   m68hc11_soft_reggroup = reggroup_new ("soft", USER_REGGROUP);
01378 }
01379 
01380 static void
01381 m68hc11_add_reggroups (struct gdbarch *gdbarch)
01382 {
01383   reggroup_add (gdbarch, m68hc11_hard_reggroup);
01384   reggroup_add (gdbarch, m68hc11_soft_reggroup);
01385   reggroup_add (gdbarch, general_reggroup);
01386   reggroup_add (gdbarch, float_reggroup);
01387   reggroup_add (gdbarch, all_reggroup);
01388   reggroup_add (gdbarch, save_reggroup);
01389   reggroup_add (gdbarch, restore_reggroup);
01390   reggroup_add (gdbarch, vector_reggroup);
01391   reggroup_add (gdbarch, system_reggroup);
01392 }
01393 
01394 static int
01395 m68hc11_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
01396                              struct reggroup *group)
01397 {
01398   /* We must save the real hard register as well as gcc
01399      soft registers including the frame pointer.  */
01400   if (group == save_reggroup || group == restore_reggroup)
01401     {
01402       return (regnum <= gdbarch_num_regs (gdbarch)
01403               || ((regnum == SOFT_FP_REGNUM
01404                    || regnum == SOFT_TMP_REGNUM
01405                    || regnum == SOFT_ZS_REGNUM
01406                    || regnum == SOFT_XY_REGNUM)
01407                   && m68hc11_register_name (gdbarch, regnum)));
01408     }
01409 
01410   /* Group to identify gcc soft registers (d1..dN).  */
01411   if (group == m68hc11_soft_reggroup)
01412     {
01413       return regnum >= SOFT_D1_REGNUM
01414              && m68hc11_register_name (gdbarch, regnum);
01415     }
01416 
01417   if (group == m68hc11_hard_reggroup)
01418     {
01419       return regnum == HARD_PC_REGNUM || regnum == HARD_SP_REGNUM
01420         || regnum == HARD_X_REGNUM || regnum == HARD_D_REGNUM
01421         || regnum == HARD_Y_REGNUM || regnum == HARD_CCR_REGNUM;
01422     }
01423   return default_register_reggroup_p (gdbarch, regnum, group);
01424 }
01425 
01426 static struct gdbarch *
01427 m68hc11_gdbarch_init (struct gdbarch_info info,
01428                       struct gdbarch_list *arches)
01429 {
01430   struct gdbarch *gdbarch;
01431   struct gdbarch_tdep *tdep;
01432   int elf_flags;
01433 
01434   soft_reg_initialized = 0;
01435 
01436   /* Extract the elf_flags if available.  */
01437   if (info.abfd != NULL
01438       && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
01439     elf_flags = elf_elfheader (info.abfd)->e_flags;
01440   else
01441     elf_flags = 0;
01442 
01443   /* Try to find a pre-existing architecture.  */
01444   for (arches = gdbarch_list_lookup_by_info (arches, &info);
01445        arches != NULL;
01446        arches = gdbarch_list_lookup_by_info (arches->next, &info))
01447     {
01448       if (gdbarch_tdep (arches->gdbarch)->elf_flags != elf_flags)
01449         continue;
01450 
01451       return arches->gdbarch;
01452     }
01453 
01454   /* Need a new architecture.  Fill in a target specific vector.  */
01455   tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
01456   gdbarch = gdbarch_alloc (&info, tdep);
01457   tdep->elf_flags = elf_flags;
01458 
01459   switch (info.bfd_arch_info->arch)
01460     {
01461     case bfd_arch_m68hc11:
01462       tdep->stack_correction = 1;
01463       tdep->use_page_register = 0;
01464       tdep->prologue = m6811_prologue;
01465       set_gdbarch_addr_bit (gdbarch, 16);
01466       set_gdbarch_num_pseudo_regs (gdbarch, M68HC11_NUM_PSEUDO_REGS);
01467       set_gdbarch_pc_regnum (gdbarch, HARD_PC_REGNUM);
01468       set_gdbarch_num_regs (gdbarch, M68HC11_NUM_REGS);
01469       break;
01470 
01471     case bfd_arch_m68hc12:
01472       tdep->stack_correction = 0;
01473       tdep->use_page_register = elf_flags & E_M68HC12_BANKS;
01474       tdep->prologue = m6812_prologue;
01475       set_gdbarch_addr_bit (gdbarch, elf_flags & E_M68HC12_BANKS ? 32 : 16);
01476       set_gdbarch_num_pseudo_regs (gdbarch,
01477                                    elf_flags & E_M68HC12_BANKS
01478                                    ? M68HC12_NUM_PSEUDO_REGS
01479                                    : M68HC11_NUM_PSEUDO_REGS);
01480       set_gdbarch_pc_regnum (gdbarch, elf_flags & E_M68HC12_BANKS
01481                              ? M68HC12_HARD_PC_REGNUM : HARD_PC_REGNUM);
01482       set_gdbarch_num_regs (gdbarch, elf_flags & E_M68HC12_BANKS
01483                             ? M68HC12_NUM_REGS : M68HC11_NUM_REGS);
01484       break;
01485 
01486     default:
01487       break;
01488     }
01489 
01490   /* Initially set everything according to the ABI.
01491      Use 16-bit integers since it will be the case for most
01492      programs.  The size of these types should normally be set
01493      according to the dwarf2 debug information.  */
01494   set_gdbarch_short_bit (gdbarch, 16);
01495   set_gdbarch_int_bit (gdbarch, elf_flags & E_M68HC11_I32 ? 32 : 16);
01496   set_gdbarch_float_bit (gdbarch, 32);
01497   if (elf_flags & E_M68HC11_F64)
01498     {
01499       set_gdbarch_double_bit (gdbarch, 64);
01500       set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
01501     }
01502   else
01503     {
01504       set_gdbarch_double_bit (gdbarch, 32);
01505       set_gdbarch_double_format (gdbarch, floatformats_ieee_single);
01506     }
01507   set_gdbarch_long_double_bit (gdbarch, 64);
01508   set_gdbarch_long_bit (gdbarch, 32);
01509   set_gdbarch_ptr_bit (gdbarch, 16);
01510   set_gdbarch_long_long_bit (gdbarch, 64);
01511 
01512   /* Characters are unsigned.  */
01513   set_gdbarch_char_signed (gdbarch, 0);
01514 
01515   set_gdbarch_unwind_pc (gdbarch, m68hc11_unwind_pc);
01516   set_gdbarch_unwind_sp (gdbarch, m68hc11_unwind_sp);
01517 
01518   /* Set register info.  */
01519   set_gdbarch_fp0_regnum (gdbarch, -1);
01520 
01521   set_gdbarch_sp_regnum (gdbarch, HARD_SP_REGNUM);
01522   set_gdbarch_register_name (gdbarch, m68hc11_register_name);
01523   set_gdbarch_register_type (gdbarch, m68hc11_register_type);
01524   set_gdbarch_pseudo_register_read (gdbarch, m68hc11_pseudo_register_read);
01525   set_gdbarch_pseudo_register_write (gdbarch, m68hc11_pseudo_register_write);
01526 
01527   set_gdbarch_push_dummy_call (gdbarch, m68hc11_push_dummy_call);
01528 
01529   set_gdbarch_return_value (gdbarch, m68hc11_return_value);
01530   set_gdbarch_skip_prologue (gdbarch, m68hc11_skip_prologue);
01531   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
01532   set_gdbarch_breakpoint_from_pc (gdbarch, m68hc11_breakpoint_from_pc);
01533   set_gdbarch_print_insn (gdbarch, gdb_print_insn_m68hc11);
01534 
01535   m68hc11_add_reggroups (gdbarch);
01536   set_gdbarch_register_reggroup_p (gdbarch, m68hc11_register_reggroup_p);
01537   set_gdbarch_print_registers_info (gdbarch, m68hc11_print_registers_info);
01538 
01539   /* Hook in the DWARF CFI frame unwinder.  */
01540   dwarf2_append_unwinders (gdbarch);
01541 
01542   frame_unwind_append_unwinder (gdbarch, &m68hc11_frame_unwind);
01543   frame_base_set_default (gdbarch, &m68hc11_frame_base);
01544   
01545   /* Methods for saving / extracting a dummy frame's ID.  The ID's
01546      stack address must match the SP value returned by
01547      PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
01548   set_gdbarch_dummy_id (gdbarch, m68hc11_dummy_id);
01549 
01550   /* Return the unwound PC value.  */
01551   set_gdbarch_unwind_pc (gdbarch, m68hc11_unwind_pc);
01552 
01553   /* Minsymbol frobbing.  */
01554   set_gdbarch_elf_make_msymbol_special (gdbarch,
01555                                         m68hc11_elf_make_msymbol_special);
01556 
01557   set_gdbarch_believe_pcc_promotion (gdbarch, 1);
01558 
01559   return gdbarch;
01560 }
01561 
01562 /* -Wmissing-prototypes */
01563 extern initialize_file_ftype _initialize_m68hc11_tdep;
01564 
01565 void
01566 _initialize_m68hc11_tdep (void)
01567 {
01568   register_gdbarch_init (bfd_arch_m68hc11, m68hc11_gdbarch_init);
01569   register_gdbarch_init (bfd_arch_m68hc12, m68hc11_gdbarch_init);
01570   m68hc11_init_reggroups ();
01571 } 
01572 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines