home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / gnu / gdb-4.14-src.lha / gdb-4.14 / gdb / sp64-tdep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-21  |  7.5 KB  |  289 lines

  1. /* Target-dependent code for the SPARC 64 for GDB, the GNU debugger.
  2.    Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
  3.    Contributed by Doug Evans (dje@cygnus.com).
  4.  
  5. This file is part of GDB.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. #include "defs.h"
  22. #include "frame.h"
  23. #include "inferior.h"
  24. #include "obstack.h"
  25. #include "target.h"
  26.  
  27. /*#include "symfile.h" /* for objfiles.h */
  28. /*#include "objfiles.h" /* for find_pc_section */
  29.  
  30. /* This file contains replacements and additions to sparc-tdep.c only.
  31.    Some of this code has been written for a day when we can merge at least
  32.    some of this with sparc-tdep.c.  Macro TARGET_SPARC64 exists to allow some
  33.    code to potentially be used by both.  */
  34.  
  35. #define TARGET_SPARC64 1    /* later make a config parm or some such */
  36.  
  37. /* From infrun.c */
  38. extern int stop_after_trap;
  39.  
  40. /* Branches with prediction are treated like their non-predicting cousins.  */
  41. /* FIXME: What about floating point branches?  */
  42.  
  43. typedef enum
  44. {
  45.   Error, not_branch, bicc, bicca, ba, baa, ticc, ta, done_retry
  46. } branch_type;
  47.  
  48. /* Simulate single-step ptrace call for sun4.  Code written by Gary
  49.    Beihl (beihl@mcc.com).  */
  50.  
  51. /* npc4 and next_pc describe the situation at the time that the
  52.    step-breakpoint was set, not necessary the current value of NPC_REGNUM.  */
  53. static CORE_ADDR next_pc, npc4, target;
  54. static int brknpc4, brktrg;
  55. typedef char binsn_quantum[BREAKPOINT_MAX];
  56. static binsn_quantum break_mem[3];
  57.  
  58. /* Non-zero if we just simulated a single-step ptrace call.  This is
  59.    needed because we cannot remove the breakpoints in the inferior
  60.    process until after the `wait' in `wait_for_inferior'.  Used for
  61.    sun4. */
  62.  
  63. int one_stepped;
  64.  
  65. /* sparc64_single_step() is called just before we want to resume the inferior,
  66.    if we want to single-step it but there is no hardware or kernel single-step
  67.    support (as on all SPARCs).  We find all the possible targets of the
  68.    coming instruction and breakpoint them.
  69.  
  70.    single_step is also called just after the inferior stops.  If we had
  71.    set up a simulated single-step, we undo our damage.  */
  72.  
  73. /* FIXME: When the code is releasable, sparc's single step could become this
  74.    one, removing the duplication.  */
  75.  
  76. void
  77. sparc64_single_step (ignore)
  78.      int ignore; /* pid, but we don't need it */
  79. {
  80.   branch_type br, isbranch();
  81.   CORE_ADDR pc;
  82.   long pc_instruction;
  83.  
  84.   if (!one_stepped)
  85.     {
  86.       /* Always set breakpoint for NPC.  */
  87.       next_pc = read_register (NPC_REGNUM);
  88.       npc4 = next_pc + 4; /* branch not taken */
  89.  
  90.       target_insert_breakpoint (next_pc, break_mem[0]);
  91.       /* printf_unfiltered ("set break at %x\n",next_pc); */
  92.  
  93.       pc = read_register (PC_REGNUM);
  94.       pc_instruction = read_memory_integer (pc, sizeof(pc_instruction));
  95.       br = isbranch (pc_instruction, pc, &target);
  96.       brknpc4 = brktrg = 0;
  97.  
  98.       if (br == bicca)
  99.     {
  100.       /* Conditional annulled branch will either end up at
  101.          npc (if taken) or at npc+4 (if not taken).
  102.          Trap npc+4.  */
  103.       brknpc4 = 1;
  104.       target_insert_breakpoint (npc4, break_mem[1]);
  105.     }
  106.       else if ((br == baa && target != next_pc)
  107.            || (TARGET_SPARC64 && br == done_retry))
  108.     {
  109.       /* Unconditional annulled branch will always end up at
  110.          the target.  */
  111.       brktrg = 1;
  112.       target_insert_breakpoint (target, break_mem[2]);
  113.     }
  114.  
  115.       /* We are ready to let it go */
  116.       one_stepped = 1;
  117.       return;
  118.     }
  119.   else
  120.     {
  121.       /* Remove breakpoints */
  122.       target_remove_breakpoint (next_pc, break_mem[0]);
  123.  
  124.       if (brknpc4)
  125.     target_remove_breakpoint (npc4, break_mem[1]);
  126.  
  127.       if (brktrg)
  128.     target_remove_breakpoint (target, break_mem[2]);
  129.  
  130.       one_stepped = 0;
  131.     }
  132. }
  133.  
  134. CORE_ADDR
  135. sparc64_extract_struct_value_address (regbuf)
  136.      char regbuf[REGISTER_BYTES];
  137. {
  138.   CORE_ADDR addr;
  139.  
  140.   /* FIXME: We assume a non-leaf function.  */
  141.   addr = read_register (I0_REGNUM);
  142.   return addr;
  143. }
  144.  
  145. /* Check instruction at ADDR to see if it is an annulled branch or other
  146.    instruction whose npc isn't pc+4 (eg: trap, done, retry).
  147.    All other instructions will go to NPC or will trap.
  148.    Set *TARGET if we find a candidate branch; set to zero if not. */
  149.    
  150. branch_type
  151. isbranch (instruction, addr, target)
  152.      long instruction;
  153.      CORE_ADDR addr, *target;
  154. {
  155.   branch_type val = not_branch;
  156.   long int offset;        /* Must be signed for sign-extend.  */
  157.   union
  158.     {
  159.       unsigned long int code;
  160.       struct
  161.     {
  162.       unsigned int op:2;
  163.       unsigned int a:1;
  164.       unsigned int cond:4;
  165.       unsigned int op2:3;
  166.       unsigned int disp22:22;
  167.     } b;
  168.       struct
  169.     {
  170.       unsigned int op:2;
  171.       unsigned int a:1;
  172.       unsigned int cond:4;
  173.       unsigned int op2:3;
  174.       unsigned int cc:2;
  175.       unsigned int p:1;
  176.       unsigned int disp19:19;
  177.     } bp;
  178.       struct
  179.     {
  180.       unsigned int op:2;
  181.       unsigned int a:1;
  182.       unsigned int zero:1;
  183.       unsigned int rcond:3;
  184.       unsigned int op2:3;
  185.       unsigned int disp16hi:2;
  186.       unsigned int p:1;
  187.       unsigned int rs1:5;
  188.       unsigned int disp16lo:14;
  189.     } bpr;
  190.       struct
  191.     {
  192.       unsigned int op:2;
  193.       unsigned int fcn:5;
  194.       unsigned int op3:6;
  195.       unsigned int reserved:19;
  196.     } dr;
  197.     } insn;
  198.  
  199.   *target = 0;
  200.   insn.code = instruction;
  201.  
  202.   if (insn.b.op == 0
  203.       && (insn.b.op2 == 1 || insn.b.op2 == 2 || insn.b.op2 ==3
  204.       || insn.b.op2 == 5 || insn.b.op2 == 6))
  205.     {
  206.       if (insn.b.cond == 8)
  207.     val = insn.b.a ? baa : ba;
  208.       else
  209.     val = insn.b.a ? bicca : bicc;
  210.       switch (insn.b.op2)
  211.     {
  212.     case 1: /* bpcc */
  213.       offset = 4 * ((int) (insn.bp.disp19 << 13) >> 13);
  214.       break;
  215.     case 2: /* bicc */
  216.       offset = 4 * ((int) (insn.b.disp22 << 10) >> 10);
  217.       break;
  218.     case 3: /* bpr */
  219.       offset = 4 * ((int) ((insn.bpr.disp16hi << 10)
  220.                    || (insn.bpr.disp16lo << 18)) >> 13);
  221.       break;
  222.     case 5: /* fbpfcc */
  223.       offset = 4 * ((int) (insn.bp.disp19 << 13) >> 13);
  224.       break;
  225.     case 6: /* fbfcc */
  226.       offset = 4 * ((int) (insn.b.disp22 << 10) >> 10);
  227.       break;
  228.     }
  229.       *target = addr + offset;
  230.     }
  231.   else if (insn.dr.op == 2 && insn.dr.op3 == 62)
  232.     {
  233.       if (insn.dr.fcn == 0)
  234.     {
  235.       /* done */
  236.       *target = read_register (TNPC_REGNUM);
  237.       val = done_retry;
  238.     }
  239.       else if (insn.dr.fcn == 1)
  240.     {
  241.       /* retry */
  242.       *target = read_register (TPC_REGNUM);
  243.       val = done_retry;
  244.     }
  245.     }
  246.  
  247.   return val;
  248. }
  249.  
  250. /* PRINT_REGISTER_HOOK routine.
  251.    Pretty print various registers.  */
  252.  
  253. static void
  254. dump_ccreg (reg, val)
  255.      char *reg;
  256.      int val;
  257. {
  258.   printf_unfiltered ("%s:%s,%s,%s,%s", reg,
  259.       val & 8 ? "N" : "NN",
  260.       val & 4 ? "Z" : "NZ",
  261.       val & 2 ? "O" : "NO",
  262.       val & 1 ? "C" : "NC"
  263.   );
  264. }
  265.  
  266. void
  267. sparc_print_register_hook (regno)
  268.      int regno;
  269. {
  270.   if (((unsigned) (regno) - FP0_REGNUM < FP_MAX_REGNUM - FP0_REGNUM)
  271.        && ((regno) & 1) == 0)
  272.     {
  273.       char doublereg[8];        /* two float regs */
  274.       if (!read_relative_register_raw_bytes ((regno), doublereg))
  275.     {
  276.       printf_unfiltered("\t");
  277.       print_floating (doublereg, builtin_type_double, gdb_stdout);
  278.     }
  279.     }
  280.   else if ((regno) == CCR_REGNUM)
  281.     {
  282.       int ccr = read_register (CCR_REGNUM);
  283.       printf_unfiltered("\t");
  284.       dump_ccreg ("xcc", ccr >> 4);
  285.       printf_unfiltered(", ");
  286.       dump_ccreg ("icc", ccr & 15);
  287.     }
  288. }
  289.