1 /* Simulator for TI MSP430 and MSP430X 2 3 Copyright (C) 2013-2023 Free Software Foundation, Inc. 4 Contributed by Red Hat. 5 Based on sim/bfin/bfin-sim.c which was contributed by Analog Devices, Inc. 6 7 This file is part of simulators. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22 /* This must come before any other includes. */ 23 #include "defs.h" 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <inttypes.h> 29 #include <unistd.h> 30 #include <assert.h> 31 #include "opcode/msp430-decode.h" 32 #include "sim-main.h" 33 #include "sim-signal.h" 34 #include "sim-syscall.h" 35 36 static sim_cia 37 msp430_pc_fetch (SIM_CPU *cpu) 38 { 39 return cpu->state.regs[0]; 40 } 41 42 static void 43 msp430_pc_store (SIM_CPU *cpu, sim_cia newpc) 44 { 45 cpu->state.regs[0] = newpc; 46 } 47 48 static int 49 msp430_reg_fetch (SIM_CPU *cpu, int regno, void *buf, int len) 50 { 51 unsigned char *memory = buf; 52 53 if (0 <= regno && regno < 16) 54 { 55 if (len == 2) 56 { 57 int val = cpu->state.regs[regno]; 58 memory[0] = val & 0xff; 59 memory[1] = (val >> 8) & 0xff; 60 return 0; 61 } 62 else if (len == 4) 63 { 64 int val = cpu->state.regs[regno]; 65 memory[0] = val & 0xff; 66 memory[1] = (val >> 8) & 0xff; 67 memory[2] = (val >> 16) & 0x0f; /* Registers are only 20 bits wide. */ 68 memory[3] = 0; 69 return 0; 70 } 71 else 72 return -1; 73 } 74 else 75 return -1; 76 } 77 78 static int 79 msp430_reg_store (SIM_CPU *cpu, int regno, const void *buf, int len) 80 { 81 const unsigned char *memory = buf; 82 83 if (0 <= regno && regno < 16) 84 { 85 if (len == 2) 86 { 87 cpu->state.regs[regno] = (memory[1] << 8) | memory[0]; 88 return len; 89 } 90 91 if (len == 4) 92 { 93 cpu->state.regs[regno] = ((memory[2] << 16) & 0xf0000) 94 | (memory[1] << 8) | memory[0]; 95 return len; 96 } 97 } 98 99 return -1; 100 } 101 102 static inline void 103 msp430_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu) 104 { 105 memset (&cpu->state, 0, sizeof (cpu->state)); 106 } 107 108 SIM_DESC 109 sim_open (SIM_OPEN_KIND kind, 110 struct host_callback_struct *callback, 111 struct bfd *abfd, 112 char * const *argv) 113 { 114 SIM_DESC sd = sim_state_alloc (kind, callback); 115 char c; 116 117 /* Initialise the simulator. */ 118 119 /* Set default options before parsing user options. */ 120 current_target_byte_order = BFD_ENDIAN_LITTLE; 121 122 if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK) 123 { 124 sim_state_free (sd); 125 return 0; 126 } 127 128 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) 129 { 130 sim_state_free (sd); 131 return 0; 132 } 133 134 if (sim_parse_args (sd, argv) != SIM_RC_OK) 135 { 136 sim_state_free (sd); 137 return 0; 138 } 139 140 CPU_PC_FETCH (MSP430_CPU (sd)) = msp430_pc_fetch; 141 CPU_PC_STORE (MSP430_CPU (sd)) = msp430_pc_store; 142 CPU_REG_FETCH (MSP430_CPU (sd)) = msp430_reg_fetch; 143 CPU_REG_STORE (MSP430_CPU (sd)) = msp430_reg_store; 144 145 /* Allocate memory if none specified by user. 146 Note - these values match the memory regions in the libgloss/msp430/msp430[xl]-sim.ld scripts. */ 147 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x2, 1) == 0) 148 sim_do_commandf (sd, "memory-region 0,0x20"); /* Needed by the GDB testsuite. */ 149 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x500, 1) == 0) 150 sim_do_commandf (sd, "memory-region 0x500,0xfac0"); /* RAM and/or ROM */ 151 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0xfffe, 1) == 0) 152 sim_do_commandf (sd, "memory-region 0xffc0,0x40"); /* VECTORS. */ 153 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x10000, 1) == 0) 154 sim_do_commandf (sd, "memory-region 0x10000,0x80000"); /* HIGH FLASH RAM. */ 155 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x90000, 1) == 0) 156 sim_do_commandf (sd, "memory-region 0x90000,0x70000"); /* HIGH ROM. */ 157 158 /* Check for/establish the a reference program image. */ 159 if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK) 160 { 161 sim_state_free (sd); 162 return 0; 163 } 164 165 /* Establish any remaining configuration options. */ 166 if (sim_config (sd) != SIM_RC_OK) 167 { 168 sim_state_free (sd); 169 return 0; 170 } 171 172 if (sim_post_argv_init (sd) != SIM_RC_OK) 173 { 174 sim_state_free (sd); 175 return 0; 176 } 177 178 /* CPU specific initialization. */ 179 assert (MAX_NR_PROCESSORS == 1); 180 msp430_initialize_cpu (sd, MSP430_CPU (sd)); 181 182 MSP430_CPU (sd)->state.cio_breakpoint = trace_sym_value (sd, "C$$IO$$"); 183 MSP430_CPU (sd)->state.cio_buffer = trace_sym_value (sd, "__CIOBUF__"); 184 if (MSP430_CPU (sd)->state.cio_buffer == -1) 185 MSP430_CPU (sd)->state.cio_buffer = trace_sym_value (sd, "_CIOBUF_"); 186 187 return sd; 188 } 189 190 SIM_RC 191 sim_create_inferior (SIM_DESC sd, 192 struct bfd *abfd, 193 char * const *argv, 194 char * const *env) 195 { 196 unsigned char resetv[2]; 197 int c; 198 int new_pc; 199 200 /* Set the PC to the default reset vector if available. */ 201 c = sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, resetv, 0xfffe, 2); 202 new_pc = resetv[0] + 256 * resetv[1]; 203 204 /* If the reset vector isn't initialized, then use the ELF entry. */ 205 if (abfd != NULL && !new_pc) 206 new_pc = bfd_get_start_address (abfd); 207 208 sim_pc_set (MSP430_CPU (sd), new_pc); 209 msp430_pc_store (MSP430_CPU (sd), new_pc); 210 211 return SIM_RC_OK; 212 } 213 214 typedef struct 215 { 216 SIM_DESC sd; 217 int gb_addr; 218 } Get_Byte_Local_Data; 219 220 static int 221 msp430_getbyte (void *vld) 222 { 223 Get_Byte_Local_Data *ld = (Get_Byte_Local_Data *)vld; 224 char buf[1]; 225 SIM_DESC sd = ld->sd; 226 227 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, ld->gb_addr, 1); 228 ld->gb_addr ++; 229 return buf[0]; 230 } 231 232 #define REG(N) MSP430_CPU (sd)->state.regs[(N)] 233 #define PC REG(MSR_PC) 234 #define SP REG(MSR_SP) 235 #define SR REG(MSR_SR) 236 237 static const char * 238 register_names[] = 239 { 240 "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8", 241 "R9", "R10", "R11", "R12", "R13", "R14", "R15" 242 }; 243 244 static void 245 trace_reg_put (SIM_DESC sd, int n, unsigned int v) 246 { 247 TRACE_REGISTER (MSP430_CPU (sd), "PUT: %#x -> %s", v, register_names[n]); 248 REG (n) = v; 249 } 250 251 static unsigned int 252 trace_reg_get (SIM_DESC sd, int n) 253 { 254 TRACE_REGISTER (MSP430_CPU (sd), "GET: %s -> %#x", register_names[n], REG (n)); 255 return REG (n); 256 } 257 258 #define REG_PUT(N,V) trace_reg_put (sd, N, V) 259 #define REG_GET(N) trace_reg_get (sd, N) 260 261 /* Hardware multiply (and accumulate) support. */ 262 263 static unsigned int 264 zero_ext (unsigned int v, unsigned int bits) 265 { 266 v &= ((1 << bits) - 1); 267 return v; 268 } 269 270 static signed long long 271 sign_ext (signed long long v, unsigned int bits) 272 { 273 signed long long sb = 1LL << (bits-1); /* Sign bit. */ 274 signed long long mb = (1LL << (bits-1)) - 1LL; /* Mantissa bits. */ 275 276 if (v & sb) 277 v = v | ~mb; 278 else 279 v = v & mb; 280 return v; 281 } 282 283 static int 284 get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n) 285 { 286 MSP430_Opcode_Operand *op = opc->op + n; 287 int rv = 0; 288 int addr; 289 unsigned char buf[4]; 290 int incval = 0; 291 292 switch (op->type) 293 { 294 case MSP430_Operand_Immediate: 295 rv = op->addend; 296 break; 297 case MSP430_Operand_Register: 298 rv = REG_GET (op->reg); 299 break; 300 case MSP430_Operand_Indirect: 301 case MSP430_Operand_Indirect_Postinc: 302 addr = op->addend; 303 if (op->reg != MSR_None) 304 { 305 int reg = REG_GET (op->reg); 306 int sign = opc->ofs_430x ? 20 : 16; 307 308 /* Index values are signed. */ 309 if (addr & (1 << (sign - 1))) 310 addr |= -(1 << sign); 311 312 addr += reg; 313 314 /* For MSP430 instructions the sum is limited to 16 bits if the 315 address in the index register is less than 64k even if we are 316 running on an MSP430X CPU. This is for MSP430 compatibility. */ 317 if (reg < 0x10000 && ! opc->ofs_430x) 318 { 319 if (addr >= 0x10000) 320 fprintf (stderr, " XXX WRAPPING ADDRESS %x on read\n", addr); 321 322 addr &= 0xffff; 323 } 324 } 325 addr &= 0xfffff; 326 switch (opc->size) 327 { 328 case 8: 329 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 1); 330 rv = buf[0]; 331 break; 332 case 16: 333 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 2); 334 rv = buf[0] | (buf[1] << 8); 335 break; 336 case 20: 337 case 32: 338 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 4); 339 rv = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); 340 break; 341 default: 342 assert (! opc->size); 343 break; 344 } 345 #if 0 346 /* Hack - MSP430X5438 serial port status register. */ 347 if (addr == 0x5dd) 348 rv = 2; 349 #endif 350 if ((addr >= 0x130 && addr <= 0x15B) 351 || (addr >= 0x4C0 && addr <= 0x4EB)) 352 { 353 switch (addr) 354 { 355 case 0x4CA: 356 case 0x13A: 357 switch (HWMULT (sd, hwmult_type)) 358 { 359 case UNSIGN_MAC_32: 360 case UNSIGN_32: 361 rv = zero_ext (HWMULT (sd, hwmult_result), 16); 362 break; 363 case SIGN_MAC_32: 364 case SIGN_32: 365 rv = sign_ext (HWMULT (sd, hwmult_signed_result), 16); 366 break; 367 } 368 break; 369 370 case 0x4CC: 371 case 0x13C: 372 switch (HWMULT (sd, hwmult_type)) 373 { 374 case UNSIGN_MAC_32: 375 case UNSIGN_32: 376 rv = zero_ext (HWMULT (sd, hwmult_result) >> 16, 16); 377 break; 378 379 case SIGN_MAC_32: 380 case SIGN_32: 381 rv = sign_ext (HWMULT (sd, hwmult_signed_result) >> 16, 16); 382 break; 383 } 384 break; 385 386 case 0x4CE: 387 case 0x13E: 388 switch (HWMULT (sd, hwmult_type)) 389 { 390 case UNSIGN_32: 391 rv = 0; 392 break; 393 case SIGN_32: 394 rv = HWMULT (sd, hwmult_signed_result) < 0 ? -1 : 0; 395 break; 396 case UNSIGN_MAC_32: 397 rv = 0; /* FIXME: Should be carry of last accumulate. */ 398 break; 399 case SIGN_MAC_32: 400 rv = HWMULT (sd, hwmult_signed_accumulator) < 0 ? -1 : 0; 401 break; 402 } 403 break; 404 405 case 0x4E4: 406 case 0x154: 407 rv = zero_ext (HWMULT (sd, hw32mult_result), 16); 408 break; 409 410 case 0x4E6: 411 case 0x156: 412 rv = zero_ext (HWMULT (sd, hw32mult_result) >> 16, 16); 413 break; 414 415 case 0x4E8: 416 case 0x158: 417 rv = zero_ext (HWMULT (sd, hw32mult_result) >> 32, 16); 418 break; 419 420 case 0x4EA: 421 case 0x15A: 422 switch (HWMULT (sd, hw32mult_type)) 423 { 424 case UNSIGN_64: rv = zero_ext (HWMULT (sd, hw32mult_result) >> 48, 16); break; 425 case SIGN_64: rv = sign_ext (HWMULT (sd, hw32mult_result) >> 48, 16); break; 426 } 427 break; 428 429 default: 430 fprintf (stderr, "unimplemented HW MULT read from %x!\n", addr); 431 break; 432 } 433 } 434 435 TRACE_MEMORY (MSP430_CPU (sd), "GET: [%#x].%d -> %#x", addr, opc->size, 436 rv); 437 break; 438 439 default: 440 fprintf (stderr, "invalid operand %d type %d\n", n, op->type); 441 abort (); 442 } 443 444 switch (opc->size) 445 { 446 case 8: 447 rv &= 0xff; 448 incval = 1; 449 break; 450 case 16: 451 rv &= 0xffff; 452 incval = 2; 453 break; 454 case 20: 455 rv &= 0xfffff; 456 incval = 4; 457 break; 458 case 32: 459 rv &= 0xffffffff; 460 incval = 4; 461 break; 462 } 463 464 if (op->type == MSP430_Operand_Indirect_Postinc) 465 REG_PUT (op->reg, REG_GET (op->reg) + incval); 466 467 return rv; 468 } 469 470 static int 471 put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val) 472 { 473 MSP430_Opcode_Operand *op = opc->op + n; 474 int rv = 0; 475 int addr; 476 unsigned char buf[4]; 477 int incval = 0; 478 479 switch (opc->size) 480 { 481 case 8: 482 val &= 0xff; 483 break; 484 case 16: 485 val &= 0xffff; 486 break; 487 case 20: 488 val &= 0xfffff; 489 break; 490 case 32: 491 val &= 0xffffffff; 492 break; 493 } 494 495 switch (op->type) 496 { 497 case MSP430_Operand_Register: 498 REG (op->reg) = val; 499 REG_PUT (op->reg, val); 500 break; 501 case MSP430_Operand_Indirect: 502 case MSP430_Operand_Indirect_Postinc: 503 addr = op->addend; 504 if (op->reg != MSR_None) 505 { 506 int reg = REG_GET (op->reg); 507 int sign = opc->ofs_430x ? 20 : 16; 508 509 /* Index values are signed. */ 510 if (addr & (1 << (sign - 1))) 511 addr |= -(1 << sign); 512 513 addr += reg; 514 515 /* For MSP430 instructions the sum is limited to 16 bits if the 516 address in the index register is less than 64k even if we are 517 running on an MSP430X CPU. This is for MSP430 compatibility. */ 518 if (reg < 0x10000 && ! opc->ofs_430x) 519 { 520 if (addr >= 0x10000) 521 fprintf (stderr, " XXX WRAPPING ADDRESS %x on write\n", addr); 522 523 addr &= 0xffff; 524 } 525 } 526 addr &= 0xfffff; 527 528 TRACE_MEMORY (MSP430_CPU (sd), "PUT: [%#x].%d <- %#x", addr, opc->size, 529 val); 530 #if 0 531 /* Hack - MSP430X5438 serial port transmit register. */ 532 if (addr == 0x5ce) 533 putchar (val); 534 #endif 535 if ((addr >= 0x130 && addr <= 0x15B) 536 || (addr >= 0x4C0 && addr <= 0x4EB)) 537 { 538 signed int a,b; 539 540 /* Hardware Multiply emulation. */ 541 assert (opc->size == 16); 542 543 switch (addr) 544 { 545 case 0x4C0: 546 case 0x130: 547 HWMULT (sd, hwmult_op1) = val; 548 HWMULT (sd, hwmult_type) = UNSIGN_32; 549 break; 550 551 case 0x4C2: 552 case 0x132: 553 HWMULT (sd, hwmult_op1) = val; 554 HWMULT (sd, hwmult_type) = SIGN_32; 555 break; 556 557 case 0x4C4: 558 case 0x134: 559 HWMULT (sd, hwmult_op1) = val; 560 HWMULT (sd, hwmult_type) = UNSIGN_MAC_32; 561 break; 562 563 case 0x4C6: 564 case 0x136: 565 HWMULT (sd, hwmult_op1) = val; 566 HWMULT (sd, hwmult_type) = SIGN_MAC_32; 567 break; 568 569 case 0x4C8: 570 case 0x138: 571 HWMULT (sd, hwmult_op2) = val; 572 switch (HWMULT (sd, hwmult_type)) 573 { 574 case UNSIGN_32: 575 a = HWMULT (sd, hwmult_op1); 576 b = HWMULT (sd, hwmult_op2); 577 /* For unsigned 32-bit multiplication of 16-bit operands, an 578 explicit cast is required to prevent any implicit 579 sign-extension. */ 580 HWMULT (sd, hwmult_result) = (uint32_t) a * (uint32_t) b; 581 HWMULT (sd, hwmult_signed_result) = a * b; 582 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_signed_accumulator) = 0; 583 break; 584 585 case SIGN_32: 586 a = sign_ext (HWMULT (sd, hwmult_op1), 16); 587 b = sign_ext (HWMULT (sd, hwmult_op2), 16); 588 HWMULT (sd, hwmult_signed_result) = a * b; 589 HWMULT (sd, hwmult_result) = (uint32_t) a * (uint32_t) b; 590 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_signed_accumulator) = 0; 591 break; 592 593 case UNSIGN_MAC_32: 594 a = HWMULT (sd, hwmult_op1); 595 b = HWMULT (sd, hwmult_op2); 596 HWMULT (sd, hwmult_accumulator) 597 += (uint32_t) a * (uint32_t) b; 598 HWMULT (sd, hwmult_signed_accumulator) += a * b; 599 HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_accumulator); 600 HWMULT (sd, hwmult_signed_result) = HWMULT (sd, hwmult_signed_accumulator); 601 break; 602 603 case SIGN_MAC_32: 604 a = sign_ext (HWMULT (sd, hwmult_op1), 16); 605 b = sign_ext (HWMULT (sd, hwmult_op2), 16); 606 HWMULT (sd, hwmult_accumulator) 607 += (uint32_t) a * (uint32_t) b; 608 HWMULT (sd, hwmult_signed_accumulator) += a * b; 609 HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_accumulator); 610 HWMULT (sd, hwmult_signed_result) = HWMULT (sd, hwmult_signed_accumulator); 611 break; 612 } 613 break; 614 615 case 0x4CA: 616 case 0x13A: 617 /* Copy into LOW result... */ 618 switch (HWMULT (sd, hwmult_type)) 619 { 620 case UNSIGN_MAC_32: 621 case UNSIGN_32: 622 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_result) = zero_ext (val, 16); 623 HWMULT (sd, hwmult_signed_accumulator) = sign_ext (val, 16); 624 break; 625 case SIGN_MAC_32: 626 case SIGN_32: 627 HWMULT (sd, hwmult_signed_accumulator) = HWMULT (sd, hwmult_result) = sign_ext (val, 16); 628 HWMULT (sd, hwmult_accumulator) = zero_ext (val, 16); 629 break; 630 } 631 break; 632 633 case 0x4D0: 634 case 0x140: 635 HWMULT (sd, hw32mult_op1) = val; 636 HWMULT (sd, hw32mult_type) = UNSIGN_64; 637 break; 638 639 case 0x4D2: 640 case 0x142: 641 HWMULT (sd, hw32mult_op1) = (HWMULT (sd, hw32mult_op1) & 0xFFFF) | (val << 16); 642 break; 643 644 case 0x4D4: 645 case 0x144: 646 HWMULT (sd, hw32mult_op1) = val; 647 HWMULT (sd, hw32mult_type) = SIGN_64; 648 break; 649 650 case 0x4D6: 651 case 0x146: 652 HWMULT (sd, hw32mult_op1) = (HWMULT (sd, hw32mult_op1) & 0xFFFF) | (val << 16); 653 break; 654 655 case 0x4E0: 656 case 0x150: 657 HWMULT (sd, hw32mult_op2) = val; 658 break; 659 660 case 0x4E2: 661 case 0x152: 662 HWMULT (sd, hw32mult_op2) = (HWMULT (sd, hw32mult_op2) & 0xFFFF) | (val << 16); 663 switch (HWMULT (sd, hw32mult_type)) 664 { 665 case UNSIGN_64: 666 HWMULT (sd, hw32mult_result) 667 = (uint64_t) HWMULT (sd, hw32mult_op1) 668 * (uint64_t) HWMULT (sd, hw32mult_op2); 669 break; 670 case SIGN_64: 671 HWMULT (sd, hw32mult_result) 672 = sign_ext (HWMULT (sd, hw32mult_op1), 32) 673 * sign_ext (HWMULT (sd, hw32mult_op2), 32); 674 break; 675 } 676 break; 677 678 default: 679 fprintf (stderr, "unimplemented HW MULT write to %x!\n", addr); 680 break; 681 } 682 } 683 684 switch (opc->size) 685 { 686 case 8: 687 buf[0] = val; 688 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 1); 689 break; 690 case 16: 691 buf[0] = val; 692 buf[1] = val >> 8; 693 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 2); 694 break; 695 case 20: 696 case 32: 697 buf[0] = val; 698 buf[1] = val >> 8; 699 buf[2] = val >> 16; 700 buf[3] = val >> 24; 701 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 4); 702 break; 703 default: 704 assert (! opc->size); 705 break; 706 } 707 break; 708 default: 709 fprintf (stderr, "invalid operand %d type %d\n", n, op->type); 710 abort (); 711 } 712 713 switch (opc->size) 714 { 715 case 8: 716 rv &= 0xff; 717 incval = 1; 718 break; 719 case 16: 720 rv &= 0xffff; 721 incval = 2; 722 break; 723 case 20: 724 rv &= 0xfffff; 725 incval = 4; 726 break; 727 case 32: 728 rv &= 0xffffffff; 729 incval = 4; 730 break; 731 } 732 733 if (op->type == MSP430_Operand_Indirect_Postinc) 734 { 735 int new_val = REG_GET (op->reg) + incval; 736 /* SP is always word-aligned. */ 737 if (op->reg == MSR_SP && (new_val & 1)) 738 new_val ++; 739 REG_PUT (op->reg, new_val); 740 } 741 742 return rv; 743 } 744 745 static void 746 mem_put_val (SIM_DESC sd, int addr, int val, int bits) 747 { 748 MSP430_Opcode_Decoded opc; 749 750 opc.size = bits; 751 opc.op[0].type = MSP430_Operand_Indirect; 752 opc.op[0].addend = addr; 753 opc.op[0].reg = MSR_None; 754 put_op (sd, &opc, 0, val); 755 } 756 757 static int 758 mem_get_val (SIM_DESC sd, int addr, int bits) 759 { 760 MSP430_Opcode_Decoded opc; 761 762 opc.size = bits; 763 opc.op[0].type = MSP430_Operand_Indirect; 764 opc.op[0].addend = addr; 765 opc.op[0].reg = MSR_None; 766 return get_op (sd, &opc, 0); 767 } 768 769 #define CIO_OPEN (0xF0) 770 #define CIO_CLOSE (0xF1) 771 #define CIO_READ (0xF2) 772 #define CIO_WRITE (0xF3) 773 #define CIO_LSEEK (0xF4) 774 #define CIO_UNLINK (0xF5) 775 #define CIO_GETENV (0xF6) 776 #define CIO_RENAME (0xF7) 777 #define CIO_GETTIME (0xF8) 778 #define CIO_GETCLK (0xF9) 779 #define CIO_SYNC (0xFF) 780 781 #define CIO_I(n) (parms[(n)] + parms[(n)+1] * 256) 782 #define CIO_L(n) (parms[(n)] + parms[(n)+1] * 256 \ 783 + parms[(n)+2] * 65536 + parms[(n)+3] * 16777216) 784 785 static void 786 msp430_cio (SIM_DESC sd) 787 { 788 /* A block of data at __CIOBUF__ describes the I/O operation to 789 perform. */ 790 791 unsigned char raw_parms[13]; 792 unsigned char parms[8]; 793 long length; 794 int command; 795 unsigned char buffer[512]; 796 long ret_buflen = 0; 797 long fd, addr, len, rv; 798 799 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, parms, 800 MSP430_CPU (sd)->state.cio_buffer, 5); 801 length = CIO_I (0); 802 command = parms[2]; 803 804 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, parms, 805 MSP430_CPU (sd)->state.cio_buffer + 3, 8); 806 807 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, buffer, 808 MSP430_CPU (sd)->state.cio_buffer + 11, length); 809 810 switch (command) 811 { 812 case CIO_WRITE: 813 fd = CIO_I (0); 814 len = CIO_I (2); 815 816 rv = write (fd, buffer, len); 817 parms[0] = rv & 0xff; 818 parms[1] = rv >> 8; 819 820 break; 821 } 822 823 sim_core_write_buffer (sd, MSP430_CPU (sd), 0, parms, 824 MSP430_CPU (sd)->state.cio_buffer + 4, 8); 825 if (ret_buflen) 826 sim_core_write_buffer (sd, MSP430_CPU (sd), 0, buffer, 827 MSP430_CPU (sd)->state.cio_buffer + 12, ret_buflen); 828 } 829 830 #define SRC get_op (sd, opcode, 1) 831 #define DSRC get_op (sd, opcode, 0) 832 #define DEST(V) put_op (sd, opcode, 0, (V)) 833 834 #define DO_ALU(OP,SOP,MORE) \ 835 { \ 836 int s1 = DSRC; \ 837 int s2 = SRC; \ 838 int result = s1 OP s2 MORE; \ 839 TRACE_ALU (MSP430_CPU (sd), "ALU: %#x %s %#x %s = %#x", s1, SOP, \ 840 s2, #MORE, result); \ 841 DEST (result); \ 842 } 843 844 #define SIGN (1 << (opcode->size - 1)) 845 #define POS(x) (((x) & SIGN) ? 0 : 1) 846 #define NEG(x) (((x) & SIGN) ? 1 : 0) 847 848 #define SX(v) sign_ext (v, opcode->size) 849 #define ZX(v) zero_ext (v, opcode->size) 850 851 static char * 852 flags2string (int f) 853 { 854 static char buf[2][6]; 855 static int bi = 0; 856 char *bp = buf[bi]; 857 858 bi = (bi + 1) % 2; 859 860 bp[0] = f & MSP430_FLAG_V ? 'V' : '-'; 861 bp[1] = f & MSP430_FLAG_N ? 'N' : '-'; 862 bp[2] = f & MSP430_FLAG_Z ? 'Z' : '-'; 863 bp[3] = f & MSP430_FLAG_C ? 'C' : '-'; 864 bp[4] = 0; 865 return bp; 866 } 867 868 /* Random number that won't show up in our usual logic. */ 869 #define MAGIC_OVERFLOW 0x55000F 870 871 static void 872 do_flags (SIM_DESC sd, 873 MSP430_Opcode_Decoded *opcode, 874 int vnz_val, /* Signed result. */ 875 int carry, 876 int overflow) 877 { 878 int f = SR; 879 int new_f = 0; 880 int signbit = 1 << (opcode->size - 1); 881 882 f &= ~opcode->flags_0; 883 f &= ~opcode->flags_set; 884 f |= opcode->flags_1; 885 886 if (vnz_val & signbit) 887 new_f |= MSP430_FLAG_N; 888 if (! (vnz_val & ((signbit << 1) - 1))) 889 new_f |= MSP430_FLAG_Z; 890 if (overflow == MAGIC_OVERFLOW) 891 { 892 if (vnz_val != SX (vnz_val)) 893 new_f |= MSP430_FLAG_V; 894 } 895 else 896 if (overflow) 897 new_f |= MSP430_FLAG_V; 898 if (carry) 899 new_f |= MSP430_FLAG_C; 900 901 new_f = f | (new_f & opcode->flags_set); 902 if (SR != new_f) 903 TRACE_ALU (MSP430_CPU (sd), "FLAGS: %s -> %s", flags2string (SR), 904 flags2string (new_f)); 905 else 906 TRACE_ALU (MSP430_CPU (sd), "FLAGS: %s", flags2string (new_f)); 907 SR = new_f; 908 } 909 910 #define FLAGS(vnz,c) do_flags (sd, opcode, vnz, c, MAGIC_OVERFLOW) 911 #define FLAGSV(vnz,c,v) do_flags (sd, opcode, vnz, c, v) 912 913 /* These two assume unsigned 16-bit (four digit) words. 914 Mask off unwanted bits for byte operations. */ 915 916 static int 917 bcd_to_binary (int v) 918 { 919 int r = ( ((v >> 0) & 0xf) * 1 920 + ((v >> 4) & 0xf) * 10 921 + ((v >> 8) & 0xf) * 100 922 + ((v >> 12) & 0xf) * 1000); 923 return r; 924 } 925 926 static int 927 binary_to_bcd (int v) 928 { 929 int r = ( ((v / 1) % 10) << 0 930 | ((v / 10) % 10) << 4 931 | ((v / 100) % 10) << 8 932 | ((v / 1000) % 10) << 12); 933 return r; 934 } 935 936 static const char * 937 cond_string (int cond) 938 { 939 switch (cond) 940 { 941 case MSC_nz: 942 return "NZ"; 943 case MSC_z: 944 return "Z"; 945 case MSC_nc: 946 return "NC"; 947 case MSC_c: 948 return "C"; 949 case MSC_n: 950 return "N"; 951 case MSC_ge: 952 return "GE"; 953 case MSC_l: 954 return "L"; 955 case MSC_true: 956 return "MP"; 957 default: 958 return "??"; 959 } 960 } 961 962 /* Checks a CALL to address CALL_ADDR. If this is a special 963 syscall address then the call is simulated and non-zero is 964 returned. Otherwise 0 is returned. */ 965 966 static int 967 maybe_perform_syscall (SIM_DESC sd, int call_addr) 968 { 969 if (call_addr == 0x00160) 970 { 971 int i; 972 973 for (i = 0; i < 16; i++) 974 { 975 if (i % 4 == 0) 976 fprintf (stderr, "\t"); 977 fprintf (stderr, "R%-2d %05x ", i, MSP430_CPU (sd)->state.regs[i]); 978 if (i % 4 == 3) 979 { 980 int sp = SP + (3 - (i / 4)) * 2; 981 unsigned char buf[2]; 982 983 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, sp, 2); 984 985 fprintf (stderr, "\tSP%+d: %04x", sp - SP, 986 buf[0] + buf[1] * 256); 987 988 if (i / 4 == 0) 989 { 990 int flags = SR; 991 992 fprintf (stderr, flags & 0x100 ? " V" : " -"); 993 fprintf (stderr, flags & 0x004 ? "N" : "-"); 994 fprintf (stderr, flags & 0x002 ? "Z" : "-"); 995 fprintf (stderr, flags & 0x001 ? "C" : "-"); 996 } 997 998 fprintf (stderr, "\n"); 999 } 1000 } 1001 return 1; 1002 } 1003 1004 if ((call_addr & ~0x3f) == 0x00180) 1005 { 1006 /* Syscall! */ 1007 int arg1, arg2, arg3, arg4; 1008 int syscall_num = call_addr & 0x3f; 1009 1010 /* syscall_num == 2 is used for the variadic function "open". 1011 The arguments are set up differently for variadic functions. 1012 See slaa534.pdf distributed by TI. */ 1013 if (syscall_num == 2) 1014 { 1015 arg1 = MSP430_CPU (sd)->state.regs[12]; 1016 arg2 = mem_get_val (sd, SP, 16); 1017 arg3 = mem_get_val (sd, SP + 2, 16); 1018 arg4 = mem_get_val (sd, SP + 4, 16); 1019 } 1020 else 1021 { 1022 arg1 = MSP430_CPU (sd)->state.regs[12]; 1023 arg2 = MSP430_CPU (sd)->state.regs[13]; 1024 arg3 = MSP430_CPU (sd)->state.regs[14]; 1025 arg4 = MSP430_CPU (sd)->state.regs[15]; 1026 } 1027 1028 MSP430_CPU (sd)->state.regs[12] = sim_syscall (MSP430_CPU (sd), 1029 syscall_num, arg1, arg2, 1030 arg3, arg4); 1031 return 1; 1032 } 1033 1034 return 0; 1035 } 1036 1037 static void 1038 msp430_step_once (SIM_DESC sd) 1039 { 1040 Get_Byte_Local_Data ld; 1041 unsigned char buf[100]; 1042 int i; 1043 int opsize; 1044 unsigned int opcode_pc; 1045 MSP430_Opcode_Decoded opcode_buf; 1046 MSP430_Opcode_Decoded *opcode = &opcode_buf; 1047 int s1, s2, result; 1048 int u1 = 0, u2, uresult; 1049 int c = 0, reg; 1050 int sp; 1051 int carry_to_use; 1052 int n_repeats; 1053 int rept; 1054 int op_bytes = 0, op_bits; 1055 1056 PC &= 0xfffff; 1057 opcode_pc = PC; 1058 1059 if (opcode_pc < 0x10) 1060 { 1061 fprintf (stderr, "Fault: PC(%#x) is less than 0x10\n", opcode_pc); 1062 sim_engine_halt (sd, MSP430_CPU (sd), NULL, 1063 MSP430_CPU (sd)->state.regs[0], 1064 sim_exited, -1); 1065 return; 1066 } 1067 1068 if (PC == MSP430_CPU (sd)->state.cio_breakpoint 1069 && STATE_OPEN_KIND (sd) != SIM_OPEN_DEBUG) 1070 msp430_cio (sd); 1071 1072 ld.sd = sd; 1073 ld.gb_addr = PC; 1074 opsize = msp430_decode_opcode (MSP430_CPU (sd)->state.regs[0], 1075 opcode, msp430_getbyte, &ld); 1076 PC += opsize; 1077 if (opsize <= 0) 1078 { 1079 fprintf (stderr, "Fault: undecodable opcode at %#x\n", opcode_pc); 1080 sim_engine_halt (sd, MSP430_CPU (sd), NULL, 1081 MSP430_CPU (sd)->state.regs[0], 1082 sim_exited, -1); 1083 return; 1084 } 1085 1086 if (opcode->repeat_reg) 1087 n_repeats = (MSP430_CPU (sd)->state.regs[opcode->repeats] & 0x000f) + 1; 1088 else 1089 n_repeats = opcode->repeats + 1; 1090 1091 op_bits = opcode->size; 1092 switch (op_bits) 1093 { 1094 case 8: 1095 op_bytes = 1; 1096 break; 1097 case 16: 1098 op_bytes = 2; 1099 break; 1100 case 20: 1101 case 32: 1102 op_bytes = 4; 1103 break; 1104 } 1105 1106 if (TRACE_ANY_P (MSP430_CPU (sd))) 1107 trace_prefix (sd, MSP430_CPU (sd), NULL_CIA, opcode_pc, 1108 TRACE_LINENUM_P (MSP430_CPU (sd)), NULL, 0, " "); 1109 1110 TRACE_DISASM (MSP430_CPU (sd), opcode_pc); 1111 1112 carry_to_use = 0; 1113 switch (opcode->id) 1114 { 1115 case MSO_unknown: 1116 break; 1117 1118 /* Double-operand instructions. */ 1119 case MSO_mov: 1120 if (opcode->n_bytes == 2 1121 && opcode->op[0].type == MSP430_Operand_Register 1122 && opcode->op[0].reg == MSR_CG 1123 && opcode->op[1].type == MSP430_Operand_Immediate 1124 && opcode->op[1].addend == 0 1125 /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK. */ 1126 && opcode->size == 8) 1127 { 1128 /* This is the designated software breakpoint instruction. */ 1129 PC -= opsize; 1130 sim_engine_halt (sd, MSP430_CPU (sd), NULL, 1131 MSP430_CPU (sd)->state.regs[0], 1132 sim_stopped, SIM_SIGTRAP); 1133 1134 } 1135 else 1136 { 1137 /* Otherwise, do the move. */ 1138 for (rept = 0; rept < n_repeats; rept ++) 1139 { 1140 DEST (SRC); 1141 } 1142 } 1143 break; 1144 1145 case MSO_addc: 1146 for (rept = 0; rept < n_repeats; rept ++) 1147 { 1148 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0; 1149 u1 = DSRC; 1150 u2 = SRC; 1151 s1 = SX (u1); 1152 s2 = SX (u2); 1153 uresult = u1 + u2 + carry_to_use; 1154 result = s1 + s2 + carry_to_use; 1155 TRACE_ALU (MSP430_CPU (sd), "ADDC: %#x + %#x + %d = %#x", 1156 u1, u2, carry_to_use, uresult); 1157 DEST (result); 1158 FLAGS (result, uresult != ZX (uresult)); 1159 } 1160 break; 1161 1162 case MSO_add: 1163 for (rept = 0; rept < n_repeats; rept ++) 1164 { 1165 u1 = DSRC; 1166 u2 = SRC; 1167 s1 = SX (u1); 1168 s2 = SX (u2); 1169 uresult = u1 + u2; 1170 result = s1 + s2; 1171 TRACE_ALU (MSP430_CPU (sd), "ADD: %#x + %#x = %#x", 1172 u1, u2, uresult); 1173 DEST (result); 1174 FLAGS (result, uresult != ZX (uresult)); 1175 } 1176 break; 1177 1178 case MSO_subc: 1179 for (rept = 0; rept < n_repeats; rept ++) 1180 { 1181 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0; 1182 u1 = DSRC; 1183 u2 = SRC; 1184 s1 = SX (u1); 1185 s2 = SX (u2); 1186 uresult = ZX (~u2) + u1 + carry_to_use; 1187 result = s1 - s2 + (carry_to_use - 1); 1188 TRACE_ALU (MSP430_CPU (sd), "SUBC: %#x - %#x + %d = %#x", 1189 u1, u2, carry_to_use, uresult); 1190 DEST (result); 1191 FLAGS (result, uresult != ZX (uresult)); 1192 } 1193 break; 1194 1195 case MSO_sub: 1196 for (rept = 0; rept < n_repeats; rept ++) 1197 { 1198 u1 = DSRC; 1199 u2 = SRC; 1200 s1 = SX (u1); 1201 s2 = SX (u2); 1202 uresult = ZX (~u2) + u1 + 1; 1203 result = SX (uresult); 1204 TRACE_ALU (MSP430_CPU (sd), "SUB: %#x - %#x = %#x", 1205 u1, u2, uresult); 1206 DEST (result); 1207 FLAGS (result, uresult != ZX (uresult)); 1208 } 1209 break; 1210 1211 case MSO_cmp: 1212 for (rept = 0; rept < n_repeats; rept ++) 1213 { 1214 u1 = DSRC; 1215 u2 = SRC; 1216 s1 = SX (u1); 1217 s2 = SX (u2); 1218 uresult = ZX (~u2) + u1 + 1; 1219 result = s1 - s2; 1220 TRACE_ALU (MSP430_CPU (sd), "CMP: %#x - %#x = %x", 1221 u1, u2, uresult); 1222 FLAGS (result, uresult != ZX (uresult)); 1223 } 1224 break; 1225 1226 case MSO_dadd: 1227 for (rept = 0; rept < n_repeats; rept ++) 1228 { 1229 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0; 1230 u1 = DSRC; 1231 u2 = SRC; 1232 uresult = bcd_to_binary (u1) + bcd_to_binary (u2) + carry_to_use; 1233 result = binary_to_bcd (uresult); 1234 TRACE_ALU (MSP430_CPU (sd), "DADD: %#x + %#x + %d = %#x", 1235 u1, u2, carry_to_use, result); 1236 DEST (result); 1237 FLAGS (result, uresult > ((opcode->size == 8) ? 99 : 9999)); 1238 } 1239 break; 1240 1241 case MSO_and: 1242 for (rept = 0; rept < n_repeats; rept ++) 1243 { 1244 u1 = DSRC; 1245 u2 = SRC; 1246 uresult = u1 & u2; 1247 TRACE_ALU (MSP430_CPU (sd), "AND: %#x & %#x = %#x", 1248 u1, u2, uresult); 1249 DEST (uresult); 1250 FLAGS (uresult, uresult != 0); 1251 } 1252 break; 1253 1254 case MSO_bit: 1255 for (rept = 0; rept < n_repeats; rept ++) 1256 { 1257 u1 = DSRC; 1258 u2 = SRC; 1259 uresult = u1 & u2; 1260 TRACE_ALU (MSP430_CPU (sd), "BIT: %#x & %#x -> %#x", 1261 u1, u2, uresult); 1262 FLAGS (uresult, uresult != 0); 1263 } 1264 break; 1265 1266 case MSO_bic: 1267 for (rept = 0; rept < n_repeats; rept ++) 1268 { 1269 u1 = DSRC; 1270 u2 = SRC; 1271 uresult = u1 & ~ u2; 1272 TRACE_ALU (MSP430_CPU (sd), "BIC: %#x & ~ %#x = %#x", 1273 u1, u2, uresult); 1274 DEST (uresult); 1275 } 1276 break; 1277 1278 case MSO_bis: 1279 for (rept = 0; rept < n_repeats; rept ++) 1280 { 1281 u1 = DSRC; 1282 u2 = SRC; 1283 uresult = u1 | u2; 1284 TRACE_ALU (MSP430_CPU (sd), "BIS: %#x | %#x = %#x", 1285 u1, u2, uresult); 1286 DEST (uresult); 1287 } 1288 break; 1289 1290 case MSO_xor: 1291 for (rept = 0; rept < n_repeats; rept ++) 1292 { 1293 s1 = 1 << (opcode->size - 1); 1294 u1 = DSRC; 1295 u2 = SRC; 1296 uresult = u1 ^ u2; 1297 TRACE_ALU (MSP430_CPU (sd), "XOR: %#x & %#x = %#x", 1298 u1, u2, uresult); 1299 DEST (uresult); 1300 FLAGSV (uresult, uresult != 0, (u1 & s1) && (u2 & s1)); 1301 } 1302 break; 1303 1304 /* Single-operand instructions. Note: the decoder puts the same 1305 operand in SRC as in DEST, for our convenience. */ 1306 1307 case MSO_rrc: 1308 for (rept = 0; rept < n_repeats; rept ++) 1309 { 1310 u1 = SRC; 1311 carry_to_use = u1 & 1; 1312 uresult = u1 >> 1; 1313 /* If the ZC bit of the opcode is set, it means we are synthesizing 1314 RRUX, so the carry bit must be ignored. */ 1315 if (opcode->zc == 0 && (SR & MSP430_FLAG_C)) 1316 uresult |= (1 << (opcode->size - 1)); 1317 TRACE_ALU (MSP430_CPU (sd), "RRC: %#x >>= %#x", 1318 u1, uresult); 1319 DEST (uresult); 1320 FLAGS (uresult, carry_to_use); 1321 } 1322 break; 1323 1324 case MSO_swpb: 1325 for (rept = 0; rept < n_repeats; rept ++) 1326 { 1327 u1 = SRC; 1328 uresult = ((u1 >> 8) & 0x00ff) | ((u1 << 8) & 0xff00); 1329 TRACE_ALU (MSP430_CPU (sd), "SWPB: %#x -> %#x", 1330 u1, uresult); 1331 DEST (uresult); 1332 } 1333 break; 1334 1335 case MSO_rra: 1336 for (rept = 0; rept < n_repeats; rept ++) 1337 { 1338 u1 = SRC; 1339 c = u1 & 1; 1340 s1 = 1 << (opcode->size - 1); 1341 uresult = (u1 >> 1) | (u1 & s1); 1342 TRACE_ALU (MSP430_CPU (sd), "RRA: %#x >>= %#x", 1343 u1, uresult); 1344 DEST (uresult); 1345 FLAGS (uresult, c); 1346 } 1347 break; 1348 1349 case MSO_rru: 1350 for (rept = 0; rept < n_repeats; rept ++) 1351 { 1352 u1 = SRC; 1353 c = u1 & 1; 1354 uresult = (u1 >> 1); 1355 TRACE_ALU (MSP430_CPU (sd), "RRU: %#x >>= %#x", 1356 u1, uresult); 1357 DEST (uresult); 1358 FLAGS (uresult, c); 1359 } 1360 break; 1361 1362 case MSO_sxt: 1363 for (rept = 0; rept < n_repeats; rept ++) 1364 { 1365 u1 = SRC; 1366 if (u1 & 0x80) 1367 uresult = u1 | 0xfff00; 1368 else 1369 uresult = u1 & 0x000ff; 1370 TRACE_ALU (MSP430_CPU (sd), "SXT: %#x -> %#x", 1371 u1, uresult); 1372 DEST (uresult); 1373 FLAGS (uresult, c); 1374 } 1375 break; 1376 1377 case MSO_push: 1378 for (rept = 0; rept < n_repeats; rept ++) 1379 { 1380 int new_sp; 1381 1382 new_sp = REG_GET (MSR_SP) - op_bytes; 1383 /* SP is always word-aligned. */ 1384 if (new_sp & 1) 1385 new_sp --; 1386 REG_PUT (MSR_SP, new_sp); 1387 u1 = SRC; 1388 mem_put_val (sd, SP, u1, op_bits); 1389 if (opcode->op[1].type == MSP430_Operand_Register) 1390 opcode->op[1].reg --; 1391 } 1392 break; 1393 1394 case MSO_pop: 1395 for (rept = 0; rept < n_repeats; rept ++) 1396 { 1397 int new_sp; 1398 1399 u1 = mem_get_val (sd, SP, op_bits); 1400 DEST (u1); 1401 if (opcode->op[0].type == MSP430_Operand_Register) 1402 opcode->op[0].reg ++; 1403 new_sp = REG_GET (MSR_SP) + op_bytes; 1404 /* SP is always word-aligned. */ 1405 if (new_sp & 1) 1406 new_sp ++; 1407 REG_PUT (MSR_SP, new_sp); 1408 } 1409 break; 1410 1411 case MSO_call: 1412 u1 = SRC; 1413 1414 if (maybe_perform_syscall (sd, u1)) 1415 break; 1416 1417 REG_PUT (MSR_SP, REG_GET (MSR_SP) - op_bytes); 1418 mem_put_val (sd, SP, PC, op_bits); 1419 TRACE_ALU (MSP430_CPU (sd), "CALL: func %#x ret %#x, sp %#x", 1420 u1, PC, SP); 1421 REG_PUT (MSR_PC, u1); 1422 break; 1423 1424 case MSO_reti: 1425 u1 = mem_get_val (sd, SP, 16); 1426 SR = u1 & 0xFF; 1427 SP += 2; 1428 PC = mem_get_val (sd, SP, 16); 1429 SP += 2; 1430 /* Emulate the RETI action of the 20-bit CPUX architecure. 1431 This is safe for 16-bit CPU architectures as well, since the top 1432 8-bits of SR will have been written to the stack here, and will 1433 have been read as 0. */ 1434 PC |= (u1 & 0xF000) << 4; 1435 TRACE_ALU (MSP430_CPU (sd), "RETI: pc %#x sr %#x", 1436 PC, SR); 1437 break; 1438 1439 /* Jumps. */ 1440 1441 case MSO_jmp: 1442 i = SRC; 1443 switch (opcode->cond) 1444 { 1445 case MSC_nz: 1446 u1 = (SR & MSP430_FLAG_Z) ? 0 : 1; 1447 break; 1448 case MSC_z: 1449 u1 = (SR & MSP430_FLAG_Z) ? 1 : 0; 1450 break; 1451 case MSC_nc: 1452 u1 = (SR & MSP430_FLAG_C) ? 0 : 1; 1453 break; 1454 case MSC_c: 1455 u1 = (SR & MSP430_FLAG_C) ? 1 : 0; 1456 break; 1457 case MSC_n: 1458 u1 = (SR & MSP430_FLAG_N) ? 1 : 0; 1459 break; 1460 case MSC_ge: 1461 u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 1 : 0; 1462 break; 1463 case MSC_l: 1464 u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 0 : 1; 1465 break; 1466 case MSC_true: 1467 u1 = 1; 1468 break; 1469 } 1470 1471 if (u1) 1472 { 1473 TRACE_BRANCH (MSP430_CPU (sd), "J%s: pc %#x -> %#x sr %#x, taken", 1474 cond_string (opcode->cond), PC, i, SR); 1475 PC = i; 1476 if (PC == opcode_pc) 1477 exit (0); 1478 } 1479 else 1480 TRACE_BRANCH (MSP430_CPU (sd), "J%s: pc %#x to %#x sr %#x, not taken", 1481 cond_string (opcode->cond), PC, i, SR); 1482 break; 1483 1484 default: 1485 fprintf (stderr, "error: unexpected opcode id %d\n", opcode->id); 1486 exit (1); 1487 } 1488 } 1489 1490 void 1491 sim_engine_run (SIM_DESC sd, 1492 int next_cpu_nr, 1493 int nr_cpus, 1494 int siggnal) 1495 { 1496 while (1) 1497 { 1498 msp430_step_once (sd); 1499 if (sim_events_tick (sd)) 1500 sim_events_process (sd); 1501 } 1502 } 1503