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