1 /* Simulator parallel routines for CGEN simulators (and maybe others). 2 Copyright (C) 1999-2014 Free Software Foundation, Inc. 3 Contributed by Cygnus Solutions. 4 5 This file is part of the GNU instruction set simulator. 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 #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. */ 26 void 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 36 void 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 46 void 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 56 void 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 66 void 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 75 void 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 91 void 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 107 void 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 123 void 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 139 void 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 158 void 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 174 void 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 188 void 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 198 void 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 208 void 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 218 void 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 228 void 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 238 void 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 251 void 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 267 void 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 283 void 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 299 void 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 315 void 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 331 void 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. */ 351 void 352 cgen_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. */ 484 CGEN_WRITE_QUEUE_ELEMENT * 485 cgen_write_queue_overflow (CGEN_WRITE_QUEUE *q) 486 { 487 abort (); /* FIXME: for now....print message later. */ 488 return 0; 489 } 490