1 /* Simulation code for the CR16 processor. 2 Copyright (C) 2008-2024 Free Software Foundation, Inc. 3 Contributed by M Ranga Swami Reddy <MR.Swami.Reddy@nsc.com> 4 5 This file is part of GDB, the GNU debugger. 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, or (at your option) 10 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 /* This must come before any other includes. */ 21 #include "defs.h" 22 23 #include <inttypes.h> 24 #include <signal.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include "bfd.h" 28 #include "sim/callback.h" 29 #include "sim/sim.h" 30 31 #include "sim-main.h" 32 #include "sim-options.h" 33 #include "sim-signal.h" 34 35 #include "sim/sim-cr16.h" 36 #include "gdb/signals.h" 37 #include "opcode/cr16.h" 38 39 #include "target-newlib-syscall.h" 40 41 #include "cr16-sim.h" 42 43 struct _state State; 44 45 int cr16_debug; 46 47 uint32_t OP[4]; 48 uint32_t sign_flag; 49 50 static struct hash_entry *lookup_hash (SIM_DESC, SIM_CPU *, uint64_t ins, int size); 51 static void get_operands (operand_desc *s, uint64_t mcode, int isize, int nops); 52 53 #define MAX_HASH 16 54 55 struct hash_entry 56 { 57 struct hash_entry *next; 58 uint32_t opcode; 59 uint32_t mask; 60 int format; 61 int size; 62 struct simops *ops; 63 }; 64 65 struct hash_entry hash_table[MAX_HASH+1]; 66 67 INLINE static long 68 hash(unsigned long long insn, int format) 69 { 70 unsigned int i = 4; 71 if (format) 72 { 73 while ((insn >> i) != 0) i +=4; 74 75 return ((insn >> (i-4)) & 0xf); /* Use last 4 bits as hask key. */ 76 } 77 return ((insn & 0xF)); /* Use last 4 bits as hask key. */ 78 } 79 80 81 INLINE static struct hash_entry * 82 lookup_hash (SIM_DESC sd, SIM_CPU *cpu, uint64_t ins, int size) 83 { 84 uint32_t mask; 85 struct hash_entry *h; 86 87 h = &hash_table[hash(ins,1)]; 88 89 90 mask = (((1 << (32 - h->mask)) -1) << h->mask); 91 92 /* Adjuest mask for branch with 2 word instructions. */ 93 if (streq(h->ops->mnemonic,"b") && h->size == 2) 94 mask = 0xff0f0000; 95 96 97 while ((ins & mask) != (BIN(h->opcode, h->mask))) 98 { 99 if (h->next == NULL) 100 sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGILL); 101 h = h->next; 102 103 mask = (((1 << (32 - h->mask)) -1) << h->mask); 104 /* Adjuest mask for branch with 2 word instructions. */ 105 if ((streq(h->ops->mnemonic,"b")) && h->size == 2) 106 mask = 0xff0f0000; 107 108 } 109 return (h); 110 } 111 112 INLINE static void 113 get_operands (operand_desc *s, uint64_t ins, int isize, int nops) 114 { 115 uint32_t i, opn = 0, start_bit = 0, op_type = 0; 116 int32_t op_size = 0; 117 118 if (isize == 1) /* Trunkcate the extra 16 bits of INS. */ 119 ins = ins >> 16; 120 121 for (i=0; i < 4; ++i,++opn) 122 { 123 if (s[opn].op_type == dummy) break; 124 125 op_type = s[opn].op_type; 126 start_bit = s[opn].shift; 127 op_size = cr16_optab[op_type].bit_size; 128 129 switch (op_type) 130 { 131 case imm3: case imm4: case imm5: case imm6: 132 { 133 if (isize == 1) 134 OP[i] = ((ins >> 4) & ((1 << op_size) -1)); 135 else 136 OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1)); 137 138 if (OP[i] & ((long)1 << (op_size -1))) 139 { 140 sign_flag = 1; 141 OP[i] = ~(OP[i]) + 1; 142 } 143 OP[i] = (unsigned long int)(OP[i] & (((long)1 << op_size) -1)); 144 } 145 break; 146 147 case uimm3: case uimm3_1: case uimm4_1: 148 switch (isize) 149 { 150 case 1: 151 OP[i] = ((ins >> 4) & ((1 << op_size) -1)); break; 152 case 2: 153 OP[i] = ((ins >> (32 - start_bit)) & ((1 << op_size) -1));break; 154 default: /* for case 3. */ 155 OP[i] = ((ins >> (16 + start_bit)) & ((1 << op_size) -1)); break; 156 break; 157 } 158 break; 159 160 case uimm4: 161 switch (isize) 162 { 163 case 1: 164 if (start_bit == 20) 165 OP[i] = ((ins >> 4) & ((1 << op_size) -1)); 166 else 167 OP[i] = (ins & ((1 << op_size) -1)); 168 break; 169 case 2: 170 OP[i] = ((ins >> start_bit) & ((1 << op_size) -1)); 171 break; 172 case 3: 173 OP[i] = ((ins >> (start_bit + 16)) & ((1 << op_size) -1)); 174 break; 175 default: 176 OP[i] = ((ins >> start_bit) & ((1 << op_size) -1)); 177 break; 178 } 179 break; 180 181 case imm16: case uimm16: 182 OP[i] = ins & 0xFFFF; 183 break; 184 185 case uimm20: case imm20: 186 OP[i] = ins & (((long)1 << op_size) - 1); 187 break; 188 189 case imm32: case uimm32: 190 OP[i] = ins & 0xFFFFFFFF; 191 break; 192 193 case uimm5: break; /*NOT USED. */ 194 OP[i] = ins & ((1 << op_size) - 1); break; 195 196 case disps5: 197 OP[i] = (ins >> 4) & ((1 << 4) - 1); 198 OP[i] = (OP[i] * 2) + 2; 199 if (OP[i] & ((long)1 << 5)) 200 { 201 sign_flag = 1; 202 OP[i] = ~(OP[i]) + 1; 203 OP[i] = (unsigned long int)(OP[i] & 0x1F); 204 } 205 break; 206 207 case dispe9: 208 OP[i] = ((((ins >> 8) & 0xf) << 4) | (ins & 0xf)); 209 OP[i] <<= 1; 210 if (OP[i] & ((long)1 << 8)) 211 { 212 sign_flag = 1; 213 OP[i] = ~(OP[i]) + 1; 214 OP[i] = (unsigned long int)(OP[i] & 0xFF); 215 } 216 break; 217 218 case disps17: 219 OP[i] = (ins & 0xFFFF); 220 if (OP[i] & 1) 221 { 222 OP[i] = (OP[i] & 0xFFFE); 223 sign_flag = 1; 224 OP[i] = ~(OP[i]) + 1; 225 OP[i] = (unsigned long int)(OP[i] & 0xFFFF); 226 } 227 break; 228 229 case disps25: 230 if (isize == 2) 231 OP[i] = (ins & 0xFFFFFF); 232 else 233 OP[i] = (ins & 0xFFFF) | (((ins >> 24) & 0xf) << 16) | 234 (((ins >> 16) & 0xf) << 20); 235 236 if (OP[i] & 1) 237 { 238 OP[i] = (OP[i] & 0xFFFFFE); 239 sign_flag = 1; 240 OP[i] = ~(OP[i]) + 1; 241 OP[i] = (unsigned long int)(OP[i] & 0xFFFFFF); 242 } 243 break; 244 245 case abs20: 246 if (isize == 3) 247 OP[i] = (ins) & 0xFFFFF; 248 else 249 OP[i] = (ins >> start_bit) & 0xFFFFF; 250 break; 251 case abs24: 252 if (isize == 3) 253 OP[i] = ((ins & 0xFFFF) | (((ins >> 16) & 0xf) << 20) 254 | (((ins >> 24) & 0xf) << 16)); 255 else 256 OP[i] = (ins >> 16) & 0xFFFFFF; 257 break; 258 259 case rra: 260 case rbase: break; /* NOT USED. */ 261 case rbase_disps20: case rbase_dispe20: 262 case rpbase_disps20: case rpindex_disps20: 263 OP[i] = ((((ins >> 24)&0xf) << 16)|((ins) & 0xFFFF)); 264 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */ 265 break; 266 case rpbase_disps0: 267 OP[i] = 0; /* 4 bit disp const. */ 268 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */ 269 break; 270 case rpbase_dispe4: 271 OP[i] = ((ins >> 8) & 0xF) * 2; /* 4 bit disp const. */ 272 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */ 273 break; 274 case rpbase_disps4: 275 OP[i] = ((ins >> 8) & 0xF); /* 4 bit disp const. */ 276 OP[++i] = (ins) & 0xF; /* get 4 bit for reg. */ 277 break; 278 case rpbase_disps16: 279 OP[i] = (ins) & 0xFFFF; 280 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */ 281 break; 282 case rpindex_disps0: 283 OP[i] = 0; 284 OP[++i] = (ins >> 4) & 0xF; /* get 4 bit for reg. */ 285 OP[++i] = (ins >> 8) & 0x1; /* get 1 bit for index-reg. */ 286 break; 287 case rpindex_disps14: 288 OP[i] = (ins) & 0x3FFF; 289 OP[++i] = (ins >> 14) & 0x1; /* get 1 bit for index-reg. */ 290 OP[++i] = (ins >> 16) & 0xF; /* get 4 bit for reg. */ 291 break; 292 case rindex7_abs20: 293 case rindex8_abs20: 294 OP[i] = (ins) & 0xFFFFF; 295 OP[++i] = (ins >> 24) & 0x1; /* get 1 bit for index-reg. */ 296 OP[++i] = (ins >> 20) & 0xF; /* get 4 bit for reg. */ 297 break; 298 case regr: case regp: case pregr: case pregrp: 299 switch(isize) 300 { 301 case 1: 302 if (start_bit == 20) OP[i] = (ins >> 4) & 0xF; 303 else if (start_bit == 16) OP[i] = ins & 0xF; 304 break; 305 case 2: OP[i] = (ins >> start_bit) & 0xF; break; 306 case 3: OP[i] = (ins >> (start_bit + 16)) & 0xF; break; 307 } 308 break; 309 case cc: 310 { 311 if (isize == 1) OP[i] = (ins >> 4) & 0xF; 312 else if (isize == 2) OP[i] = (ins >> start_bit) & 0xF; 313 else OP[i] = (ins >> (start_bit + 16)) & 0xF; 314 break; 315 } 316 default: break; 317 } 318 319 /* For ESC on uimm4_1 operand. */ 320 if (op_type == uimm4_1) 321 if (OP[i] == 9) 322 OP[i] = -1; 323 324 /* For increment by 1. */ 325 if ((op_type == pregr) || (op_type == pregrp)) 326 OP[i] += 1; 327 } 328 /* FIXME: for tracing, update values that need to be updated each 329 instruction decode cycle */ 330 State.trace.psw = PSR; 331 } 332 333 static int 334 do_run (SIM_DESC sd, SIM_CPU *cpu, uint64_t mcode) 335 { 336 struct hash_entry *h; 337 338 #ifdef DEBUG 339 if ((cr16_debug & DEBUG_INSTRUCTION) != 0) 340 sim_io_printf (sd, "do_long 0x%" PRIx64 "\n", mcode); 341 #endif 342 343 h = lookup_hash (sd, cpu, mcode, 1); 344 345 if ((h == NULL) || (h->opcode == 0)) 346 return 0; 347 348 if (h->size == 3) 349 mcode = (mcode << 16) | RW (PC + 4); 350 351 /* Re-set OP list. */ 352 OP[0] = OP[1] = OP[2] = OP[3] = sign_flag = 0; 353 354 /* for push/pop/pushrtn with RA instructions. */ 355 if ((h->format & REG_LIST) && (mcode & 0x800000)) 356 OP[2] = 1; /* Set 1 for RA operand. */ 357 358 /* numops == 0 means, no operands. */ 359 if (((h->ops) != NULL) && (((h->ops)->numops) != 0)) 360 get_operands ((h->ops)->operands, mcode, h->size, (h->ops)->numops); 361 362 //State.ins_type = h->flags; 363 364 (h->ops->func) (sd, cpu); 365 366 return h->size; 367 } 368 369 static sim_cia 370 cr16_pc_get (sim_cpu *cpu) 371 { 372 return PC; 373 } 374 375 static void 376 cr16_pc_set (sim_cpu *cpu, sim_cia pc) 377 { 378 SIM_DESC sd = CPU_STATE (cpu); 379 SET_PC (pc); 380 } 381 382 static void 383 free_state (SIM_DESC sd) 384 { 385 if (STATE_MODULES (sd) != NULL) 386 sim_module_uninstall (sd); 387 sim_cpu_free_all (sd); 388 sim_state_free (sd); 389 } 390 391 static int cr16_reg_fetch (SIM_CPU *, int, void *, int); 392 static int cr16_reg_store (SIM_CPU *, int, const void *, int); 393 394 SIM_DESC 395 sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *cb, 396 struct bfd *abfd, char * const *argv) 397 { 398 struct simops *s; 399 struct hash_entry *h; 400 static int init_p = 0; 401 int i; 402 SIM_DESC sd = sim_state_alloc (kind, cb); 403 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 404 405 /* Set default options before parsing user options. */ 406 current_target_byte_order = BFD_ENDIAN_LITTLE; 407 cb->syscall_map = cb_cr16_syscall_map; 408 409 /* The cpu data is kept in a separately allocated chunk of memory. */ 410 if (sim_cpu_alloc_all (sd, 0) != SIM_RC_OK) 411 { 412 free_state (sd); 413 return 0; 414 } 415 416 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) 417 { 418 free_state (sd); 419 return 0; 420 } 421 422 /* The parser will print an error message for us, so we silently return. */ 423 if (sim_parse_args (sd, argv) != SIM_RC_OK) 424 { 425 free_state (sd); 426 return 0; 427 } 428 429 /* Check for/establish the a reference program image. */ 430 if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK) 431 { 432 free_state (sd); 433 return 0; 434 } 435 436 /* Configure/verify the target byte order and other runtime 437 configuration options. */ 438 if (sim_config (sd) != SIM_RC_OK) 439 { 440 sim_module_uninstall (sd); 441 return 0; 442 } 443 444 if (sim_post_argv_init (sd) != SIM_RC_OK) 445 { 446 /* Uninstall the modules to avoid memory leaks, 447 file descriptor leaks, etc. */ 448 sim_module_uninstall (sd); 449 return 0; 450 } 451 452 /* CPU specific initialization. */ 453 for (i = 0; i < MAX_NR_PROCESSORS; ++i) 454 { 455 SIM_CPU *cpu = STATE_CPU (sd, i); 456 457 CPU_REG_FETCH (cpu) = cr16_reg_fetch; 458 CPU_REG_STORE (cpu) = cr16_reg_store; 459 CPU_PC_FETCH (cpu) = cr16_pc_get; 460 CPU_PC_STORE (cpu) = cr16_pc_set; 461 } 462 463 /* The CR16 has an interrupt controller at 0xFC00, but we don't currently 464 handle that. Revisit if anyone ever implements operating mode. */ 465 /* cr16 memory: There are three separate cr16 memory regions IMEM, 466 UMEM and DMEM. The IMEM and DMEM are further broken down into 467 blocks (very like VM pages). This might not match the hardware, 468 but it matches what the toolchain currently expects. Ugh. */ 469 sim_do_commandf (sd, "memory-size %#x", 20 * 1024 * 1024); 470 471 /* put all the opcodes in the hash table. */ 472 if (!init_p++) 473 { 474 for (s = Simops; s->func; s++) 475 { 476 switch(32 - s->mask) 477 { 478 case 0x4: 479 h = &hash_table[hash(s->opcode, 0)]; 480 break; 481 482 case 0x7: 483 if (((s->opcode << 1) >> 4) != 0) 484 h = &hash_table[hash((s->opcode << 1) >> 4, 0)]; 485 else 486 h = &hash_table[hash((s->opcode << 1), 0)]; 487 break; 488 489 case 0x8: 490 if ((s->opcode >> 4) != 0) 491 h = &hash_table[hash(s->opcode >> 4, 0)]; 492 else 493 h = &hash_table[hash(s->opcode, 0)]; 494 break; 495 496 case 0x9: 497 if (((s->opcode >> 1) >> 4) != 0) 498 h = &hash_table[hash((s->opcode >>1) >> 4, 0)]; 499 else 500 h = &hash_table[hash((s->opcode >> 1), 0)]; 501 break; 502 503 case 0xa: 504 if ((s->opcode >> 8) != 0) 505 h = &hash_table[hash(s->opcode >> 8, 0)]; 506 else if ((s->opcode >> 4) != 0) 507 h = &hash_table[hash(s->opcode >> 4, 0)]; 508 else 509 h = &hash_table[hash(s->opcode, 0)]; 510 break; 511 512 case 0xc: 513 if ((s->opcode >> 8) != 0) 514 h = &hash_table[hash(s->opcode >> 8, 0)]; 515 else if ((s->opcode >> 4) != 0) 516 h = &hash_table[hash(s->opcode >> 4, 0)]; 517 else 518 h = &hash_table[hash(s->opcode, 0)]; 519 break; 520 521 case 0xd: 522 if (((s->opcode >> 1) >> 8) != 0) 523 h = &hash_table[hash((s->opcode >>1) >> 8, 0)]; 524 else if (((s->opcode >> 1) >> 4) != 0) 525 h = &hash_table[hash((s->opcode >>1) >> 4, 0)]; 526 else 527 h = &hash_table[hash((s->opcode >>1), 0)]; 528 break; 529 530 case 0x10: 531 if ((s->opcode >> 0xc) != 0) 532 h = &hash_table[hash(s->opcode >> 12, 0)]; 533 else if ((s->opcode >> 8) != 0) 534 h = &hash_table[hash(s->opcode >> 8, 0)]; 535 else if ((s->opcode >> 4) != 0) 536 h = &hash_table[hash(s->opcode >> 4, 0)]; 537 else 538 h = &hash_table[hash(s->opcode, 0)]; 539 break; 540 541 case 0x14: 542 if ((s->opcode >> 16) != 0) 543 h = &hash_table[hash(s->opcode >> 16, 0)]; 544 else if ((s->opcode >> 12) != 0) 545 h = &hash_table[hash(s->opcode >> 12, 0)]; 546 else if ((s->opcode >> 8) != 0) 547 h = &hash_table[hash(s->opcode >> 8, 0)]; 548 else if ((s->opcode >> 4) != 0) 549 h = &hash_table[hash(s->opcode >> 4, 0)]; 550 else 551 h = &hash_table[hash(s->opcode, 0)]; 552 break; 553 554 default: 555 continue; 556 } 557 558 /* go to the last entry in the chain. */ 559 while (h->next) 560 h = h->next; 561 562 if (h->ops) 563 { 564 h->next = (struct hash_entry *) calloc(1,sizeof(struct hash_entry)); 565 if (!h->next) 566 perror ("malloc failure"); 567 568 h = h->next; 569 } 570 h->ops = s; 571 h->mask = s->mask; 572 h->opcode = s->opcode; 573 h->format = s->format; 574 h->size = s->size; 575 } 576 } 577 578 return sd; 579 } 580 581 static void 582 step_once (SIM_DESC sd, SIM_CPU *cpu) 583 { 584 uint32_t curr_ins_size = 0; 585 uint64_t mcode = RLW (PC); 586 587 State.pc_changed = 0; 588 589 curr_ins_size = do_run (sd, cpu, mcode); 590 591 #if CR16_DEBUG 592 sim_io_printf (sd, "INS: PC=0x%X, mcode=0x%X\n", PC, mcode); 593 #endif 594 595 if (curr_ins_size == 0) 596 sim_engine_halt (sd, cpu, NULL, PC, sim_exited, GPR (2)); 597 else if (!State.pc_changed) 598 SET_PC (PC + (curr_ins_size * 2)); /* For word instructions. */ 599 600 #if 0 601 /* Check for a breakpoint trap on this instruction. This 602 overrides any pending branches or loops */ 603 if (PSR_DB && PC == DBS) 604 { 605 SET_BPC (PC); 606 SET_BPSR (PSR); 607 SET_PC (SDBT_VECTOR_START); 608 } 609 #endif 610 611 /* Writeback all the DATA / PC changes */ 612 SLOT_FLUSH (); 613 } 614 615 void 616 sim_engine_run (SIM_DESC sd, 617 int next_cpu_nr, /* ignore */ 618 int nr_cpus, /* ignore */ 619 int siggnal) 620 { 621 sim_cpu *cpu; 622 623 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 624 625 cpu = STATE_CPU (sd, 0); 626 627 switch (siggnal) 628 { 629 case 0: 630 break; 631 case GDB_SIGNAL_BUS: 632 case GDB_SIGNAL_SEGV: 633 SET_PC (PC); 634 SET_PSR (PSR); 635 JMP (AE_VECTOR_START); 636 SLOT_FLUSH (); 637 break; 638 case GDB_SIGNAL_ILL: 639 SET_PC (PC); 640 SET_PSR (PSR); 641 SET_HW_PSR ((PSR & (PSR_C_BIT))); 642 JMP (RIE_VECTOR_START); 643 SLOT_FLUSH (); 644 break; 645 default: 646 /* just ignore it */ 647 break; 648 } 649 650 while (1) 651 { 652 step_once (sd, cpu); 653 if (sim_events_tick (sd)) 654 sim_events_process (sd); 655 } 656 } 657 658 SIM_RC 659 sim_create_inferior (SIM_DESC sd, struct bfd *abfd, 660 char * const *argv, char * const *env) 661 { 662 bfd_vma start_address; 663 664 /* reset all state information */ 665 memset (&State, 0, sizeof (State)); 666 667 /* There was a hack here to copy the values of argc and argv into r0 668 and r1. The values were also saved into some high memory that 669 won't be overwritten by the stack (0x7C00). The reason for doing 670 this was to allow the 'run' program to accept arguments. Without 671 the hack, this is not possible anymore. If the simulator is run 672 from the debugger, arguments cannot be passed in, so this makes 673 no difference. */ 674 675 /* set PC */ 676 if (abfd != NULL) 677 start_address = bfd_get_start_address (abfd); 678 else 679 start_address = 0x0; 680 #ifdef DEBUG 681 if (cr16_debug) 682 sim_io_printf (sd, "sim_create_inferior: PC=0x%" PRIx64 "\n", 683 (uint64_t) start_address); 684 #endif 685 { 686 SIM_CPU *cpu = STATE_CPU (sd, 0); 687 SET_CREG (PC_CR, start_address); 688 } 689 690 SLOT_FLUSH (); 691 return SIM_RC_OK; 692 } 693 694 static uint32_t 695 cr16_extract_unsigned_integer (const unsigned char *addr, int len) 696 { 697 uint32_t retval; 698 unsigned char * p; 699 unsigned char * startaddr = (unsigned char *)addr; 700 unsigned char * endaddr = startaddr + len; 701 702 retval = 0; 703 704 for (p = endaddr; p > startaddr;) 705 retval = (retval << 8) | *--p; 706 707 return retval; 708 } 709 710 static void 711 cr16_store_unsigned_integer (unsigned char *addr, int len, uint32_t val) 712 { 713 unsigned char *p; 714 unsigned char *startaddr = addr; 715 unsigned char *endaddr = startaddr + len; 716 717 for (p = startaddr; p < endaddr;) 718 { 719 *p++ = val & 0xff; 720 val >>= 8; 721 } 722 } 723 724 static int 725 cr16_reg_fetch (SIM_CPU *cpu, int rn, void *memory, int length) 726 { 727 int size; 728 switch ((enum sim_cr16_regs) rn) 729 { 730 case SIM_CR16_R0_REGNUM: 731 case SIM_CR16_R1_REGNUM: 732 case SIM_CR16_R2_REGNUM: 733 case SIM_CR16_R3_REGNUM: 734 case SIM_CR16_R4_REGNUM: 735 case SIM_CR16_R5_REGNUM: 736 case SIM_CR16_R6_REGNUM: 737 case SIM_CR16_R7_REGNUM: 738 case SIM_CR16_R8_REGNUM: 739 case SIM_CR16_R9_REGNUM: 740 case SIM_CR16_R10_REGNUM: 741 case SIM_CR16_R11_REGNUM: 742 cr16_store_unsigned_integer (memory, 2, GPR (rn - SIM_CR16_R0_REGNUM)); 743 size = 2; 744 break; 745 case SIM_CR16_R12_REGNUM: 746 case SIM_CR16_R13_REGNUM: 747 case SIM_CR16_R14_REGNUM: 748 case SIM_CR16_R15_REGNUM: 749 cr16_store_unsigned_integer (memory, 4, GPR (rn - SIM_CR16_R0_REGNUM)); 750 size = 4; 751 break; 752 case SIM_CR16_PC_REGNUM: 753 case SIM_CR16_ISP_REGNUM: 754 case SIM_CR16_USP_REGNUM: 755 case SIM_CR16_INTBASE_REGNUM: 756 case SIM_CR16_PSR_REGNUM: 757 case SIM_CR16_CFG_REGNUM: 758 case SIM_CR16_DBS_REGNUM: 759 case SIM_CR16_DCR_REGNUM: 760 case SIM_CR16_DSR_REGNUM: 761 case SIM_CR16_CAR0_REGNUM: 762 case SIM_CR16_CAR1_REGNUM: 763 cr16_store_unsigned_integer (memory, 4, CREG (rn - SIM_CR16_PC_REGNUM)); 764 size = 4; 765 break; 766 default: 767 size = 0; 768 break; 769 } 770 return size; 771 } 772 773 static int 774 cr16_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length) 775 { 776 SIM_DESC sd = CPU_STATE (cpu); 777 int size; 778 switch ((enum sim_cr16_regs) rn) 779 { 780 case SIM_CR16_R0_REGNUM: 781 case SIM_CR16_R1_REGNUM: 782 case SIM_CR16_R2_REGNUM: 783 case SIM_CR16_R3_REGNUM: 784 case SIM_CR16_R4_REGNUM: 785 case SIM_CR16_R5_REGNUM: 786 case SIM_CR16_R6_REGNUM: 787 case SIM_CR16_R7_REGNUM: 788 case SIM_CR16_R8_REGNUM: 789 case SIM_CR16_R9_REGNUM: 790 case SIM_CR16_R10_REGNUM: 791 case SIM_CR16_R11_REGNUM: 792 SET_GPR (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2)); 793 size = 2; 794 break; 795 case SIM_CR16_R12_REGNUM: 796 case SIM_CR16_R13_REGNUM: 797 case SIM_CR16_R14_REGNUM: 798 case SIM_CR16_R15_REGNUM: 799 SET_GPR32 (rn - SIM_CR16_R0_REGNUM, cr16_extract_unsigned_integer (memory, 2)); 800 size = 4; 801 break; 802 case SIM_CR16_PC_REGNUM: 803 case SIM_CR16_ISP_REGNUM: 804 case SIM_CR16_USP_REGNUM: 805 case SIM_CR16_INTBASE_REGNUM: 806 case SIM_CR16_PSR_REGNUM: 807 case SIM_CR16_CFG_REGNUM: 808 case SIM_CR16_DBS_REGNUM: 809 case SIM_CR16_DCR_REGNUM: 810 case SIM_CR16_DSR_REGNUM: 811 case SIM_CR16_CAR0_REGNUM: 812 case SIM_CR16_CAR1_REGNUM: 813 SET_CREG (rn - SIM_CR16_PC_REGNUM, cr16_extract_unsigned_integer (memory, 4)); 814 size = 4; 815 break; 816 default: 817 size = 0; 818 break; 819 } 820 SLOT_FLUSH (); 821 return size; 822 } 823