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