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