1 /* Simulator for TI MSP430 and MSP430X
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.
7 This file is part of simulators.
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.
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.
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/>. */
29 #include "opcode/msp430-decode.h"
32 #include "targ-vals.h"
35 loader_write_mem (SIM_DESC sd,
37 const unsigned char *buf,
40 SIM_CPU *cpu = MSP430_CPU (sd);
41 return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
45 msp430_pc_fetch (SIM_CPU *cpu)
47 return cpu->state.regs[0];
51 msp430_pc_store (SIM_CPU *cpu, sim_cia newpc)
53 cpu->state.regs[0] = newpc;
57 lookup_symbol (SIM_DESC sd, const char *name)
59 struct bfd *abfd = STATE_PROG_BFD (sd);
60 asymbol **symbol_table = STATE_SYMBOL_TABLE (sd);
61 long number_of_symbols = STATE_NUM_SYMBOLS (sd);
64 if (symbol_table == NULL)
68 storage_needed = bfd_get_symtab_upper_bound (abfd);
69 if (storage_needed <= 0)
72 STATE_SYMBOL_TABLE (sd) = symbol_table = xmalloc (storage_needed);
73 STATE_NUM_SYMBOLS (sd) = number_of_symbols =
74 bfd_canonicalize_symtab (abfd, symbol_table);
77 for (i = 0; i < number_of_symbols; i++)
78 if (strcmp (symbol_table[i]->name, name) == 0)
80 long val = symbol_table[i]->section->vma + symbol_table[i]->value;
87 msp430_reg_fetch (SIM_CPU *cpu, int regno, unsigned char *buf, int len)
89 if (0 <= regno && regno < 16)
93 int val = cpu->state.regs[regno];
95 buf[1] = (val >> 8) & 0xff;
100 int val = cpu->state.regs[regno];
102 buf[1] = (val >> 8) & 0xff;
103 buf[2] = (val >> 16) & 0x0f; /* Registers are only 20 bits wide. */
115 msp430_reg_store (SIM_CPU *cpu, int regno, unsigned char *buf, int len)
117 if (0 <= regno && regno < 16)
121 cpu->state.regs[regno] = (buf[1] << 8) | buf[0];
127 cpu->state.regs[regno] = ((buf[2] << 16) & 0xf0000)
128 | (buf[1] << 8) | buf[0];
137 msp430_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu)
139 memset (&cpu->state, 0, sizeof (cpu->state));
143 sim_open (SIM_OPEN_KIND kind,
144 struct host_callback_struct *callback,
148 SIM_DESC sd = sim_state_alloc (kind, callback);
150 struct bfd *prog_bfd;
152 /* Initialise the simulator. */
154 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
160 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
166 if (sim_parse_args (sd, argv) != SIM_RC_OK)
172 CPU_PC_FETCH (MSP430_CPU (sd)) = msp430_pc_fetch;
173 CPU_PC_STORE (MSP430_CPU (sd)) = msp430_pc_store;
174 CPU_REG_FETCH (MSP430_CPU (sd)) = msp430_reg_fetch;
175 CPU_REG_STORE (MSP430_CPU (sd)) = msp430_reg_store;
177 /* Allocate memory if none specified by user.
178 Note - these values match the memory regions in the libgloss/msp430/msp430[xl]-sim.ld scripts. */
179 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x2, 1) == 0)
180 sim_do_commandf (sd, "memory-region 0,0x20"); /* Needed by the GDB testsuite. */
181 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x200, 1) == 0)
182 sim_do_commandf (sd, "memory-region 0x200,0xfd00"); /* RAM and/or ROM */
183 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0xfffe, 1) == 0)
184 sim_do_commandf (sd, "memory-region 0xffc0,0x40"); /* VECTORS. */
185 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x10000, 1) == 0)
186 sim_do_commandf (sd, "memory-region 0x10000,0x80000"); /* HIGH FLASH RAM. */
187 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x90000, 1) == 0)
188 sim_do_commandf (sd, "memory-region 0x90000,0x70000"); /* HIGH ROM. */
190 /* Check for/establish the a reference program image. */
191 if (sim_analyze_program (sd,
192 (STATE_PROG_ARGV (sd) != NULL
193 ? *STATE_PROG_ARGV (sd)
194 : NULL), abfd) != SIM_RC_OK)
200 prog_bfd = sim_load_file (sd, argv[0], callback,
204 1 /* use LMA instead of VMA */,
206 /* Allow prog_bfd to be NULL - this is needed by the GDB testsuite. */
208 /* Establish any remaining configuration options. */
209 if (sim_config (sd) != SIM_RC_OK)
215 if (sim_post_argv_init (sd) != SIM_RC_OK)
221 /* CPU specific initialization. */
222 assert (MAX_NR_PROCESSORS == 1);
223 msp430_initialize_cpu (sd, MSP430_CPU (sd));
225 msp430_trace_init (STATE_PROG_BFD (sd));
227 if (prog_bfd != NULL)
229 MSP430_CPU (sd)->state.cio_breakpoint = lookup_symbol (sd, "C$$IO$$");
230 MSP430_CPU (sd)->state.cio_buffer = lookup_symbol (sd, "__CIOBUF__");
231 if (MSP430_CPU (sd)->state.cio_buffer == -1)
232 MSP430_CPU (sd)->state.cio_buffer = lookup_symbol (sd, "_CIOBUF_");
239 sim_close (SIM_DESC sd,
242 free (STATE_SYMBOL_TABLE (sd));
247 sim_create_inferior (SIM_DESC sd,
252 unsigned char resetv[2];
256 /* Set the PC to the default reset vector if available. */
257 c = sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, resetv, 0xfffe, 2);
258 new_pc = resetv[0] + 256 * resetv[1];
260 /* If the reset vector isn't initialized, then use the ELF entry. */
261 if (abfd != NULL && !new_pc)
262 new_pc = bfd_get_start_address (abfd);
264 sim_pc_set (MSP430_CPU (sd), new_pc);
265 msp430_pc_store (MSP430_CPU (sd), new_pc);
274 } Get_Byte_Local_Data;
277 msp430_getbyte (void *vld)
279 Get_Byte_Local_Data *ld = (Get_Byte_Local_Data *)vld;
281 SIM_DESC sd = ld->sd;
283 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, ld->gb_addr, 1);
288 #define REG(N) MSP430_CPU (sd)->state.regs[(N)]
289 #define PC REG(MSR_PC)
290 #define SP REG(MSR_SP)
291 #define SR REG(MSR_SR)
296 "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8",
297 "R9", "R10", "R11", "R12", "R13", "R14", "R15"
301 trace_reg_put (SIM_DESC sd, int n, unsigned int v)
303 if (TRACE_VPU_P (MSP430_CPU (sd)))
304 trace_generic (sd, MSP430_CPU (sd), TRACE_VPU_IDX,
305 "PUT: %#x -> %s", v, register_names [n]);
310 trace_reg_get (SIM_DESC sd, int n)
312 if (TRACE_VPU_P (MSP430_CPU (sd)))
313 trace_generic (sd, MSP430_CPU (sd), TRACE_VPU_IDX,
314 "GET: %s -> %#x", register_names [n], REG (n));
318 #define REG_PUT(N,V) trace_reg_put (sd, N, V)
319 #define REG_GET(N) trace_reg_get (sd, N)
321 /* Hardware multiply (and accumulate) support. */
324 zero_ext (unsigned int v, unsigned int bits)
326 v &= ((1 << bits) - 1);
330 static signed long long
331 sign_ext (signed long long v, unsigned int bits)
333 signed long long sb = 1LL << (bits-1); /* Sign bit. */
334 signed long long mb = (1LL << (bits-1)) - 1LL; /* Mantissa bits. */
344 get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
346 MSP430_Opcode_Operand *op = opc->op + n;
349 unsigned char buf[4];
354 case MSP430_Operand_Immediate:
357 case MSP430_Operand_Register:
358 rv = REG_GET (op->reg);
360 case MSP430_Operand_Indirect:
361 case MSP430_Operand_Indirect_Postinc:
363 if (op->reg != MSR_None)
365 int reg = REG_GET (op->reg);
366 int sign = opc->ofs_430x ? 20 : 16;
368 /* Index values are signed. */
369 if (addr & (1 << (sign - 1)))
374 /* For MSP430 instructions the sum is limited to 16 bits if the
375 address in the index register is less than 64k even if we are
376 running on an MSP430X CPU. This is for MSP430 compatibility. */
377 if (reg < 0x10000 && ! opc->ofs_430x)
380 fprintf (stderr, " XXX WRAPPING ADDRESS %x on read\n", addr);
389 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 1);
393 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 2);
394 rv = buf[0] | (buf[1] << 8);
398 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 4);
399 rv = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
402 assert (! opc->size);
406 /* Hack - MSP430X5438 serial port status register. */
410 if (addr >= 0x130 && addr <= 0x15B)
415 switch (HWMULT (sd, hwmult_type))
419 rv = zero_ext (HWMULT (sd, hwmult_result), 16);
423 rv = sign_ext (HWMULT (sd, hwmult_signed_result), 16);
429 switch (HWMULT (sd, hwmult_type))
433 rv = zero_ext (HWMULT (sd, hwmult_result) >> 16, 16);
438 rv = sign_ext (HWMULT (sd, hwmult_signed_result) >> 16, 16);
444 switch (HWMULT (sd, hwmult_type))
450 rv = HWMULT (sd, hwmult_signed_result) < 0 ? -1 : 0;
453 rv = 0; /* FIXME: Should be carry of last accumulate. */
456 rv = HWMULT (sd, hwmult_signed_accumulator) < 0 ? -1 : 0;
462 rv = zero_ext (HWMULT (sd, hw32mult_result), 16);
466 rv = zero_ext (HWMULT (sd, hw32mult_result) >> 16, 16);
470 rv = zero_ext (HWMULT (sd, hw32mult_result) >> 32, 16);
474 switch (HWMULT (sd, hw32mult_type))
476 case UNSIGN_64: rv = zero_ext (HWMULT (sd, hw32mult_result) >> 48, 16); break;
477 case SIGN_64: rv = sign_ext (HWMULT (sd, hw32mult_result) >> 48, 16); break;
482 fprintf (stderr, "unimplemented HW MULT read from %x!\n", addr);
487 if (TRACE_MEMORY_P (MSP430_CPU (sd)))
488 trace_generic (sd, MSP430_CPU (sd), TRACE_MEMORY_IDX,
489 "GET: [%#x].%d -> %#x", addr, opc->size, rv);
493 fprintf (stderr, "invalid operand %d type %d\n", n, op->type);
517 if (op->type == MSP430_Operand_Indirect_Postinc)
518 REG_PUT (op->reg, REG_GET (op->reg) + incval);
524 put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val)
526 MSP430_Opcode_Operand *op = opc->op + n;
529 unsigned char buf[4];
550 case MSP430_Operand_Register:
552 REG_PUT (op->reg, val);
554 case MSP430_Operand_Indirect:
555 case MSP430_Operand_Indirect_Postinc:
557 if (op->reg != MSR_None)
559 int reg = REG_GET (op->reg);
560 int sign = opc->ofs_430x ? 20 : 16;
562 /* Index values are signed. */
563 if (addr & (1 << (sign - 1)))
568 /* For MSP430 instructions the sum is limited to 16 bits if the
569 address in the index register is less than 64k even if we are
570 running on an MSP430X CPU. This is for MSP430 compatibility. */
571 if (reg < 0x10000 && ! opc->ofs_430x)
574 fprintf (stderr, " XXX WRAPPING ADDRESS %x on write\n", addr);
581 if (TRACE_MEMORY_P (MSP430_CPU (sd)))
582 trace_generic (sd, MSP430_CPU (sd), TRACE_MEMORY_IDX,
583 "PUT: [%#x].%d <- %#x", addr, opc->size, val);
585 /* Hack - MSP430X5438 serial port transmit register. */
589 if (addr >= 0x130 && addr <= 0x15B)
593 /* Hardware Multiply emulation. */
594 assert (opc->size == 16);
598 case 0x130: HWMULT (sd, hwmult_op1) = val; HWMULT (sd, hwmult_type) = UNSIGN_32; break;
599 case 0x132: HWMULT (sd, hwmult_op1) = val; HWMULT (sd, hwmult_type) = SIGN_32; break;
600 case 0x134: HWMULT (sd, hwmult_op1) = val; HWMULT (sd, hwmult_type) = UNSIGN_MAC_32; break;
601 case 0x136: HWMULT (sd, hwmult_op1) = val; HWMULT (sd, hwmult_type) = SIGN_MAC_32; break;
603 case 0x138: HWMULT (sd, hwmult_op2) = val;
604 switch (HWMULT (sd, hwmult_type))
607 HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_op1) * HWMULT (sd, hwmult_op2);
608 HWMULT (sd, hwmult_signed_result) = (signed) HWMULT (sd, hwmult_result);
609 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_signed_accumulator) = 0;
613 a = sign_ext (HWMULT (sd, hwmult_op1), 16);
614 b = sign_ext (HWMULT (sd, hwmult_op2), 16);
615 HWMULT (sd, hwmult_signed_result) = a * b;
616 HWMULT (sd, hwmult_result) = (unsigned) HWMULT (sd, hwmult_signed_result);
617 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_signed_accumulator) = 0;
621 HWMULT (sd, hwmult_accumulator) += HWMULT (sd, hwmult_op1) * HWMULT (sd, hwmult_op2);
622 HWMULT (sd, hwmult_signed_accumulator) += HWMULT (sd, hwmult_op1) * HWMULT (sd, hwmult_op2);
623 HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_accumulator);
624 HWMULT (sd, hwmult_signed_result) = HWMULT (sd, hwmult_signed_accumulator);
628 a = sign_ext (HWMULT (sd, hwmult_op1), 16);
629 b = sign_ext (HWMULT (sd, hwmult_op2), 16);
630 HWMULT (sd, hwmult_accumulator) += a * b;
631 HWMULT (sd, hwmult_signed_accumulator) += a * b;
632 HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_accumulator);
633 HWMULT (sd, hwmult_signed_result) = HWMULT (sd, hwmult_signed_accumulator);
639 /* Copy into LOW result... */
640 switch (HWMULT (sd, hwmult_type))
644 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_result) = zero_ext (val, 16);
645 HWMULT (sd, hwmult_signed_accumulator) = sign_ext (val, 16);
649 HWMULT (sd, hwmult_signed_accumulator) = HWMULT (sd, hwmult_result) = sign_ext (val, 16);
650 HWMULT (sd, hwmult_accumulator) = zero_ext (val, 16);
656 HWMULT (sd, hw32mult_op1) = val;
657 HWMULT (sd, hw32mult_type) = UNSIGN_64;
660 HWMULT (sd, hw32mult_op1) = (HWMULT (sd, hw32mult_op1) & 0xFFFF) | (val << 16);
663 HWMULT (sd, hw32mult_op1) = val;
664 HWMULT (sd, hw32mult_type) = SIGN_64;
667 HWMULT (sd, hw32mult_op1) = (HWMULT (sd, hw32mult_op1) & 0xFFFF) | (val << 16);
670 HWMULT (sd, hw32mult_op2) = val;
674 HWMULT (sd, hw32mult_op2) = (HWMULT (sd, hw32mult_op2) & 0xFFFF) | (val << 16);
675 switch (HWMULT (sd, hw32mult_type))
678 HWMULT (sd, hw32mult_result) = HWMULT (sd, hw32mult_op1) * HWMULT (sd, hw32mult_op2);
681 HWMULT (sd, hw32mult_result) = sign_ext (HWMULT (sd, hw32mult_op1), 32)
682 * sign_ext (HWMULT (sd, hw32mult_op2), 32);
688 fprintf (stderr, "unimplemented HW MULT write to %x!\n", addr);
697 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 1);
702 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 2);
710 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 4);
713 assert (! opc->size);
718 fprintf (stderr, "invalid operand %d type %d\n", n, op->type);
742 if (op->type == MSP430_Operand_Indirect_Postinc)
744 int new_val = REG_GET (op->reg) + incval;
745 /* SP is always word-aligned. */
746 if (op->reg == MSR_SP && (new_val & 1))
748 REG_PUT (op->reg, new_val);
755 mem_put_val (SIM_DESC sd, int addr, int val, int bits)
757 MSP430_Opcode_Decoded opc;
760 opc.op[0].type = MSP430_Operand_Indirect;
761 opc.op[0].addend = addr;
762 opc.op[0].reg = MSR_None;
763 put_op (sd, &opc, 0, val);
767 mem_get_val (SIM_DESC sd, int addr, int bits)
769 MSP430_Opcode_Decoded opc;
772 opc.op[0].type = MSP430_Operand_Indirect;
773 opc.op[0].addend = addr;
774 opc.op[0].reg = MSR_None;
775 return get_op (sd, &opc, 0);
778 #define CIO_OPEN (0xF0)
779 #define CIO_CLOSE (0xF1)
780 #define CIO_READ (0xF2)
781 #define CIO_WRITE (0xF3)
782 #define CIO_LSEEK (0xF4)
783 #define CIO_UNLINK (0xF5)
784 #define CIO_GETENV (0xF6)
785 #define CIO_RENAME (0xF7)
786 #define CIO_GETTIME (0xF8)
787 #define CIO_GETCLK (0xF9)
788 #define CIO_SYNC (0xFF)
790 #define CIO_I(n) (parms[(n)] + parms[(n)+1] * 256)
791 #define CIO_L(n) (parms[(n)] + parms[(n)+1] * 256 \
792 + parms[(n)+2] * 65536 + parms[(n)+3] * 16777216)
795 msp430_cio (SIM_DESC sd)
797 /* A block of data at __CIOBUF__ describes the I/O operation to
800 unsigned char raw_parms[13];
801 unsigned char parms[8];
804 unsigned char buffer[512];
806 long fd, addr, len, rv;
808 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, parms,
809 MSP430_CPU (sd)->state.cio_buffer, 5);
813 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, parms,
814 MSP430_CPU (sd)->state.cio_buffer + 3, 8);
816 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, buffer,
817 MSP430_CPU (sd)->state.cio_buffer + 11, length);
825 rv = write (fd, buffer, len);
826 parms[0] = rv & 0xff;
832 sim_core_write_buffer (sd, MSP430_CPU (sd), 0, parms,
833 MSP430_CPU (sd)->state.cio_buffer + 4, 8);
835 sim_core_write_buffer (sd, MSP430_CPU (sd), 0, buffer,
836 MSP430_CPU (sd)->state.cio_buffer + 12, ret_buflen);
839 #define SRC get_op (sd, opcode, 1)
840 #define DSRC get_op (sd, opcode, 0)
841 #define DEST(V) put_op (sd, opcode, 0, (V))
844 msp430_dis_read (bfd_vma memaddr,
847 struct disassemble_info *dinfo)
849 SIM_DESC sd = dinfo->private_data;
850 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, myaddr, memaddr, length);
854 #define DO_ALU(OP,SOP,MORE) \
858 int result = s1 OP s2 MORE; \
859 if (TRACE_ALU_P (MSP430_CPU (sd))) \
860 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, \
861 "ALU: %#x %s %#x %s = %#x", s1, SOP, s2, #MORE, result); \
865 #define SIGN (1 << (opcode->size - 1))
866 #define POS(x) (((x) & SIGN) ? 0 : 1)
867 #define NEG(x) (((x) & SIGN) ? 1 : 0)
869 #define SX(v) sign_ext (v, opcode->size)
870 #define ZX(v) zero_ext (v, opcode->size)
875 static char buf[2][6];
881 bp[0] = f & MSP430_FLAG_V ? 'V' : '-';
882 bp[1] = f & MSP430_FLAG_N ? 'N' : '-';
883 bp[2] = f & MSP430_FLAG_Z ? 'Z' : '-';
884 bp[3] = f & MSP430_FLAG_C ? 'C' : '-';
889 /* Random number that won't show up in our usual logic. */
890 #define MAGIC_OVERFLOW 0x55000F
893 do_flags (SIM_DESC sd,
894 MSP430_Opcode_Decoded *opcode,
895 int vnz_val, /* Signed result. */
901 int signbit = 1 << (opcode->size - 1);
903 f &= ~opcode->flags_0;
904 f &= ~opcode->flags_set;
905 f |= opcode->flags_1;
907 if (vnz_val & signbit)
908 new_f |= MSP430_FLAG_N;
909 if (! (vnz_val & ((signbit << 1) - 1)))
910 new_f |= MSP430_FLAG_Z;
911 if (overflow == MAGIC_OVERFLOW)
913 if (vnz_val != SX (vnz_val))
914 new_f |= MSP430_FLAG_V;
918 new_f |= MSP430_FLAG_V;
920 new_f |= MSP430_FLAG_C;
922 new_f = f | (new_f & opcode->flags_set);
923 if (TRACE_ALU_P (MSP430_CPU (sd)))
926 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
927 "FLAGS: %s -> %s", flags2string (SR),
928 flags2string (new_f));
930 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
931 "FLAGS: %s", flags2string (new_f));
936 #define FLAGS(vnz,c) do_flags (sd, opcode, vnz, c, MAGIC_OVERFLOW)
937 #define FLAGSV(vnz,c,v) do_flags (sd, opcode, vnz, c, v)
939 /* These two assume unsigned 16-bit (four digit) words.
940 Mask off unwanted bits for byte operations. */
943 bcd_to_binary (int v)
945 int r = ( ((v >> 0) & 0xf) * 1
946 + ((v >> 4) & 0xf) * 10
947 + ((v >> 8) & 0xf) * 100
948 + ((v >> 12) & 0xf) * 1000);
953 binary_to_bcd (int v)
955 int r = ( ((v / 1) % 10) << 0
956 | ((v / 10) % 10) << 4
957 | ((v / 100) % 10) << 8
958 | ((v / 1000) % 10) << 12);
963 syscall_read_mem (host_callback *cb, struct cb_syscall *sc,
964 unsigned long taddr, char *buf, int bytes)
966 SIM_DESC sd = (SIM_DESC) sc->p1;
967 SIM_CPU *cpu = (SIM_CPU *) sc->p2;
969 return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
973 syscall_write_mem (host_callback *cb, struct cb_syscall *sc,
974 unsigned long taddr, const char *buf, int bytes)
976 SIM_DESC sd = (SIM_DESC) sc->p1;
977 SIM_CPU *cpu = (SIM_CPU *) sc->p2;
979 return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
983 cond_string (int cond)
1008 /* Checks a CALL to address CALL_ADDR. If this is a special
1009 syscall address then the call is simulated and non-zero is
1010 returned. Otherwise 0 is returned. */
1013 maybe_perform_syscall (SIM_DESC sd, int call_addr)
1015 if (call_addr == 0x00160)
1019 for (i = 0; i < 16; i++)
1022 fprintf (stderr, "\t");
1023 fprintf (stderr, "R%-2d %05x ", i, MSP430_CPU (sd)->state.regs[i]);
1026 int sp = SP + (3 - (i / 4)) * 2;
1027 unsigned char buf[2];
1029 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, sp, 2);
1031 fprintf (stderr, "\tSP%+d: %04x", sp - SP,
1032 buf[0] + buf[1] * 256);
1038 fprintf (stderr, flags & 0x100 ? " V" : " -");
1039 fprintf (stderr, flags & 0x004 ? "N" : "-");
1040 fprintf (stderr, flags & 0x002 ? "Z" : "-");
1041 fprintf (stderr, flags & 0x001 ? "C" : "-");
1044 fprintf (stderr, "\n");
1050 if ((call_addr & ~0x3f) == 0x00180)
1053 int syscall_num = call_addr & 0x3f;
1054 host_callback *cb = STATE_CALLBACK (sd);
1057 CB_SYSCALL_INIT (&sc);
1059 sc.func = syscall_num;
1060 sc.arg1 = MSP430_CPU (sd)->state.regs[12];
1061 sc.arg2 = MSP430_CPU (sd)->state.regs[13];
1062 sc.arg3 = MSP430_CPU (sd)->state.regs[14];
1063 sc.arg4 = MSP430_CPU (sd)->state.regs[15];
1065 if (TRACE_SYSCALL_P (MSP430_CPU (sd)))
1067 const char *syscall_name = "*unknown*";
1069 switch (syscall_num)
1071 case TARGET_SYS_exit:
1072 syscall_name = "exit(%d)";
1074 case TARGET_SYS_open:
1075 syscall_name = "open(%#x,%#x)";
1077 case TARGET_SYS_close:
1078 syscall_name = "close(%d)";
1080 case TARGET_SYS_read:
1081 syscall_name = "read(%d,%#x,%d)";
1083 case TARGET_SYS_write:
1084 syscall_name = "write(%d,%#x,%d)";
1087 trace_generic (sd, MSP430_CPU (sd), TRACE_SYSCALL_IDX,
1088 syscall_name, sc.arg1, sc.arg2, sc.arg3, sc.arg4);
1091 /* Handle SYS_exit here. */
1092 if (syscall_num == 1)
1094 sim_engine_halt (sd, MSP430_CPU (sd), NULL,
1095 MSP430_CPU (sd)->state.regs[0],
1096 sim_exited, sc.arg1);
1101 sc.p2 = MSP430_CPU (sd);
1102 sc.read_mem = syscall_read_mem;
1103 sc.write_mem = syscall_write_mem;
1105 cb_syscall (cb, &sc);
1107 if (TRACE_SYSCALL_P (MSP430_CPU (sd)))
1108 trace_generic (sd, MSP430_CPU (sd), TRACE_SYSCALL_IDX,
1109 "returns %ld", sc.result);
1111 MSP430_CPU (sd)->state.regs[12] = sc.result;
1119 msp430_step_once (SIM_DESC sd)
1121 Get_Byte_Local_Data ld;
1122 unsigned char buf[100];
1125 unsigned int opcode_pc;
1126 MSP430_Opcode_Decoded opcode_buf;
1127 MSP430_Opcode_Decoded *opcode = &opcode_buf;
1129 int u1, u2, uresult;
1135 int op_bytes, op_bits;
1140 if (opcode_pc < 0x10)
1142 fprintf (stderr, "Fault: PC(%#x) is less than 0x10\n", opcode_pc);
1143 sim_engine_halt (sd, MSP430_CPU (sd), NULL,
1144 MSP430_CPU (sd)->state.regs[0],
1149 if (PC == MSP430_CPU (sd)->state.cio_breakpoint
1150 && STATE_OPEN_KIND (sd) != SIM_OPEN_DEBUG)
1155 opsize = msp430_decode_opcode (MSP430_CPU (sd)->state.regs[0],
1156 opcode, msp430_getbyte, &ld);
1160 fprintf (stderr, "Fault: undecodable opcode at %#x\n", opcode_pc);
1161 sim_engine_halt (sd, MSP430_CPU (sd), NULL,
1162 MSP430_CPU (sd)->state.regs[0],
1167 if (opcode->repeat_reg)
1168 n_repeats = (MSP430_CPU (sd)->state.regs[opcode->repeats] & 0x000f) + 1;
1170 n_repeats = opcode->repeats + 1;
1172 op_bits = opcode->size;
1187 if (TRACE_INSN_P (MSP430_CPU (sd)))
1189 disassemble_info info;
1190 unsigned char b[10];
1192 msp430_trace_one (opcode_pc);
1194 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, b, opcode_pc, opsize);
1196 init_disassemble_info (&info, stderr, (fprintf_ftype) fprintf);
1197 info.private_data = sd;
1198 info.read_memory_func = msp430_dis_read;
1199 fprintf (stderr, "%#8x ", opcode_pc);
1200 for (i = 0; i < opsize; i += 2)
1201 fprintf (stderr, " %02x%02x", b[i+1], b[i]);
1202 for (; i < 6; i += 2)
1203 fprintf (stderr, " ");
1204 fprintf (stderr, " ");
1205 print_insn_msp430 (opcode_pc, &info);
1206 fprintf (stderr, "\n");
1210 if (TRACE_ANY_P (MSP430_CPU (sd)))
1211 trace_prefix (sd, MSP430_CPU (sd), NULL_CIA, opcode_pc,
1212 TRACE_LINENUM_P (MSP430_CPU (sd)), NULL, 0, "");
1220 /* Double-operand instructions. */
1222 if (opcode->n_bytes == 2
1223 && opcode->op[0].type == MSP430_Operand_Register
1224 && opcode->op[0].reg == MSR_CG
1225 && opcode->op[1].type == MSP430_Operand_Immediate
1226 && opcode->op[1].addend == 0
1227 /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK. */
1228 && opcode->size == 8)
1230 /* This is the designated software breakpoint instruction. */
1232 sim_engine_halt (sd, MSP430_CPU (sd), NULL,
1233 MSP430_CPU (sd)->state.regs[0],
1234 sim_stopped, SIM_SIGTRAP);
1239 /* Otherwise, do the move. */
1240 for (rept = 0; rept < n_repeats; rept ++)
1248 for (rept = 0; rept < n_repeats; rept ++)
1250 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
1255 uresult = u1 + u2 + carry_to_use;
1256 result = s1 + s2 + carry_to_use;
1257 if (TRACE_ALU_P (MSP430_CPU (sd)))
1258 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1259 "ADDC: %#x + %#x + %d = %#x",
1260 u1, u2, carry_to_use, uresult);
1262 FLAGS (result, uresult != ZX (uresult));
1267 for (rept = 0; rept < n_repeats; rept ++)
1275 if (TRACE_ALU_P (MSP430_CPU (sd)))
1276 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1277 "ADD: %#x + %#x = %#x",
1280 FLAGS (result, uresult != ZX (uresult));
1285 for (rept = 0; rept < n_repeats; rept ++)
1287 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
1292 uresult = ZX (~u2) + u1 + carry_to_use;
1293 result = s1 - s2 + (carry_to_use - 1);
1294 if (TRACE_ALU_P (MSP430_CPU (sd)))
1295 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1296 "SUBC: %#x - %#x + %d = %#x",
1297 u1, u2, carry_to_use, uresult);
1299 FLAGS (result, uresult != ZX (uresult));
1304 for (rept = 0; rept < n_repeats; rept ++)
1310 uresult = ZX (~u2) + u1 + 1;
1311 result = SX (uresult);
1312 if (TRACE_ALU_P (MSP430_CPU (sd)))
1313 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1314 "SUB: %#x - %#x = %#x",
1317 FLAGS (result, uresult != ZX (uresult));
1322 for (rept = 0; rept < n_repeats; rept ++)
1328 uresult = ZX (~u2) + u1 + 1;
1330 if (TRACE_ALU_P (MSP430_CPU (sd)))
1331 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1332 "CMP: %#x - %#x = %x",
1334 FLAGS (result, uresult != ZX (uresult));
1339 for (rept = 0; rept < n_repeats; rept ++)
1341 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
1344 uresult = bcd_to_binary (u1) + bcd_to_binary (u2) + carry_to_use;
1345 result = binary_to_bcd (uresult);
1346 if (TRACE_ALU_P (MSP430_CPU (sd)))
1347 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1348 "DADD: %#x + %#x + %d = %#x",
1349 u1, u2, carry_to_use, result);
1351 FLAGS (result, uresult > ((opcode->size == 8) ? 99 : 9999));
1356 for (rept = 0; rept < n_repeats; rept ++)
1361 if (TRACE_ALU_P (MSP430_CPU (sd)))
1362 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1363 "AND: %#x & %#x = %#x",
1366 FLAGS (uresult, uresult != 0);
1371 for (rept = 0; rept < n_repeats; rept ++)
1376 if (TRACE_ALU_P (MSP430_CPU (sd)))
1377 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1378 "BIT: %#x & %#x -> %#x",
1380 FLAGS (uresult, uresult != 0);
1385 for (rept = 0; rept < n_repeats; rept ++)
1389 uresult = u1 & ~ u2;
1390 if (TRACE_ALU_P (MSP430_CPU (sd)))
1391 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1392 "BIC: %#x & ~ %#x = %#x",
1399 for (rept = 0; rept < n_repeats; rept ++)
1404 if (TRACE_ALU_P (MSP430_CPU (sd)))
1405 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1406 "BIS: %#x | %#x = %#x",
1413 for (rept = 0; rept < n_repeats; rept ++)
1415 s1 = 1 << (opcode->size - 1);
1419 if (TRACE_ALU_P (MSP430_CPU (sd)))
1420 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1421 "XOR: %#x & %#x = %#x",
1424 FLAGSV (uresult, uresult != 0, (u1 & s1) && (u2 & s1));
1428 /* Single-operand instructions. Note: the decoder puts the same
1429 operand in SRC as in DEST, for our convenience. */
1432 for (rept = 0; rept < n_repeats; rept ++)
1435 carry_to_use = u1 & 1;
1437 if (SR & MSP430_FLAG_C)
1438 uresult |= (1 << (opcode->size - 1));
1439 if (TRACE_ALU_P (MSP430_CPU (sd)))
1440 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1444 FLAGS (uresult, carry_to_use);
1449 for (rept = 0; rept < n_repeats; rept ++)
1452 uresult = ((u1 >> 8) & 0x00ff) | ((u1 << 8) & 0xff00);
1453 if (TRACE_ALU_P (MSP430_CPU (sd)))
1454 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1462 for (rept = 0; rept < n_repeats; rept ++)
1466 s1 = 1 << (opcode->size - 1);
1467 uresult = (u1 >> 1) | (u1 & s1);
1468 if (TRACE_ALU_P (MSP430_CPU (sd)))
1469 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1478 for (rept = 0; rept < n_repeats; rept ++)
1482 uresult = (u1 >> 1);
1483 if (TRACE_ALU_P (MSP430_CPU (sd)))
1484 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1493 for (rept = 0; rept < n_repeats; rept ++)
1497 uresult = u1 | 0xfff00;
1499 uresult = u1 & 0x000ff;
1500 if (TRACE_ALU_P (MSP430_CPU (sd)))
1501 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1510 for (rept = 0; rept < n_repeats; rept ++)
1514 new_sp = REG_GET (MSR_SP) - op_bytes;
1515 /* SP is always word-aligned. */
1518 REG_PUT (MSR_SP, new_sp);
1520 mem_put_val (sd, SP, u1, op_bits);
1521 if (opcode->op[1].type == MSP430_Operand_Register)
1522 opcode->op[1].reg --;
1527 for (rept = 0; rept < n_repeats; rept ++)
1531 u1 = mem_get_val (sd, SP, op_bits);
1533 if (opcode->op[0].type == MSP430_Operand_Register)
1534 opcode->op[0].reg ++;
1535 new_sp = REG_GET (MSR_SP) + op_bytes;
1536 /* SP is always word-aligned. */
1539 REG_PUT (MSR_SP, new_sp);
1546 if (maybe_perform_syscall (sd, u1))
1549 REG_PUT (MSR_SP, REG_GET (MSR_SP) - op_bytes);
1550 mem_put_val (sd, SP, PC, op_bits);
1551 if (TRACE_ALU_P (MSP430_CPU (sd)))
1552 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1553 "CALL: func %#x ret %#x, sp %#x",
1555 REG_PUT (MSR_PC, u1);
1559 u1 = mem_get_val (sd, SP, 16);
1562 PC = mem_get_val (sd, SP, 16);
1564 /* Emulate the RETI action of the 20-bit CPUX architecure.
1565 This is safe for 16-bit CPU architectures as well, since the top
1566 8-bits of SR will have been written to the stack here, and will
1567 have been read as 0. */
1568 PC |= (u1 & 0xF000) << 4;
1569 if (TRACE_ALU_P (MSP430_CPU (sd)))
1570 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX,
1571 "RETI: pc %#x sr %#x",
1579 switch (opcode->cond)
1582 u1 = (SR & MSP430_FLAG_Z) ? 0 : 1;
1585 u1 = (SR & MSP430_FLAG_Z) ? 1 : 0;
1588 u1 = (SR & MSP430_FLAG_C) ? 0 : 1;
1591 u1 = (SR & MSP430_FLAG_C) ? 1 : 0;
1594 u1 = (SR & MSP430_FLAG_N) ? 1 : 0;
1597 u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 1 : 0;
1600 u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 0 : 1;
1609 if (TRACE_BRANCH_P (MSP430_CPU (sd)))
1610 trace_generic (sd, MSP430_CPU (sd), TRACE_BRANCH_IDX,
1611 "J%s: pc %#x -> %#x sr %#x, taken",
1612 cond_string (opcode->cond), PC, i, SR);
1614 if (PC == opcode_pc)
1618 if (TRACE_BRANCH_P (MSP430_CPU (sd)))
1619 trace_generic (sd, MSP430_CPU (sd), TRACE_BRANCH_IDX,
1620 "J%s: pc %#x to %#x sr %#x, not taken",
1621 cond_string (opcode->cond), PC, i, SR);
1625 fprintf (stderr, "error: unexpected opcode id %d\n", opcode->id);
1631 sim_engine_run (SIM_DESC sd,
1638 msp430_step_once (sd);
1639 if (sim_events_tick (sd))
1640 sim_events_process (sd);