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