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