Home | History | Annotate | Line # | Download | only in m32r
      1 /* m32rx simulator support code
      2    Copyright (C) 1997-2024 Free Software Foundation, Inc.
      3    Contributed by Cygnus Support.
      4 
      5 This file is part of GDB, the GNU debugger.
      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 3 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, see <http://www.gnu.org/licenses/>.  */
     19 
     20 /* This must come before any other includes.  */
     21 #include "defs.h"
     22 
     23 #define WANT_CPU m32rxf
     24 #define WANT_CPU_M32RXF
     25 
     26 #include "sim-main.h"
     27 #include "cgen-mem.h"
     28 #include "cgen-ops.h"
     29 
     30 #include "m32r-sim.h"
     31 
     32 /* The contents of BUF are in target byte order.  */
     33 
     34 int
     35 m32rxf_fetch_register (SIM_CPU *current_cpu, int rn, void *buf, int len)
     36 {
     37   return m32rbf_fetch_register (current_cpu, rn, buf, len);
     38 }
     39 
     40 /* The contents of BUF are in target byte order.  */
     41 
     42 int
     43 m32rxf_store_register (SIM_CPU *current_cpu, int rn, const void *buf, int len)
     44 {
     45   return m32rbf_store_register (current_cpu, rn, buf, len);
     46 }
     47 
     48 /* Cover fns to get/set the control registers.
     50    FIXME: Duplicated from m32r.c.  The issue is structure offsets.  */
     51 
     52 USI
     53 m32rxf_h_cr_get_handler (SIM_CPU *current_cpu, UINT cr)
     54 {
     55   switch (cr)
     56     {
     57     case H_CR_PSW : /* psw */
     58       return (((CPU (h_bpsw) & 0xc1) << 8)
     59 	      | ((CPU (h_psw) & 0xc0) << 0)
     60 	      | GET_H_COND ());
     61     case H_CR_BBPSW : /* backup backup psw */
     62       return CPU (h_bbpsw) & 0xc1;
     63     case H_CR_CBR : /* condition bit */
     64       return GET_H_COND ();
     65     case H_CR_SPI : /* interrupt stack pointer */
     66       if (! GET_H_SM ())
     67 	return CPU (h_gr[H_GR_SP]);
     68       else
     69 	return CPU (h_cr[H_CR_SPI]);
     70     case H_CR_SPU : /* user stack pointer */
     71       if (GET_H_SM ())
     72 	return CPU (h_gr[H_GR_SP]);
     73       else
     74 	return CPU (h_cr[H_CR_SPU]);
     75     case H_CR_BPC : /* backup pc */
     76       return CPU (h_cr[H_CR_BPC]) & 0xfffffffe;
     77     case H_CR_BBPC : /* backup backup pc */
     78       return CPU (h_cr[H_CR_BBPC]) & 0xfffffffe;
     79     case 4 : /* ??? unspecified, but apparently available */
     80     case 5 : /* ??? unspecified, but apparently available */
     81       return CPU (h_cr[cr]);
     82     default :
     83       return 0;
     84     }
     85 }
     86 
     87 void
     88 m32rxf_h_cr_set_handler (SIM_CPU *current_cpu, UINT cr, USI newval)
     89 {
     90   switch (cr)
     91     {
     92     case H_CR_PSW : /* psw */
     93       {
     94 	int old_sm = (CPU (h_psw) & 0x80) != 0;
     95 	int new_sm = (newval & 0x80) != 0;
     96 	CPU (h_bpsw) = (newval >> 8) & 0xff;
     97 	CPU (h_psw) = newval & 0xff;
     98 	SET_H_COND (newval & 1);
     99 	/* When switching stack modes, update the registers.  */
    100 	if (old_sm != new_sm)
    101 	  {
    102 	    if (old_sm)
    103 	      {
    104 		/* Switching user -> system.  */
    105 		CPU (h_cr[H_CR_SPU]) = CPU (h_gr[H_GR_SP]);
    106 		CPU (h_gr[H_GR_SP]) = CPU (h_cr[H_CR_SPI]);
    107 	      }
    108 	    else
    109 	      {
    110 		/* Switching system -> user.  */
    111 		CPU (h_cr[H_CR_SPI]) = CPU (h_gr[H_GR_SP]);
    112 		CPU (h_gr[H_GR_SP]) = CPU (h_cr[H_CR_SPU]);
    113 	      }
    114 	  }
    115 	break;
    116       }
    117     case H_CR_BBPSW : /* backup backup psw */
    118       CPU (h_bbpsw) = newval & 0xff;
    119       break;
    120     case H_CR_CBR : /* condition bit */
    121       SET_H_COND (newval & 1);
    122       break;
    123     case H_CR_SPI : /* interrupt stack pointer */
    124       if (! GET_H_SM ())
    125 	CPU (h_gr[H_GR_SP]) = newval;
    126       else
    127 	CPU (h_cr[H_CR_SPI]) = newval;
    128       break;
    129     case H_CR_SPU : /* user stack pointer */
    130       if (GET_H_SM ())
    131 	CPU (h_gr[H_GR_SP]) = newval;
    132       else
    133 	CPU (h_cr[H_CR_SPU]) = newval;
    134       break;
    135     case H_CR_BPC : /* backup pc */
    136       CPU (h_cr[H_CR_BPC]) = newval;
    137       break;
    138     case H_CR_BBPC : /* backup backup pc */
    139       CPU (h_cr[H_CR_BBPC]) = newval;
    140       break;
    141     case 4 : /* ??? unspecified, but apparently available */
    142     case 5 : /* ??? unspecified, but apparently available */
    143       CPU (h_cr[cr]) = newval;
    144       break;
    145     default :
    146       /* ignore */
    147       break;
    148     }
    149 }
    150 
    151 /* Cover fns to access h-psw.  */
    152 
    153 UQI
    154 m32rxf_h_psw_get_handler (SIM_CPU *current_cpu)
    155 {
    156   return (CPU (h_psw) & 0xfe) | (CPU (h_cond) & 1);
    157 }
    158 
    159 void
    160 m32rxf_h_psw_set_handler (SIM_CPU *current_cpu, UQI newval)
    161 {
    162   CPU (h_psw) = newval;
    163   CPU (h_cond) = newval & 1;
    164 }
    165 
    166 /* Cover fns to access h-accum.  */
    167 
    168 DI
    169 m32rxf_h_accum_get_handler (SIM_CPU *current_cpu)
    170 {
    171   /* Sign extend the top 8 bits.  */
    172   DI r;
    173   r = ANDDI (CPU (h_accum), MAKEDI (0xffffff, 0xffffffff));
    174   r = XORDI (r, MAKEDI (0x800000, 0));
    175   r = SUBDI (r, MAKEDI (0x800000, 0));
    176   return r;
    177 }
    178 
    179 void
    180 m32rxf_h_accum_set_handler (SIM_CPU *current_cpu, DI newval)
    181 {
    182   CPU (h_accum) = newval;
    183 }
    184 
    185 /* Cover fns to access h-accums.  */
    186 
    187 DI
    188 m32rxf_h_accums_get_handler (SIM_CPU *current_cpu, UINT regno)
    189 {
    190   /* FIXME: Yes, this is just a quick hack.  */
    191   DI r;
    192   if (regno == 0)
    193     r = CPU (h_accum);
    194   else
    195     r = CPU (h_accums[1]);
    196   /* Sign extend the top 8 bits.  */
    197   r = ANDDI (r, MAKEDI (0xffffff, 0xffffffff));
    198   r = XORDI (r, MAKEDI (0x800000, 0));
    199   r = SUBDI (r, MAKEDI (0x800000, 0));
    200   return r;
    201 }
    202 
    203 void
    204 m32rxf_h_accums_set_handler (SIM_CPU *current_cpu, UINT regno, DI newval)
    205 {
    206   /* FIXME: Yes, this is just a quick hack.  */
    207   if (regno == 0)
    208     CPU (h_accum) = newval;
    209   else
    210     CPU (h_accums[1]) = newval;
    211 }
    212 
    213 #if WITH_PROFILE_MODEL_P
    215 
    216 /* Initialize cycle counting for an insn.
    217    FIRST_P is non-zero if this is the first insn in a set of parallel
    218    insns.  */
    219 
    220 void
    221 m32rxf_model_insn_before (SIM_CPU *cpu, int first_p)
    222 {
    223   m32rbf_model_insn_before (cpu, first_p);
    224 }
    225 
    226 /* Record the cycles computed for an insn.
    227    LAST_P is non-zero if this is the last insn in a set of parallel insns,
    228    and we update the total cycle count.
    229    CYCLES is the cycle count of the insn.  */
    230 
    231 void
    232 m32rxf_model_insn_after (SIM_CPU *cpu, int last_p, int cycles)
    233 {
    234   m32rbf_model_insn_after (cpu, last_p, cycles);
    235 }
    236 
    237 static INLINE void
    238 check_load_stall (SIM_CPU *cpu, int regno)
    239 {
    240   UINT h_gr = CPU_M32R_MISC_PROFILE (cpu)->load_regs;
    241 
    242   if (regno != -1
    243       && (h_gr & (1 << regno)) != 0)
    244     {
    245       CPU_M32R_MISC_PROFILE (cpu)->load_stall += 2;
    246       if (TRACE_INSN_P (cpu))
    247 	cgen_trace_printf (cpu, " ; Load stall of 2 cycles.");
    248     }
    249 }
    250 
    251 int
    252 m32rxf_model_m32rx_u_exec (SIM_CPU *cpu, const IDESC *idesc,
    253 			   int unit_num, int referenced,
    254 			   INT sr, INT sr2, INT dr)
    255 {
    256   check_load_stall (cpu, sr);
    257   check_load_stall (cpu, sr2);
    258   return idesc->timing->units[unit_num].done;
    259 }
    260 
    261 int
    262 m32rxf_model_m32rx_u_cmp (SIM_CPU *cpu, const IDESC *idesc,
    263 			   int unit_num, int referenced,
    264 			   INT src1, INT src2)
    265 {
    266   check_load_stall (cpu, src1);
    267   check_load_stall (cpu, src2);
    268   return idesc->timing->units[unit_num].done;
    269 }
    270 
    271 int
    272 m32rxf_model_m32rx_u_mac (SIM_CPU *cpu, const IDESC *idesc,
    273 			   int unit_num, int referenced,
    274 			   INT src1, INT src2)
    275 {
    276   check_load_stall (cpu, src1);
    277   check_load_stall (cpu, src2);
    278   return idesc->timing->units[unit_num].done;
    279 }
    280 
    281 int
    282 m32rxf_model_m32rx_u_cti (SIM_CPU *cpu, const IDESC *idesc,
    283 			  int unit_num, int referenced,
    284 			  INT sr)
    285 {
    286   PROFILE_DATA *profile = CPU_PROFILE_DATA (cpu);
    287   int taken_p = (referenced & (1 << 1)) != 0;
    288 
    289   check_load_stall (cpu, sr);
    290   if (taken_p)
    291     {
    292       CPU_M32R_MISC_PROFILE (cpu)->cti_stall += 2;
    293       PROFILE_MODEL_TAKEN_COUNT (profile) += 1;
    294     }
    295   else
    296     PROFILE_MODEL_UNTAKEN_COUNT (profile) += 1;
    297   return idesc->timing->units[unit_num].done;
    298 }
    299 
    300 int
    301 m32rxf_model_m32rx_u_load (SIM_CPU *cpu, const IDESC *idesc,
    302 			   int unit_num, int referenced,
    303 			   INT sr, INT dr)
    304 {
    305   CPU_M32R_MISC_PROFILE (cpu)->load_regs_pending |= (1 << dr);
    306   return idesc->timing->units[unit_num].done;
    307 }
    308 
    309 int
    310 m32rxf_model_m32rx_u_store (SIM_CPU *cpu, const IDESC *idesc,
    311 			    int unit_num, int referenced,
    312 			    INT src1, INT src2)
    313 {
    314   return idesc->timing->units[unit_num].done;
    315 }
    316 
    317 #endif /* WITH_PROFILE_MODEL_P */
    318