xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/s12z-tdep.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
17f2ac410Schristos /* Target-dependent code for the S12Z, for the GDB.
2*6881a400Schristos    Copyright (C) 2018-2023 Free Software Foundation, Inc.
37f2ac410Schristos 
47f2ac410Schristos    This file is part of GDB.
57f2ac410Schristos 
67f2ac410Schristos    This program is free software; you can redistribute it and/or modify
77f2ac410Schristos    it under the terms of the GNU General Public License as published by
87f2ac410Schristos    the Free Software Foundation; either version 3 of the License, or
97f2ac410Schristos    (at your option) any later version.
107f2ac410Schristos 
117f2ac410Schristos    This program is distributed in the hope that it will be useful,
127f2ac410Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
137f2ac410Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
147f2ac410Schristos    GNU General Public License for more details.
157f2ac410Schristos 
167f2ac410Schristos    You should have received a copy of the GNU General Public License
177f2ac410Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
187f2ac410Schristos 
197f2ac410Schristos /* Much of this file is shamelessly copied from or1k-tdep.c and others.  */
207f2ac410Schristos 
217f2ac410Schristos #include "defs.h"
227f2ac410Schristos 
237f2ac410Schristos #include "arch-utils.h"
247d62b00eSchristos #include "dwarf2/frame.h"
257d62b00eSchristos #include "gdbsupport/errors.h"
267f2ac410Schristos #include "frame-unwind.h"
277f2ac410Schristos #include "gdbcore.h"
287f2ac410Schristos #include "gdbcmd.h"
297f2ac410Schristos #include "inferior.h"
307f2ac410Schristos #include "opcode/s12z.h"
317f2ac410Schristos #include "trad-frame.h"
327f2ac410Schristos #include "remote.h"
337d62b00eSchristos #include "opcodes/s12z-opc.h"
34*6881a400Schristos #include "gdbarch.h"
35*6881a400Schristos #include "disasm.h"
367f2ac410Schristos 
377f2ac410Schristos /* Two of the registers included in S12Z_N_REGISTERS are
387f2ac410Schristos    the CCH and CCL "registers" which are just views into
397f2ac410Schristos    the CCW register.  */
407f2ac410Schristos #define N_PHYSICAL_REGISTERS (S12Z_N_REGISTERS - 2)
417f2ac410Schristos 
427f2ac410Schristos 
437f2ac410Schristos /*  A permutation of all the physical registers.   Indexing this array
447f2ac410Schristos     with an integer from gdb's internal representation will return the
457f2ac410Schristos     register enum.  */
467f2ac410Schristos static const int reg_perm[N_PHYSICAL_REGISTERS] =
477f2ac410Schristos   {
487f2ac410Schristos    REG_D0,
497f2ac410Schristos    REG_D1,
507f2ac410Schristos    REG_D2,
517f2ac410Schristos    REG_D3,
527f2ac410Schristos    REG_D4,
537f2ac410Schristos    REG_D5,
547f2ac410Schristos    REG_D6,
557f2ac410Schristos    REG_D7,
567f2ac410Schristos    REG_X,
577f2ac410Schristos    REG_Y,
587f2ac410Schristos    REG_S,
597f2ac410Schristos    REG_P,
607f2ac410Schristos    REG_CCW
617f2ac410Schristos   };
627f2ac410Schristos 
637f2ac410Schristos /*  The inverse of the above permutation.  Indexing this
647f2ac410Schristos     array with a register enum (e.g. REG_D2) will return the register
657f2ac410Schristos     number in gdb's internal representation.  */
667f2ac410Schristos static const int inv_reg_perm[N_PHYSICAL_REGISTERS] =
677f2ac410Schristos   {
687f2ac410Schristos    2, 3, 4, 5,      /* d2, d3, d4, d5 */
697f2ac410Schristos    0, 1,            /* d0, d1 */
707f2ac410Schristos    6, 7,            /* d6, d7 */
717f2ac410Schristos    8, 9, 10, 11, 12 /* x, y, s, p, ccw */
727f2ac410Schristos   };
737f2ac410Schristos 
747f2ac410Schristos /*  Return the name of the register REGNUM.  */
757f2ac410Schristos static const char *
767f2ac410Schristos s12z_register_name (struct gdbarch *gdbarch, int regnum)
777f2ac410Schristos {
787f2ac410Schristos   /*  Registers is declared in opcodes/s12z.h.   */
797f2ac410Schristos   return registers[reg_perm[regnum]].name;
807f2ac410Schristos }
817f2ac410Schristos 
827f2ac410Schristos static CORE_ADDR
837f2ac410Schristos s12z_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
847f2ac410Schristos {
857f2ac410Schristos   CORE_ADDR start_pc = 0;
867f2ac410Schristos 
877f2ac410Schristos   if (find_pc_partial_function (pc, NULL, &start_pc, NULL))
887f2ac410Schristos     {
897f2ac410Schristos       CORE_ADDR prologue_end = skip_prologue_using_sal (gdbarch, pc);
907f2ac410Schristos 
917f2ac410Schristos       if (prologue_end != 0)
927f2ac410Schristos 	return prologue_end;
937f2ac410Schristos     }
947f2ac410Schristos 
957d62b00eSchristos   warning (_("%s Failed to find end of prologue PC = %08x"),
967f2ac410Schristos 	   __FUNCTION__, (unsigned int) pc);
977f2ac410Schristos 
987f2ac410Schristos   return pc;
997f2ac410Schristos }
1007f2ac410Schristos 
1017f2ac410Schristos static struct type *
1027f2ac410Schristos s12z_register_type (struct gdbarch *gdbarch, int reg_nr)
1037f2ac410Schristos {
1047f2ac410Schristos   switch (registers[reg_perm[reg_nr]].bytes)
1057f2ac410Schristos     {
1067f2ac410Schristos     case 1:
1077f2ac410Schristos       return builtin_type (gdbarch)->builtin_uint8;
1087f2ac410Schristos     case 2:
1097f2ac410Schristos       return builtin_type (gdbarch)->builtin_uint16;
1107f2ac410Schristos     case 3:
1117f2ac410Schristos       return builtin_type (gdbarch)->builtin_uint24;
1127f2ac410Schristos     case 4:
1137f2ac410Schristos       return builtin_type (gdbarch)->builtin_uint32;
1147f2ac410Schristos     default:
1157f2ac410Schristos       return builtin_type (gdbarch)->builtin_uint32;
1167f2ac410Schristos     }
1177f2ac410Schristos   return builtin_type (gdbarch)->builtin_int0;
1187f2ac410Schristos }
1197f2ac410Schristos 
1207f2ac410Schristos 
1217f2ac410Schristos static int
1227f2ac410Schristos s12z_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int num)
1237f2ac410Schristos {
1247f2ac410Schristos   switch (num)
1257f2ac410Schristos     {
1267f2ac410Schristos     case 15:      return REG_S;
1277f2ac410Schristos     case 7:       return REG_X;
1287f2ac410Schristos     case 8:       return REG_Y;
1297f2ac410Schristos     case 42:      return REG_D0;
1307f2ac410Schristos     case 43:      return REG_D1;
1317f2ac410Schristos     case 44:      return REG_D2;
1327f2ac410Schristos     case 45:      return REG_D3;
1337f2ac410Schristos     case 46:      return REG_D4;
1347f2ac410Schristos     case 47:      return REG_D5;
1357f2ac410Schristos     case 48:      return REG_D6;
1367f2ac410Schristos     case 49:      return REG_D7;
1377f2ac410Schristos     }
1387f2ac410Schristos   return -1;
1397f2ac410Schristos }
1407f2ac410Schristos 
1417f2ac410Schristos 
1427f2ac410Schristos /* Support functions for frame handling.  */
1437f2ac410Schristos 
1447d62b00eSchristos /* A struct (based on mem_read_abstraction_base) to read memory
1457d62b00eSchristos    through the disassemble_info API.  */
1467d62b00eSchristos struct mem_read_abstraction
1477d62b00eSchristos {
1487d62b00eSchristos   struct mem_read_abstraction_base base; /* The parent struct.  */
1497d62b00eSchristos   bfd_vma memaddr;                  /* Where to read from.  */
1507d62b00eSchristos   struct disassemble_info* info;  /* The disassembler  to use for reading.  */
1517d62b00eSchristos };
1527d62b00eSchristos 
1537d62b00eSchristos /* Advance the reader by one byte.  */
1547d62b00eSchristos static void
1557d62b00eSchristos advance (struct mem_read_abstraction_base *b)
1567d62b00eSchristos {
1577d62b00eSchristos   struct mem_read_abstraction *mra = (struct mem_read_abstraction *) b;
1587d62b00eSchristos   mra->memaddr++;
1597d62b00eSchristos }
1607d62b00eSchristos 
1617d62b00eSchristos /* Return the current position of the reader.  */
1627d62b00eSchristos static bfd_vma
1637d62b00eSchristos posn (struct mem_read_abstraction_base *b)
1647d62b00eSchristos {
1657d62b00eSchristos   struct mem_read_abstraction *mra = (struct mem_read_abstraction *) b;
1667d62b00eSchristos   return mra->memaddr;
1677d62b00eSchristos }
1687d62b00eSchristos 
1697d62b00eSchristos /* Read the N bytes at OFFSET  using B.  The bytes read are stored in BYTES.
1707d62b00eSchristos    It is the caller's responsibility to ensure that this is of at least N
1717d62b00eSchristos    in size.  */
1727d62b00eSchristos static int
1737d62b00eSchristos abstract_read_memory (struct mem_read_abstraction_base *b,
1747d62b00eSchristos 		      int offset,
1757d62b00eSchristos 		      size_t n, bfd_byte *bytes)
1767d62b00eSchristos {
1777d62b00eSchristos   struct mem_read_abstraction *mra = (struct mem_read_abstraction *) b;
1787d62b00eSchristos 
1797d62b00eSchristos   int status =
1807d62b00eSchristos     (*mra->info->read_memory_func) (mra->memaddr + offset,
1817d62b00eSchristos 				    bytes, n, mra->info);
1827d62b00eSchristos 
1837d62b00eSchristos   if (status != 0)
1847d62b00eSchristos     {
1857d62b00eSchristos       (*mra->info->memory_error_func) (status, mra->memaddr, mra->info);
1867d62b00eSchristos       return -1;
1877d62b00eSchristos     }
1887d62b00eSchristos 
1897d62b00eSchristos   return 0;
1907d62b00eSchristos }
1917d62b00eSchristos 
1927d62b00eSchristos 
1937d62b00eSchristos /* Return the stack adjustment caused by a push or pull instruction.  */
1947d62b00eSchristos static int
1957d62b00eSchristos push_pull_get_stack_adjustment (int n_operands,
1967d62b00eSchristos 				struct operand *const *operands)
1977d62b00eSchristos {
1987d62b00eSchristos   int stack_adjustment = 0;
1997d62b00eSchristos   gdb_assert (n_operands > 0);
2007d62b00eSchristos   if (operands[0]->cl == OPND_CL_REGISTER_ALL)
2017d62b00eSchristos     stack_adjustment = 26;  /* All the regs are involved.  */
2027d62b00eSchristos   else if (operands[0]->cl == OPND_CL_REGISTER_ALL16)
2037d62b00eSchristos     stack_adjustment = 4 * 2; /* All four 16 bit regs are involved.  */
2047d62b00eSchristos   else
2057d62b00eSchristos     for (int i = 0; i < n_operands; ++i)
2067d62b00eSchristos       {
2077d62b00eSchristos 	if (operands[i]->cl != OPND_CL_REGISTER)
2087d62b00eSchristos 	  continue; /* I don't think this can ever happen.  */
2097d62b00eSchristos 	const struct register_operand *op
2107d62b00eSchristos 	  = (const struct register_operand *) operands[i];
2117d62b00eSchristos 	switch (op->reg)
2127d62b00eSchristos 	  {
2137d62b00eSchristos 	  case REG_X:
2147d62b00eSchristos 	  case REG_Y:
2157d62b00eSchristos 	    stack_adjustment += 3;
2167d62b00eSchristos 	    break;
2177d62b00eSchristos 	  case REG_D7:
2187d62b00eSchristos 	  case REG_D6:
2197d62b00eSchristos 	    stack_adjustment += 4;
2207d62b00eSchristos 	    break;
2217d62b00eSchristos 	  case REG_D2:
2227d62b00eSchristos 	  case REG_D3:
2237d62b00eSchristos 	  case REG_D4:
2247d62b00eSchristos 	  case REG_D5:
2257d62b00eSchristos 	    stack_adjustment += 2;
2267d62b00eSchristos 	    break;
2277d62b00eSchristos 	  case REG_D0:
2287d62b00eSchristos 	  case REG_D1:
2297d62b00eSchristos 	  case REG_CCL:
2307d62b00eSchristos 	  case REG_CCH:
2317d62b00eSchristos 	    stack_adjustment += 1;
2327d62b00eSchristos 	    break;
2337d62b00eSchristos 	  default:
2347d62b00eSchristos 	    gdb_assert_not_reached ("Invalid register in push/pull operation.");
2357d62b00eSchristos 	    break;
2367d62b00eSchristos 	  }
2377d62b00eSchristos       }
2387d62b00eSchristos   return stack_adjustment;
2397d62b00eSchristos }
2407d62b00eSchristos 
2417f2ac410Schristos /* Initialize a prologue cache.  */
2427f2ac410Schristos 
2437f2ac410Schristos static struct trad_frame_cache *
244*6881a400Schristos s12z_frame_cache (frame_info_ptr this_frame, void **prologue_cache)
2457f2ac410Schristos {
2467f2ac410Schristos   struct trad_frame_cache *info;
2477f2ac410Schristos 
2487f2ac410Schristos   CORE_ADDR this_sp;
2497f2ac410Schristos   CORE_ADDR this_sp_for_id;
2507f2ac410Schristos 
2517f2ac410Schristos   CORE_ADDR start_addr;
2527f2ac410Schristos   CORE_ADDR end_addr;
2537f2ac410Schristos 
2547f2ac410Schristos   /* Nothing to do if we already have this info.  */
2557f2ac410Schristos   if (NULL != *prologue_cache)
2567f2ac410Schristos     return (struct trad_frame_cache *) *prologue_cache;
2577f2ac410Schristos 
2587f2ac410Schristos   /* Get a new prologue cache and populate it with default values.  */
2597f2ac410Schristos   info = trad_frame_cache_zalloc (this_frame);
2607f2ac410Schristos   *prologue_cache = info;
2617f2ac410Schristos 
2627f2ac410Schristos   /* Find the start address of this function (which is a normal frame, even
2637f2ac410Schristos      if the next frame is the sentinel frame) and the end of its prologue.  */
2647f2ac410Schristos   CORE_ADDR this_pc = get_frame_pc (this_frame);
2657f2ac410Schristos   struct gdbarch *gdbarch = get_frame_arch (this_frame);
2667f2ac410Schristos   find_pc_partial_function (this_pc, NULL, &start_addr, NULL);
2677f2ac410Schristos 
2687f2ac410Schristos   /* Get the stack pointer if we have one (if there's no process executing
2697f2ac410Schristos      yet we won't have a frame.  */
2707f2ac410Schristos   this_sp = (NULL == this_frame) ? 0 :
2717f2ac410Schristos     get_frame_register_unsigned (this_frame, REG_S);
2727f2ac410Schristos 
2737f2ac410Schristos   /* Return early if GDB couldn't find the function.  */
2747f2ac410Schristos   if (start_addr == 0)
2757f2ac410Schristos     {
2767d62b00eSchristos       warning (_("Couldn't find function including address %s SP is %s"),
2777f2ac410Schristos 	       paddress (gdbarch, this_pc),
2787f2ac410Schristos 	       paddress (gdbarch, this_sp));
2797f2ac410Schristos 
2807f2ac410Schristos       /* JPB: 28-Apr-11.  This is a temporary patch, to get round GDB
2817f2ac410Schristos 	 crashing right at the beginning.  Build the frame ID as best we
2827f2ac410Schristos 	 can.  */
2837f2ac410Schristos       trad_frame_set_id (info, frame_id_build (this_sp, this_pc));
2847f2ac410Schristos 
2857f2ac410Schristos       return info;
2867f2ac410Schristos     }
2877f2ac410Schristos 
2887f2ac410Schristos   /* The default frame base of this frame (for ID purposes only - frame
2897f2ac410Schristos      base is an overloaded term) is its stack pointer.  For now we use the
2907f2ac410Schristos      value of the SP register in this frame.  However if the PC is in the
2917f2ac410Schristos      prologue of this frame, before the SP has been set up, then the value
2927f2ac410Schristos      will actually be that of the prev frame, and we'll need to adjust it
2937f2ac410Schristos      later.  */
2947f2ac410Schristos   trad_frame_set_this_base (info, this_sp);
2957f2ac410Schristos   this_sp_for_id = this_sp;
2967f2ac410Schristos 
2977f2ac410Schristos   /* We should only examine code that is in the prologue.  This is all code
2987f2ac410Schristos      up to (but not including) end_addr.  We should only populate the cache
2997f2ac410Schristos      while the address is up to (but not including) the PC or end_addr,
3007f2ac410Schristos      whichever is first.  */
3017f2ac410Schristos   end_addr = s12z_skip_prologue (gdbarch, start_addr);
3027f2ac410Schristos 
3037f2ac410Schristos   /* All the following analysis only occurs if we are in the prologue and
3047f2ac410Schristos      have executed the code.  Check we have a sane prologue size, and if
3057f2ac410Schristos      zero we are frameless and can give up here.  */
3067f2ac410Schristos   if (end_addr < start_addr)
3077f2ac410Schristos     error (_("end addr %s is less than start addr %s"),
3087f2ac410Schristos 	   paddress (gdbarch, end_addr), paddress (gdbarch, start_addr));
3097f2ac410Schristos 
3107f2ac410Schristos   CORE_ADDR addr = start_addr; /* Where we have got to?  */
3117f2ac410Schristos   int frame_size = 0;
3127f2ac410Schristos   int saved_frame_size = 0;
3137d62b00eSchristos 
314*6881a400Schristos   struct gdb_non_printing_memory_disassembler dis (gdbarch);
3157f2ac410Schristos 
3167d62b00eSchristos   struct mem_read_abstraction mra;
3177d62b00eSchristos   mra.base.read = (int (*)(mem_read_abstraction_base*,
3187d62b00eSchristos 			   int, size_t, bfd_byte*)) abstract_read_memory;
3197d62b00eSchristos   mra.base.advance = advance ;
3207d62b00eSchristos   mra.base.posn = posn;
321*6881a400Schristos   mra.info = dis.disasm_info ();
3227f2ac410Schristos 
3237d62b00eSchristos   while (this_pc > addr)
3247f2ac410Schristos     {
3257d62b00eSchristos       enum optr optr = OP_INVALID;
3267d62b00eSchristos       short osize;
3277d62b00eSchristos       int n_operands = 0;
3287d62b00eSchristos       struct operand *operands[6];
3297d62b00eSchristos       mra.memaddr = addr;
3307d62b00eSchristos       int n_bytes =
3317d62b00eSchristos 	decode_s12z (&optr, &osize, &n_operands, operands,
3327d62b00eSchristos 		     (mem_read_abstraction_base *) &mra);
3337d62b00eSchristos 
3347d62b00eSchristos       switch (optr)
3357d62b00eSchristos 	{
3367d62b00eSchristos 	case OP_tbNE:
3377d62b00eSchristos 	case OP_tbPL:
3387d62b00eSchristos 	case OP_tbMI:
3397d62b00eSchristos 	case OP_tbGT:
3407d62b00eSchristos 	case OP_tbLE:
3417d62b00eSchristos 	case OP_dbNE:
3427d62b00eSchristos 	case OP_dbEQ:
3437d62b00eSchristos 	case OP_dbPL:
3447d62b00eSchristos 	case OP_dbMI:
3457d62b00eSchristos 	case OP_dbGT:
3467d62b00eSchristos 	case OP_dbLE:
3477f2ac410Schristos 	  /* Conditional Branches.   If any of these are encountered, then
3487f2ac410Schristos 	     it is likely that a RTS will terminate it.  So we need to save
3497f2ac410Schristos 	     the frame size so it can be restored.  */
3507f2ac410Schristos 	  saved_frame_size = frame_size;
3517d62b00eSchristos 	  break;
3527d62b00eSchristos 	case OP_rts:
3537d62b00eSchristos 	  /* Restore the frame size from a previously saved value.  */
3547d62b00eSchristos 	  frame_size = saved_frame_size;
3557d62b00eSchristos 	  break;
3567d62b00eSchristos 	case OP_push:
3577d62b00eSchristos 	  frame_size += push_pull_get_stack_adjustment (n_operands, operands);
3587d62b00eSchristos 	  break;
3597d62b00eSchristos 	case OP_pull:
3607d62b00eSchristos 	  frame_size -= push_pull_get_stack_adjustment (n_operands, operands);
3617d62b00eSchristos 	  break;
3627d62b00eSchristos 	case OP_lea:
3637d62b00eSchristos 	  if (operands[0]->cl == OPND_CL_REGISTER)
3647f2ac410Schristos 	    {
3657d62b00eSchristos 	      int reg = ((struct register_operand *) (operands[0]))->reg;
3667d62b00eSchristos 	      if ((reg == REG_S) && (operands[1]->cl == OPND_CL_MEMORY))
3677f2ac410Schristos 		{
3687d62b00eSchristos 		  const struct memory_operand *mo
3697d62b00eSchristos 		    = (const struct memory_operand * ) operands[1];
3707d62b00eSchristos 		  if (mo->n_regs == 1 && !mo->indirect
3717d62b00eSchristos 		      && mo->regs[0] == REG_S
3727d62b00eSchristos 		      && mo->mutation == OPND_RM_NONE)
3737f2ac410Schristos 		    {
3747d62b00eSchristos 		      /* LEA S, (xxx, S) -- Decrement the stack.   This is
3757d62b00eSchristos 			 almost certainly the start of a frame.  */
3767d62b00eSchristos 		      int simm = (signed char)  mo->base_offset;
3777f2ac410Schristos 		      frame_size -= simm;
3787f2ac410Schristos 		    }
3797f2ac410Schristos 		}
3807f2ac410Schristos 	    }
3817d62b00eSchristos 	  break;
3827d62b00eSchristos 	default:
3837d62b00eSchristos 	  break;
3847d62b00eSchristos 	}
3857d62b00eSchristos       addr += n_bytes;
3867d62b00eSchristos       for (int o = 0; o < n_operands; ++o)
3877d62b00eSchristos 	free (operands[o]);
3887f2ac410Schristos     }
3897f2ac410Schristos 
3907f2ac410Schristos   /* If the PC has not actually got to this point, then the frame
3917f2ac410Schristos      base will be wrong, and we adjust it. */
3927f2ac410Schristos   if (this_pc < addr)
3937f2ac410Schristos     {
3947f2ac410Schristos       /* Only do if executing.  */
3957f2ac410Schristos       if (0 != this_sp)
3967f2ac410Schristos 	{
3977f2ac410Schristos 	  this_sp_for_id = this_sp - frame_size;
3987f2ac410Schristos 	  trad_frame_set_this_base (info, this_sp_for_id);
3997f2ac410Schristos 	}
4007f2ac410Schristos       trad_frame_set_reg_value (info, REG_S, this_sp + 3);
4017f2ac410Schristos       trad_frame_set_reg_addr (info, REG_P, this_sp);
4027f2ac410Schristos     }
4037f2ac410Schristos   else
4047f2ac410Schristos     {
4057f2ac410Schristos       gdb_assert (this_sp == this_sp_for_id);
4067f2ac410Schristos       /* The stack pointer of the prev frame is frame_size greater
4077f2ac410Schristos 	 than the stack pointer of this frame plus one address
4087f2ac410Schristos 	 size (caused by the JSR or BSR).  */
4097f2ac410Schristos       trad_frame_set_reg_value (info, REG_S,
4107f2ac410Schristos 				this_sp + frame_size + 3);
4117f2ac410Schristos       trad_frame_set_reg_addr (info, REG_P, this_sp + frame_size);
4127f2ac410Schristos     }
4137f2ac410Schristos 
4147f2ac410Schristos 
4157f2ac410Schristos   /* Build the frame ID.  */
4167f2ac410Schristos   trad_frame_set_id (info, frame_id_build (this_sp_for_id, start_addr));
4177f2ac410Schristos 
4187f2ac410Schristos   return info;
4197f2ac410Schristos }
4207f2ac410Schristos 
4217f2ac410Schristos /* Implement the this_id function for the stub unwinder.  */
4227f2ac410Schristos static void
423*6881a400Schristos s12z_frame_this_id (frame_info_ptr this_frame,
4247f2ac410Schristos 		    void **prologue_cache, struct frame_id *this_id)
4257f2ac410Schristos {
4267f2ac410Schristos   struct trad_frame_cache *info = s12z_frame_cache (this_frame,
4277f2ac410Schristos 						    prologue_cache);
4287f2ac410Schristos 
4297f2ac410Schristos   trad_frame_get_id (info, this_id);
4307f2ac410Schristos }
4317f2ac410Schristos 
4327f2ac410Schristos 
4337f2ac410Schristos /* Implement the prev_register function for the stub unwinder.  */
4347f2ac410Schristos static struct value *
435*6881a400Schristos s12z_frame_prev_register (frame_info_ptr this_frame,
4367f2ac410Schristos 			  void **prologue_cache, int regnum)
4377f2ac410Schristos {
4387f2ac410Schristos   struct trad_frame_cache *info = s12z_frame_cache (this_frame,
4397f2ac410Schristos 						    prologue_cache);
4407f2ac410Schristos 
4417f2ac410Schristos   return trad_frame_get_register (info, this_frame, regnum);
4427f2ac410Schristos }
4437f2ac410Schristos 
4447f2ac410Schristos /* Data structures for the normal prologue-analysis-based unwinder.  */
4457f2ac410Schristos static const struct frame_unwind s12z_frame_unwind = {
446*6881a400Schristos   "s12z prologue",
4477f2ac410Schristos   NORMAL_FRAME,
4487f2ac410Schristos   default_frame_unwind_stop_reason,
4497f2ac410Schristos   s12z_frame_this_id,
4507f2ac410Schristos   s12z_frame_prev_register,
4517f2ac410Schristos   NULL,
4527f2ac410Schristos   default_frame_sniffer,
4537f2ac410Schristos   NULL,
4547f2ac410Schristos };
4557f2ac410Schristos 
4567f2ac410Schristos 
4577f2ac410Schristos constexpr gdb_byte s12z_break_insn[] = {0x00};
4587f2ac410Schristos 
4597f2ac410Schristos typedef BP_MANIPULATION (s12z_break_insn) s12z_breakpoint;
4607f2ac410Schristos 
461*6881a400Schristos struct s12z_gdbarch_tdep : gdbarch_tdep_base
4627f2ac410Schristos {
4637f2ac410Schristos };
4647f2ac410Schristos 
4657f2ac410Schristos /*  A vector of human readable characters representing the
4667f2ac410Schristos     bits in the CCW register.  Unused bits are represented as '-'.
4677f2ac410Schristos     Lowest significant bit comes first.  */
4687f2ac410Schristos static const char ccw_bits[] =
4697f2ac410Schristos   {
4707f2ac410Schristos    'C',  /* Carry  */
4717f2ac410Schristos    'V',  /* Two's Complement Overflow  */
4727f2ac410Schristos    'Z',  /* Zero  */
4737f2ac410Schristos    'N',  /* Negative  */
4747f2ac410Schristos    'I',  /* Interrupt  */
4757f2ac410Schristos    '-',
4767f2ac410Schristos    'X',  /* Non-Maskable Interrupt  */
4777f2ac410Schristos    'S',  /* STOP Disable  */
4787f2ac410Schristos    '0',  /*  Interrupt priority level */
4797f2ac410Schristos    '0',  /*  ditto  */
4807f2ac410Schristos    '0',  /*  ditto  */
4817f2ac410Schristos    '-',
4827f2ac410Schristos    '-',
4837f2ac410Schristos    '-',
4847f2ac410Schristos    '-',
4857f2ac410Schristos    'U'   /* User/Supervisor State.  */
4867f2ac410Schristos   };
4877f2ac410Schristos 
4887f2ac410Schristos /* Print a human readable representation of the CCW register.
4897f2ac410Schristos    For example: "u----000SX-Inzvc" corresponds to the value
4907f2ac410Schristos    0xD0.  */
4917f2ac410Schristos static void
4927f2ac410Schristos s12z_print_ccw_info (struct gdbarch *gdbarch,
4937f2ac410Schristos 		     struct ui_file *file,
494*6881a400Schristos 		     frame_info_ptr frame,
4957f2ac410Schristos 		     int reg)
4967f2ac410Schristos {
4977f2ac410Schristos   struct value *v = value_of_register (reg, frame);
4987f2ac410Schristos   const char *name = gdbarch_register_name (gdbarch, reg);
4997f2ac410Schristos   uint32_t ccw = value_as_long (v);
500*6881a400Schristos   gdb_puts (name, file);
5017f2ac410Schristos   size_t len = strlen (name);
5027f2ac410Schristos   const int stop_1 = 15;
5037f2ac410Schristos   const int stop_2 = 17;
5047f2ac410Schristos   for (int i = 0; i < stop_1 - len; ++i)
505*6881a400Schristos     gdb_putc (' ', file);
506*6881a400Schristos   gdb_printf (file, "0x%04x", ccw);
5077f2ac410Schristos   for (int i = 0; i < stop_2 - len; ++i)
508*6881a400Schristos     gdb_putc (' ', file);
5097f2ac410Schristos   for (int b = 15; b >= 0; --b)
5107f2ac410Schristos     {
5117f2ac410Schristos       if (ccw & (0x1u << b))
5127f2ac410Schristos 	{
5137f2ac410Schristos 	  if (ccw_bits[b] == 0)
514*6881a400Schristos 	    gdb_putc ('1', file);
5157f2ac410Schristos 	  else
516*6881a400Schristos 	    gdb_putc (ccw_bits[b], file);
5177f2ac410Schristos 	}
5187f2ac410Schristos       else
519*6881a400Schristos 	gdb_putc (tolower (ccw_bits[b]), file);
5207f2ac410Schristos     }
521*6881a400Schristos   gdb_putc ('\n', file);
5227f2ac410Schristos }
5237f2ac410Schristos 
5247f2ac410Schristos static void
5257f2ac410Schristos s12z_print_registers_info (struct gdbarch *gdbarch,
5267f2ac410Schristos 			    struct ui_file *file,
527*6881a400Schristos 			    frame_info_ptr frame,
5287f2ac410Schristos 			    int regnum, int print_all)
5297f2ac410Schristos {
5307f2ac410Schristos   const int numregs = (gdbarch_num_regs (gdbarch)
5317f2ac410Schristos 		       + gdbarch_num_pseudo_regs (gdbarch));
5327f2ac410Schristos 
5337f2ac410Schristos   if (regnum == -1)
5347f2ac410Schristos     {
5357f2ac410Schristos       for (int reg = 0; reg < numregs; reg++)
5367f2ac410Schristos 	{
5377f2ac410Schristos 	  if (REG_CCW == reg_perm[reg])
5387f2ac410Schristos 	    {
5397f2ac410Schristos 	      s12z_print_ccw_info (gdbarch, file, frame, reg);
5407f2ac410Schristos 	      continue;
5417f2ac410Schristos 	    }
5427f2ac410Schristos 	  default_print_registers_info (gdbarch, file, frame, reg, print_all);
5437f2ac410Schristos 	}
5447f2ac410Schristos     }
5457f2ac410Schristos   else if (REG_CCW == reg_perm[regnum])
5467f2ac410Schristos     s12z_print_ccw_info (gdbarch, file, frame, regnum);
5477f2ac410Schristos   else
5487f2ac410Schristos     default_print_registers_info (gdbarch, file, frame, regnum, print_all);
5497f2ac410Schristos }
5507f2ac410Schristos 
5517f2ac410Schristos 
5527f2ac410Schristos 
5537f2ac410Schristos 
5547f2ac410Schristos static void
5557f2ac410Schristos s12z_extract_return_value (struct type *type, struct regcache *regcache,
5567f2ac410Schristos 			      void *valbuf)
5577f2ac410Schristos {
5587f2ac410Schristos   int reg = -1;
5597f2ac410Schristos 
560*6881a400Schristos   switch (type->length ())
5617f2ac410Schristos     {
5627f2ac410Schristos     case 0:   /* Nothing to do */
5637f2ac410Schristos       return;
5647f2ac410Schristos 
5657f2ac410Schristos     case 1:
5667f2ac410Schristos       reg = REG_D0;
5677f2ac410Schristos       break;
5687f2ac410Schristos 
5697f2ac410Schristos     case 2:
5707f2ac410Schristos       reg = REG_D2;
5717f2ac410Schristos       break;
5727f2ac410Schristos 
5737f2ac410Schristos     case 3:
5747f2ac410Schristos       reg = REG_X;
5757f2ac410Schristos       break;
5767f2ac410Schristos 
5777f2ac410Schristos     case 4:
5787f2ac410Schristos       reg = REG_D6;
5797f2ac410Schristos       break;
5807f2ac410Schristos 
5817f2ac410Schristos     default:
5827f2ac410Schristos       error (_("bad size for return value"));
5837f2ac410Schristos       return;
5847f2ac410Schristos     }
5857f2ac410Schristos 
5867f2ac410Schristos   regcache->cooked_read (inv_reg_perm[reg], (gdb_byte *) valbuf);
5877f2ac410Schristos }
5887f2ac410Schristos 
5897f2ac410Schristos static enum return_value_convention
5907f2ac410Schristos s12z_return_value (struct gdbarch *gdbarch, struct value *function,
5917f2ac410Schristos 		   struct type *type, struct regcache *regcache,
5927f2ac410Schristos 		   gdb_byte *readbuf, const gdb_byte *writebuf)
5937f2ac410Schristos {
5947d62b00eSchristos   if (type->code () == TYPE_CODE_STRUCT
5957d62b00eSchristos       || type->code () == TYPE_CODE_UNION
5967d62b00eSchristos       || type->code () == TYPE_CODE_ARRAY
597*6881a400Schristos       || type->length () > 4)
5987f2ac410Schristos     return RETURN_VALUE_STRUCT_CONVENTION;
5997f2ac410Schristos 
6007f2ac410Schristos   if (readbuf)
6017f2ac410Schristos     s12z_extract_return_value (type, regcache, readbuf);
6027f2ac410Schristos 
6037f2ac410Schristos   return RETURN_VALUE_REGISTER_CONVENTION;
6047f2ac410Schristos }
6057f2ac410Schristos 
6067f2ac410Schristos 
6077f2ac410Schristos static void
6087f2ac410Schristos show_bdccsr_command (const char *args, int from_tty)
6097f2ac410Schristos {
6107f2ac410Schristos   struct string_file output;
6117f2ac410Schristos   target_rcmd ("bdccsr", &output);
6127f2ac410Schristos 
613*6881a400Schristos   gdb_printf ("The current BDCCSR value is %s\n", output.string().c_str());
6147f2ac410Schristos }
6157f2ac410Schristos 
6167f2ac410Schristos static struct gdbarch *
6177f2ac410Schristos s12z_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
6187f2ac410Schristos {
619*6881a400Schristos   s12z_gdbarch_tdep *tdep = new s12z_gdbarch_tdep;
6207f2ac410Schristos   struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
6217f2ac410Schristos 
6227f2ac410Schristos   add_cmd ("bdccsr", class_support, show_bdccsr_command,
6237f2ac410Schristos 	   _("Show the current value of the microcontroller's BDCCSR."),
6247f2ac410Schristos 	   &maintenanceinfolist);
6257f2ac410Schristos 
6267f2ac410Schristos   /* Target data types.  */
6277f2ac410Schristos   set_gdbarch_short_bit (gdbarch, 16);
6287f2ac410Schristos   set_gdbarch_int_bit (gdbarch, 16);
6297f2ac410Schristos   set_gdbarch_long_bit (gdbarch, 32);
6307f2ac410Schristos   set_gdbarch_long_long_bit (gdbarch, 32);
6317f2ac410Schristos   set_gdbarch_ptr_bit (gdbarch, 24);
6327f2ac410Schristos   set_gdbarch_addr_bit (gdbarch, 24);
6337f2ac410Schristos   set_gdbarch_char_signed (gdbarch, 0);
6347f2ac410Schristos 
6357f2ac410Schristos   set_gdbarch_ps_regnum (gdbarch, REG_CCW);
6367f2ac410Schristos   set_gdbarch_pc_regnum (gdbarch, REG_P);
6377f2ac410Schristos   set_gdbarch_sp_regnum (gdbarch, REG_S);
6387f2ac410Schristos 
6397f2ac410Schristos 
6407f2ac410Schristos   set_gdbarch_print_registers_info (gdbarch, s12z_print_registers_info);
6417f2ac410Schristos 
6427f2ac410Schristos   set_gdbarch_breakpoint_kind_from_pc (gdbarch,
6437f2ac410Schristos 				       s12z_breakpoint::kind_from_pc);
6447f2ac410Schristos   set_gdbarch_sw_breakpoint_from_kind (gdbarch,
6457f2ac410Schristos 				       s12z_breakpoint::bp_from_kind);
6467f2ac410Schristos 
6477f2ac410Schristos   set_gdbarch_num_regs (gdbarch, N_PHYSICAL_REGISTERS);
6487f2ac410Schristos   set_gdbarch_register_name (gdbarch, s12z_register_name);
6497f2ac410Schristos   set_gdbarch_skip_prologue (gdbarch, s12z_skip_prologue);
6507f2ac410Schristos   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
6517f2ac410Schristos   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, s12z_dwarf_reg_to_regnum);
6527f2ac410Schristos 
6537f2ac410Schristos   set_gdbarch_register_type (gdbarch, s12z_register_type);
6547f2ac410Schristos 
6557f2ac410Schristos   frame_unwind_append_unwinder (gdbarch, &s12z_frame_unwind);
6567d62b00eSchristos   /* Currently, the only known producer for this architecture, produces buggy
6577f2ac410Schristos      dwarf CFI.   So don't append a dwarf unwinder until the situation is
6587f2ac410Schristos      better understood.  */
6597f2ac410Schristos 
6607f2ac410Schristos   set_gdbarch_return_value (gdbarch, s12z_return_value);
6617f2ac410Schristos 
6627f2ac410Schristos   return gdbarch;
6637f2ac410Schristos }
6647f2ac410Schristos 
6657d62b00eSchristos void _initialize_s12z_tdep ();
6667f2ac410Schristos void
6677d62b00eSchristos _initialize_s12z_tdep ()
6687f2ac410Schristos {
6697f2ac410Schristos   gdbarch_register (bfd_arch_s12z, s12z_gdbarch_init, NULL);
6707f2ac410Schristos }
671