1285612Sdelphij/* m32rx simulator support code 2132451Sroberto Copyright (C) 1997-2023 Free Software Foundation, Inc. 354359Sroberto Contributed by Cygnus Support. 4285612Sdelphij 5285612SdelphijThis file is part of GDB, the GNU debugger. 654359Sroberto 754359SrobertoThis program is free software; you can redistribute it and/or modify 854359Srobertoit under the terms of the GNU General Public License as published by 954359Srobertothe Free Software Foundation; either version 3 of the License, or 1054359Sroberto(at your option) any later version. 1154359Sroberto 1254359SrobertoThis program is distributed in the hope that it will be useful, 1354359Srobertobut WITHOUT ANY WARRANTY; without even the implied warranty of 1454359SrobertoMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15106163SrobertoGNU General Public License for more details. 16106163Sroberto 1754359SrobertoYou should have received a copy of the GNU General Public License 18285612Sdelphijalong with this program. If not, see <http://www.gnu.org/licenses/>. */ 19285612Sdelphij 20285612Sdelphij/* This must come before any other includes. */ 21285612Sdelphij#include "defs.h" 22285612Sdelphij 23285612Sdelphij#define WANT_CPU m32rxf 24285612Sdelphij#define WANT_CPU_M32RXF 25285612Sdelphij 26285612Sdelphij#include "sim-main.h" 27285612Sdelphij#include "cgen-mem.h" 28285612Sdelphij#include "cgen-ops.h" 29285612Sdelphij 30285612Sdelphij/* The contents of BUF are in target byte order. */ 31285612Sdelphij 32285612Sdelphijint 33285612Sdelphijm32rxf_fetch_register (SIM_CPU *current_cpu, int rn, void *buf, int len) 34285612Sdelphij{ 35285612Sdelphij return m32rbf_fetch_register (current_cpu, rn, buf, len); 36285612Sdelphij} 37285612Sdelphij 38285612Sdelphij/* The contents of BUF are in target byte order. */ 39285612Sdelphij 40285612Sdelphijint 41285612Sdelphijm32rxf_store_register (SIM_CPU *current_cpu, int rn, const void *buf, int len) 42285612Sdelphij{ 43285612Sdelphij return m32rbf_store_register (current_cpu, rn, buf, len); 44285612Sdelphij} 45285612Sdelphij 46285612Sdelphij/* Cover fns to get/set the control registers. 47285612Sdelphij FIXME: Duplicated from m32r.c. The issue is structure offsets. */ 48285612Sdelphij 49285612SdelphijUSI 50285612Sdelphijm32rxf_h_cr_get_handler (SIM_CPU *current_cpu, UINT cr) 51285612Sdelphij{ 52285612Sdelphij switch (cr) 53285612Sdelphij { 54285612Sdelphij case H_CR_PSW : /* psw */ 55285612Sdelphij return (((CPU (h_bpsw) & 0xc1) << 8) 56285612Sdelphij | ((CPU (h_psw) & 0xc0) << 0) 57285612Sdelphij | GET_H_COND ()); 58285612Sdelphij case H_CR_BBPSW : /* backup backup psw */ 59285612Sdelphij return CPU (h_bbpsw) & 0xc1; 60285612Sdelphij case H_CR_CBR : /* condition bit */ 61285612Sdelphij return GET_H_COND (); 62285612Sdelphij case H_CR_SPI : /* interrupt stack pointer */ 63285612Sdelphij if (! GET_H_SM ()) 64285612Sdelphij return CPU (h_gr[H_GR_SP]); 65285612Sdelphij else 66285612Sdelphij return CPU (h_cr[H_CR_SPI]); 67285612Sdelphij case H_CR_SPU : /* user stack pointer */ 68285612Sdelphij if (GET_H_SM ()) 69285612Sdelphij return CPU (h_gr[H_GR_SP]); 70285612Sdelphij else 71285612Sdelphij return CPU (h_cr[H_CR_SPU]); 72285612Sdelphij case H_CR_BPC : /* backup pc */ 7354359Sroberto return CPU (h_cr[H_CR_BPC]) & 0xfffffffe; 74200576Sroberto case H_CR_BBPC : /* backup backup pc */ 7554359Sroberto return CPU (h_cr[H_CR_BBPC]) & 0xfffffffe; 76200576Sroberto case 4 : /* ??? unspecified, but apparently available */ 77132451Sroberto case 5 : /* ??? unspecified, but apparently available */ 78132451Sroberto return CPU (h_cr[cr]); 79132451Sroberto default : 80132451Sroberto return 0; 8182498Sroberto } 82132451Sroberto} 8354359Sroberto 8454359Srobertovoid 8554359Srobertom32rxf_h_cr_set_handler (SIM_CPU *current_cpu, UINT cr, USI newval) 8654359Sroberto{ 8754359Sroberto switch (cr) 8854359Sroberto { 8954359Sroberto case H_CR_PSW : /* psw */ 9054359Sroberto { 91285612Sdelphij int old_sm = (CPU (h_psw) & 0x80) != 0; 92182007Sroberto int new_sm = (newval & 0x80) != 0; 93182007Sroberto CPU (h_bpsw) = (newval >> 8) & 0xff; 94285612Sdelphij CPU (h_psw) = newval & 0xff; 95285612Sdelphij SET_H_COND (newval & 1); 96285612Sdelphij /* When switching stack modes, update the registers. */ 97285612Sdelphij if (old_sm != new_sm) 98285612Sdelphij { 99285612Sdelphij if (old_sm) 100285612Sdelphij { 101285612Sdelphij /* Switching user -> system. */ 102285612Sdelphij CPU (h_cr[H_CR_SPU]) = CPU (h_gr[H_GR_SP]); 103285612Sdelphij CPU (h_gr[H_GR_SP]) = CPU (h_cr[H_CR_SPI]); 104285612Sdelphij } 105285612Sdelphij else 106285612Sdelphij { 107285612Sdelphij /* Switching system -> user. */ 108285612Sdelphij CPU (h_cr[H_CR_SPI]) = CPU (h_gr[H_GR_SP]); 109285612Sdelphij CPU (h_gr[H_GR_SP]) = CPU (h_cr[H_CR_SPU]); 110285612Sdelphij } 111285612Sdelphij } 112285612Sdelphij break; 113285612Sdelphij } 114285612Sdelphij case H_CR_BBPSW : /* backup backup psw */ 115285612Sdelphij CPU (h_bbpsw) = newval & 0xff; 116285612Sdelphij break; 117285612Sdelphij case H_CR_CBR : /* condition bit */ 118285612Sdelphij SET_H_COND (newval & 1); 119285612Sdelphij break; 120289999Sglebius case H_CR_SPI : /* interrupt stack pointer */ 121285612Sdelphij if (! GET_H_SM ()) 122285612Sdelphij CPU (h_gr[H_GR_SP]) = newval; 123285612Sdelphij else 124285612Sdelphij CPU (h_cr[H_CR_SPI]) = newval; 125285612Sdelphij break; 126285612Sdelphij case H_CR_SPU : /* user stack pointer */ 127285612Sdelphij if (GET_H_SM ()) 128285612Sdelphij CPU (h_gr[H_GR_SP]) = newval; 129285612Sdelphij else 130285612Sdelphij CPU (h_cr[H_CR_SPU]) = newval; 131285612Sdelphij break; 132182007Sroberto case H_CR_BPC : /* backup pc */ 133182007Sroberto CPU (h_cr[H_CR_BPC]) = newval; 134285612Sdelphij break; 135182007Sroberto case H_CR_BBPC : /* backup backup pc */ 136182007Sroberto CPU (h_cr[H_CR_BBPC]) = newval; 137182007Sroberto break; 138200576Sroberto case 4 : /* ??? unspecified, but apparently available */ 139182007Sroberto case 5 : /* ??? unspecified, but apparently available */ 140182007Sroberto CPU (h_cr[cr]) = newval; 141285612Sdelphij break; 142285612Sdelphij default : 143285612Sdelphij /* ignore */ 144285612Sdelphij break; 145285612Sdelphij } 146285612Sdelphij} 147285612Sdelphij 148285612Sdelphij/* Cover fns to access h-psw. */ 149285612Sdelphij 150182007SrobertoUQI 151285612Sdelphijm32rxf_h_psw_get_handler (SIM_CPU *current_cpu) 152285612Sdelphij{ 153285612Sdelphij return (CPU (h_psw) & 0xfe) | (CPU (h_cond) & 1); 154285612Sdelphij} 155285612Sdelphij 156285612Sdelphijvoid 157285612Sdelphijm32rxf_h_psw_set_handler (SIM_CPU *current_cpu, UQI newval) 158285612Sdelphij{ 159285612Sdelphij CPU (h_psw) = newval; 160285612Sdelphij CPU (h_cond) = newval & 1; 161285612Sdelphij} 162285612Sdelphij 163285612Sdelphij/* Cover fns to access h-accum. */ 164285612Sdelphij 165285612SdelphijDI 166285612Sdelphijm32rxf_h_accum_get_handler (SIM_CPU *current_cpu) 167200576Sroberto{ 168285612Sdelphij /* Sign extend the top 8 bits. */ 169182007Sroberto DI r; 170200576Sroberto r = ANDDI (CPU (h_accum), MAKEDI (0xffffff, 0xffffffff)); 171182007Sroberto r = XORDI (r, MAKEDI (0x800000, 0)); 172182007Sroberto r = SUBDI (r, MAKEDI (0x800000, 0)); 173285612Sdelphij return r; 174285612Sdelphij} 175285612Sdelphij 176285612Sdelphijvoid 177285612Sdelphijm32rxf_h_accum_set_handler (SIM_CPU *current_cpu, DI newval) 178285612Sdelphij{ 179285612Sdelphij CPU (h_accum) = newval; 180285612Sdelphij} 181182007Sroberto 182285612Sdelphij/* Cover fns to access h-accums. */ 183285612Sdelphij 184285612SdelphijDI 185285612Sdelphijm32rxf_h_accums_get_handler (SIM_CPU *current_cpu, UINT regno) 186285612Sdelphij{ 187285612Sdelphij /* FIXME: Yes, this is just a quick hack. */ 188285612Sdelphij DI r; 189285612Sdelphij if (regno == 0) 190285612Sdelphij r = CPU (h_accum); 191285612Sdelphij else 192285612Sdelphij r = CPU (h_accums[1]); 193285612Sdelphij /* Sign extend the top 8 bits. */ 194285612Sdelphij r = ANDDI (r, MAKEDI (0xffffff, 0xffffffff)); 195285612Sdelphij r = XORDI (r, MAKEDI (0x800000, 0)); 196285612Sdelphij r = SUBDI (r, MAKEDI (0x800000, 0)); 197285612Sdelphij return r; 198285612Sdelphij} 199285612Sdelphij 200285612Sdelphijvoid 201285612Sdelphijm32rxf_h_accums_set_handler (SIM_CPU *current_cpu, UINT regno, DI newval) 202285612Sdelphij{ 203285612Sdelphij /* FIXME: Yes, this is just a quick hack. */ 204285612Sdelphij if (regno == 0) 205285612Sdelphij CPU (h_accum) = newval; 206285612Sdelphij else 207285612Sdelphij CPU (h_accums[1]) = newval; 208285612Sdelphij} 209285612Sdelphij 210285612Sdelphij#if WITH_PROFILE_MODEL_P 211285612Sdelphij 212285612Sdelphij/* Initialize cycle counting for an insn. 213182007Sroberto FIRST_P is non-zero if this is the first insn in a set of parallel 214182007Sroberto insns. */ 215285612Sdelphij 216285612Sdelphijvoid 217285612Sdelphijm32rxf_model_insn_before (SIM_CPU *cpu, int first_p) 218182007Sroberto{ 219132451Sroberto m32rbf_model_insn_before (cpu, first_p); 220285612Sdelphij} 22154359Sroberto 222285612Sdelphij/* Record the cycles computed for an insn. 223182007Sroberto LAST_P is non-zero if this is the last insn in a set of parallel insns, 224132451Sroberto and we update the total cycle count. 225132451Sroberto CYCLES is the cycle count of the insn. */ 226132451Sroberto 22754359Srobertovoid 228289999Sglebiusm32rxf_model_insn_after (SIM_CPU *cpu, int last_p, int cycles) 229285612Sdelphij{ 230285612Sdelphij m32rbf_model_insn_after (cpu, last_p, cycles); 231285612Sdelphij} 232285612Sdelphij 233285612Sdelphijstatic INLINE void 23454359Srobertocheck_load_stall (SIM_CPU *cpu, int regno) 235132451Sroberto{ 23654359Sroberto UINT h_gr = CPU_M32R_MISC_PROFILE (cpu)->load_regs; 237289999Sglebius 238285612Sdelphij if (regno != -1 23954359Sroberto && (h_gr & (1 << regno)) != 0) 240285612Sdelphij { 24154359Sroberto CPU_M32R_MISC_PROFILE (cpu)->load_stall += 2; 242132451Sroberto if (TRACE_INSN_P (cpu)) 243285612Sdelphij cgen_trace_printf (cpu, " ; Load stall of 2 cycles."); 244285612Sdelphij } 245285612Sdelphij} 246285612Sdelphij 247285612Sdelphijint 248285612Sdelphijm32rxf_model_m32rx_u_exec (SIM_CPU *cpu, const IDESC *idesc, 249132451Sroberto int unit_num, int referenced, 25054359Sroberto INT sr, INT sr2, INT dr) 251132451Sroberto{ 25256746Sroberto check_load_stall (cpu, sr); 253285612Sdelphij check_load_stall (cpu, sr2); 254285612Sdelphij return idesc->timing->units[unit_num].done; 255285612Sdelphij} 256132451Sroberto 257132451Srobertoint 258132451Srobertom32rxf_model_m32rx_u_cmp (SIM_CPU *cpu, const IDESC *idesc, 259285612Sdelphij int unit_num, int referenced, 260132451Sroberto INT src1, INT src2) 261106163Sroberto{ 262285612Sdelphij check_load_stall (cpu, src1); 263200576Sroberto check_load_stall (cpu, src2); 264285612Sdelphij return idesc->timing->units[unit_num].done; 265285612Sdelphij} 266285612Sdelphij 267285612Sdelphijint 268285612Sdelphijm32rxf_model_m32rx_u_mac (SIM_CPU *cpu, const IDESC *idesc, 269200576Sroberto int unit_num, int referenced, 270285612Sdelphij INT src1, INT src2) 271285612Sdelphij{ 272285612Sdelphij check_load_stall (cpu, src1); 273200576Sroberto check_load_stall (cpu, src2); 274132451Sroberto return idesc->timing->units[unit_num].done; 275132451Sroberto} 276132451Sroberto 27782498Srobertoint 278285612Sdelphijm32rxf_model_m32rx_u_cti (SIM_CPU *cpu, const IDESC *idesc, 279285612Sdelphij int unit_num, int referenced, 280285612Sdelphij INT sr) 281285612Sdelphij{ 282285612Sdelphij PROFILE_DATA *profile = CPU_PROFILE_DATA (cpu); 283285612Sdelphij int taken_p = (referenced & (1 << 1)) != 0; 28454359Sroberto 285285612Sdelphij check_load_stall (cpu, sr); 286285612Sdelphij if (taken_p) 287285612Sdelphij { 288132451Sroberto CPU_M32R_MISC_PROFILE (cpu)->cti_stall += 2; 289182007Sroberto PROFILE_MODEL_TAKEN_COUNT (profile) += 1; 290182007Sroberto } 291182007Sroberto else 29254359Sroberto PROFILE_MODEL_UNTAKEN_COUNT (profile) += 1; 293132451Sroberto return idesc->timing->units[unit_num].done; 294182007Sroberto} 295285612Sdelphij 296285612Sdelphijint 29754359Srobertom32rxf_model_m32rx_u_load (SIM_CPU *cpu, const IDESC *idesc, 298200576Sroberto int unit_num, int referenced, 299289999Sglebius INT sr, INT dr) 300132451Sroberto{ 301132451Sroberto CPU_M32R_MISC_PROFILE (cpu)->load_regs_pending |= (1 << dr); 30254359Sroberto return idesc->timing->units[unit_num].done; 303182007Sroberto} 30454359Sroberto 305132451Srobertoint 30654359Srobertom32rxf_model_m32rx_u_store (SIM_CPU *cpu, const IDESC *idesc, 30754359Sroberto int unit_num, int referenced, 308132451Sroberto INT src1, INT src2) 309285612Sdelphij{ 31054359Sroberto return idesc->timing->units[unit_num].done; 31154359Sroberto} 31254359Sroberto 31382498Sroberto#endif /* WITH_PROFILE_MODEL_P */ 314285612Sdelphij