1/* Simulator parallel routines for CGEN simulators (and maybe others). 2 Copyright (C) 1999-2023 Free Software Foundation, Inc. 3 Contributed by Cygnus Solutions. 4 5This file is part of the GNU instruction set simulator. 6 7This program is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 3 of the License, or 10(at your option) any later version. 11 12This program is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along 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#include <stdlib.h> 24 25#include "sim-main.h" 26#include "cgen-mem.h" 27#include "cgen-par.h" 28 29/* Functions required by the cgen interface. These functions add various 30 kinds of writes to the write queue. */ 31void sim_queue_bi_write (SIM_CPU *cpu, BI *target, BI value) 32{ 33 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 34 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 35 element->kind = CGEN_BI_WRITE; 36 element->insn_address = CPU_PC_GET (cpu); 37 element->kinds.bi_write.target = target; 38 element->kinds.bi_write.value = value; 39} 40 41void sim_queue_qi_write (SIM_CPU *cpu, UQI *target, UQI value) 42{ 43 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 44 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 45 element->kind = CGEN_QI_WRITE; 46 element->insn_address = CPU_PC_GET (cpu); 47 element->kinds.qi_write.target = target; 48 element->kinds.qi_write.value = value; 49} 50 51void sim_queue_si_write (SIM_CPU *cpu, SI *target, SI value) 52{ 53 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 54 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 55 element->kind = CGEN_SI_WRITE; 56 element->insn_address = CPU_PC_GET (cpu); 57 element->kinds.si_write.target = target; 58 element->kinds.si_write.value = value; 59} 60 61void sim_queue_sf_write (SIM_CPU *cpu, SI *target, SF value) 62{ 63 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 64 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 65 element->kind = CGEN_SF_WRITE; 66 element->insn_address = CPU_PC_GET (cpu); 67 element->kinds.sf_write.target = target; 68 element->kinds.sf_write.value = value; 69} 70 71void sim_queue_pc_write (SIM_CPU *cpu, USI value) 72{ 73 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 74 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 75 element->kind = CGEN_PC_WRITE; 76 element->insn_address = CPU_PC_GET (cpu); 77 element->kinds.pc_write.value = value; 78} 79 80void sim_queue_fn_hi_write ( 81 SIM_CPU *cpu, 82 void (*write_function)(SIM_CPU *cpu, UINT, UHI), 83 UINT regno, 84 UHI value 85) 86{ 87 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 88 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 89 element->kind = CGEN_FN_HI_WRITE; 90 element->insn_address = CPU_PC_GET (cpu); 91 element->kinds.fn_hi_write.function = write_function; 92 element->kinds.fn_hi_write.regno = regno; 93 element->kinds.fn_hi_write.value = value; 94} 95 96void sim_queue_fn_si_write ( 97 SIM_CPU *cpu, 98 void (*write_function)(SIM_CPU *cpu, UINT, USI), 99 UINT regno, 100 USI value 101) 102{ 103 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 104 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 105 element->kind = CGEN_FN_SI_WRITE; 106 element->insn_address = CPU_PC_GET (cpu); 107 element->kinds.fn_si_write.function = write_function; 108 element->kinds.fn_si_write.regno = regno; 109 element->kinds.fn_si_write.value = value; 110} 111 112void sim_queue_fn_sf_write ( 113 SIM_CPU *cpu, 114 void (*write_function)(SIM_CPU *cpu, UINT, SF), 115 UINT regno, 116 SF value 117) 118{ 119 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 120 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 121 element->kind = CGEN_FN_SF_WRITE; 122 element->insn_address = CPU_PC_GET (cpu); 123 element->kinds.fn_sf_write.function = write_function; 124 element->kinds.fn_sf_write.regno = regno; 125 element->kinds.fn_sf_write.value = value; 126} 127 128void sim_queue_fn_di_write ( 129 SIM_CPU *cpu, 130 void (*write_function)(SIM_CPU *cpu, UINT, DI), 131 UINT regno, 132 DI value 133) 134{ 135 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 136 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 137 element->kind = CGEN_FN_DI_WRITE; 138 element->insn_address = CPU_PC_GET (cpu); 139 element->kinds.fn_di_write.function = write_function; 140 element->kinds.fn_di_write.regno = regno; 141 element->kinds.fn_di_write.value = value; 142} 143 144void sim_queue_fn_xi_write ( 145 SIM_CPU *cpu, 146 void (*write_function)(SIM_CPU *cpu, UINT, SI *), 147 UINT regno, 148 SI *value 149) 150{ 151 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 152 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 153 element->kind = CGEN_FN_XI_WRITE; 154 element->insn_address = CPU_PC_GET (cpu); 155 element->kinds.fn_xi_write.function = write_function; 156 element->kinds.fn_xi_write.regno = regno; 157 element->kinds.fn_xi_write.value[0] = value[0]; 158 element->kinds.fn_xi_write.value[1] = value[1]; 159 element->kinds.fn_xi_write.value[2] = value[2]; 160 element->kinds.fn_xi_write.value[3] = value[3]; 161} 162 163void sim_queue_fn_df_write ( 164 SIM_CPU *cpu, 165 void (*write_function)(SIM_CPU *cpu, UINT, DF), 166 UINT regno, 167 DF value 168) 169{ 170 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 171 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 172 element->kind = CGEN_FN_DF_WRITE; 173 element->insn_address = CPU_PC_GET (cpu); 174 element->kinds.fn_df_write.function = write_function; 175 element->kinds.fn_df_write.regno = regno; 176 element->kinds.fn_df_write.value = value; 177} 178 179void sim_queue_fn_pc_write ( 180 SIM_CPU *cpu, 181 void (*write_function)(SIM_CPU *cpu, USI), 182 USI value 183) 184{ 185 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 186 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 187 element->kind = CGEN_FN_PC_WRITE; 188 element->insn_address = CPU_PC_GET (cpu); 189 element->kinds.fn_pc_write.function = write_function; 190 element->kinds.fn_pc_write.value = value; 191} 192 193void sim_queue_mem_qi_write (SIM_CPU *cpu, SI address, QI value) 194{ 195 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 196 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 197 element->kind = CGEN_MEM_QI_WRITE; 198 element->insn_address = CPU_PC_GET (cpu); 199 element->kinds.mem_qi_write.address = address; 200 element->kinds.mem_qi_write.value = value; 201} 202 203void sim_queue_mem_hi_write (SIM_CPU *cpu, SI address, HI value) 204{ 205 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 206 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 207 element->kind = CGEN_MEM_HI_WRITE; 208 element->insn_address = CPU_PC_GET (cpu); 209 element->kinds.mem_hi_write.address = address; 210 element->kinds.mem_hi_write.value = value; 211} 212 213void sim_queue_mem_si_write (SIM_CPU *cpu, SI address, SI value) 214{ 215 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 216 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 217 element->kind = CGEN_MEM_SI_WRITE; 218 element->insn_address = CPU_PC_GET (cpu); 219 element->kinds.mem_si_write.address = address; 220 element->kinds.mem_si_write.value = value; 221} 222 223void sim_queue_mem_di_write (SIM_CPU *cpu, SI address, DI value) 224{ 225 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 226 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 227 element->kind = CGEN_MEM_DI_WRITE; 228 element->insn_address = CPU_PC_GET (cpu); 229 element->kinds.mem_di_write.address = address; 230 element->kinds.mem_di_write.value = value; 231} 232 233void sim_queue_mem_df_write (SIM_CPU *cpu, SI address, DF value) 234{ 235 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 236 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 237 element->kind = CGEN_MEM_DF_WRITE; 238 element->insn_address = CPU_PC_GET (cpu); 239 element->kinds.mem_df_write.address = address; 240 element->kinds.mem_df_write.value = value; 241} 242 243void sim_queue_mem_xi_write (SIM_CPU *cpu, SI address, SI *value) 244{ 245 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 246 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 247 element->kind = CGEN_MEM_XI_WRITE; 248 element->insn_address = CPU_PC_GET (cpu); 249 element->kinds.mem_xi_write.address = address; 250 element->kinds.mem_xi_write.value[0] = value[0]; 251 element->kinds.mem_xi_write.value[1] = value[1]; 252 element->kinds.mem_xi_write.value[2] = value[2]; 253 element->kinds.mem_xi_write.value[3] = value[3]; 254} 255 256void sim_queue_fn_mem_qi_write ( 257 SIM_CPU *cpu, 258 void (*write_function)(SIM_CPU *cpu, IADDR, SI, QI), 259 SI address, 260 QI value 261) 262{ 263 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 264 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 265 element->kind = CGEN_FN_MEM_QI_WRITE; 266 element->insn_address = CPU_PC_GET (cpu); 267 element->kinds.fn_mem_qi_write.function = write_function; 268 element->kinds.fn_mem_qi_write.address = address; 269 element->kinds.fn_mem_qi_write.value = value; 270} 271 272void sim_queue_fn_mem_hi_write ( 273 SIM_CPU *cpu, 274 void (*write_function)(SIM_CPU *cpu, IADDR, SI, HI), 275 SI address, 276 HI value 277) 278{ 279 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 280 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 281 element->kind = CGEN_FN_MEM_HI_WRITE; 282 element->insn_address = CPU_PC_GET (cpu); 283 element->kinds.fn_mem_hi_write.function = write_function; 284 element->kinds.fn_mem_hi_write.address = address; 285 element->kinds.fn_mem_hi_write.value = value; 286} 287 288void sim_queue_fn_mem_si_write ( 289 SIM_CPU *cpu, 290 void (*write_function)(SIM_CPU *cpu, IADDR, SI, SI), 291 SI address, 292 SI value 293) 294{ 295 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 296 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 297 element->kind = CGEN_FN_MEM_SI_WRITE; 298 element->insn_address = CPU_PC_GET (cpu); 299 element->kinds.fn_mem_si_write.function = write_function; 300 element->kinds.fn_mem_si_write.address = address; 301 element->kinds.fn_mem_si_write.value = value; 302} 303 304void sim_queue_fn_mem_di_write ( 305 SIM_CPU *cpu, 306 void (*write_function)(SIM_CPU *cpu, IADDR, SI, DI), 307 SI address, 308 DI value 309) 310{ 311 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 312 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 313 element->kind = CGEN_FN_MEM_DI_WRITE; 314 element->insn_address = CPU_PC_GET (cpu); 315 element->kinds.fn_mem_di_write.function = write_function; 316 element->kinds.fn_mem_di_write.address = address; 317 element->kinds.fn_mem_di_write.value = value; 318} 319 320void sim_queue_fn_mem_df_write ( 321 SIM_CPU *cpu, 322 void (*write_function)(SIM_CPU *cpu, IADDR, SI, DF), 323 SI address, 324 DF value 325) 326{ 327 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 328 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 329 element->kind = CGEN_FN_MEM_DF_WRITE; 330 element->insn_address = CPU_PC_GET (cpu); 331 element->kinds.fn_mem_df_write.function = write_function; 332 element->kinds.fn_mem_df_write.address = address; 333 element->kinds.fn_mem_df_write.value = value; 334} 335 336void sim_queue_fn_mem_xi_write ( 337 SIM_CPU *cpu, 338 void (*write_function)(SIM_CPU *cpu, IADDR, SI, SI *), 339 SI address, 340 SI *value 341) 342{ 343 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); 344 CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); 345 element->kind = CGEN_FN_MEM_XI_WRITE; 346 element->insn_address = CPU_PC_GET (cpu); 347 element->kinds.fn_mem_xi_write.function = write_function; 348 element->kinds.fn_mem_xi_write.address = address; 349 element->kinds.fn_mem_xi_write.value[0] = value[0]; 350 element->kinds.fn_mem_xi_write.value[1] = value[1]; 351 element->kinds.fn_mem_xi_write.value[2] = value[2]; 352 element->kinds.fn_mem_xi_write.value[3] = value[3]; 353} 354 355/* Execute a write stored on the write queue. */ 356void 357cgen_write_queue_element_execute (SIM_CPU *cpu, CGEN_WRITE_QUEUE_ELEMENT *item) 358{ 359 IADDR pc; 360 switch (CGEN_WRITE_QUEUE_ELEMENT_KIND (item)) 361 { 362 case CGEN_BI_WRITE: 363 *item->kinds.bi_write.target = item->kinds.bi_write.value; 364 break; 365 case CGEN_QI_WRITE: 366 *item->kinds.qi_write.target = item->kinds.qi_write.value; 367 break; 368 case CGEN_SI_WRITE: 369 *item->kinds.si_write.target = item->kinds.si_write.value; 370 break; 371 case CGEN_SF_WRITE: 372 *item->kinds.sf_write.target = item->kinds.sf_write.value; 373 break; 374 case CGEN_PC_WRITE: 375 CPU_PC_SET (cpu, item->kinds.pc_write.value); 376 break; 377 case CGEN_FN_HI_WRITE: 378 item->kinds.fn_hi_write.function (cpu, 379 item->kinds.fn_hi_write.regno, 380 item->kinds.fn_hi_write.value); 381 break; 382 case CGEN_FN_SI_WRITE: 383 item->kinds.fn_si_write.function (cpu, 384 item->kinds.fn_si_write.regno, 385 item->kinds.fn_si_write.value); 386 break; 387 case CGEN_FN_SF_WRITE: 388 item->kinds.fn_sf_write.function (cpu, 389 item->kinds.fn_sf_write.regno, 390 item->kinds.fn_sf_write.value); 391 break; 392 case CGEN_FN_DI_WRITE: 393 item->kinds.fn_di_write.function (cpu, 394 item->kinds.fn_di_write.regno, 395 item->kinds.fn_di_write.value); 396 break; 397 case CGEN_FN_DF_WRITE: 398 item->kinds.fn_df_write.function (cpu, 399 item->kinds.fn_df_write.regno, 400 item->kinds.fn_df_write.value); 401 break; 402 case CGEN_FN_XI_WRITE: 403 item->kinds.fn_xi_write.function (cpu, 404 item->kinds.fn_xi_write.regno, 405 item->kinds.fn_xi_write.value); 406 break; 407 case CGEN_FN_PC_WRITE: 408 item->kinds.fn_pc_write.function (cpu, item->kinds.fn_pc_write.value); 409 break; 410 case CGEN_MEM_QI_WRITE: 411 pc = item->insn_address; 412 SETMEMQI (cpu, pc, item->kinds.mem_qi_write.address, 413 item->kinds.mem_qi_write.value); 414 break; 415 case CGEN_MEM_HI_WRITE: 416 pc = item->insn_address; 417 SETMEMHI (cpu, pc, item->kinds.mem_hi_write.address, 418 item->kinds.mem_hi_write.value); 419 break; 420 case CGEN_MEM_SI_WRITE: 421 pc = item->insn_address; 422 SETMEMSI (cpu, pc, item->kinds.mem_si_write.address, 423 item->kinds.mem_si_write.value); 424 break; 425 case CGEN_MEM_DI_WRITE: 426 pc = item->insn_address; 427 SETMEMDI (cpu, pc, item->kinds.mem_di_write.address, 428 item->kinds.mem_di_write.value); 429 break; 430 case CGEN_MEM_DF_WRITE: 431 pc = item->insn_address; 432 SETMEMDF (cpu, pc, item->kinds.mem_df_write.address, 433 item->kinds.mem_df_write.value); 434 break; 435 case CGEN_MEM_XI_WRITE: 436 pc = item->insn_address; 437 SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address, 438 item->kinds.mem_xi_write.value[0]); 439 SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 4, 440 item->kinds.mem_xi_write.value[1]); 441 SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 8, 442 item->kinds.mem_xi_write.value[2]); 443 SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 12, 444 item->kinds.mem_xi_write.value[3]); 445 break; 446 case CGEN_FN_MEM_QI_WRITE: 447 pc = item->insn_address; 448 item->kinds.fn_mem_qi_write.function (cpu, pc, 449 item->kinds.fn_mem_qi_write.address, 450 item->kinds.fn_mem_qi_write.value); 451 break; 452 case CGEN_FN_MEM_HI_WRITE: 453 pc = item->insn_address; 454 item->kinds.fn_mem_hi_write.function (cpu, pc, 455 item->kinds.fn_mem_hi_write.address, 456 item->kinds.fn_mem_hi_write.value); 457 break; 458 case CGEN_FN_MEM_SI_WRITE: 459 pc = item->insn_address; 460 item->kinds.fn_mem_si_write.function (cpu, pc, 461 item->kinds.fn_mem_si_write.address, 462 item->kinds.fn_mem_si_write.value); 463 break; 464 case CGEN_FN_MEM_DI_WRITE: 465 pc = item->insn_address; 466 item->kinds.fn_mem_di_write.function (cpu, pc, 467 item->kinds.fn_mem_di_write.address, 468 item->kinds.fn_mem_di_write.value); 469 break; 470 case CGEN_FN_MEM_DF_WRITE: 471 pc = item->insn_address; 472 item->kinds.fn_mem_df_write.function (cpu, pc, 473 item->kinds.fn_mem_df_write.address, 474 item->kinds.fn_mem_df_write.value); 475 break; 476 case CGEN_FN_MEM_XI_WRITE: 477 pc = item->insn_address; 478 item->kinds.fn_mem_xi_write.function (cpu, pc, 479 item->kinds.fn_mem_xi_write.address, 480 item->kinds.fn_mem_xi_write.value); 481 break; 482 default: 483 abort (); 484 break; /* FIXME: for now....print message later. */ 485 } 486} 487 488/* Utilities for the write queue. */ 489CGEN_WRITE_QUEUE_ELEMENT * 490cgen_write_queue_overflow (CGEN_WRITE_QUEUE *q) 491{ 492 abort (); /* FIXME: for now....print message later. */ 493 return 0; 494} 495