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