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/>. */
30 #include "opcode/msp430-decode.h"
32 #include "sim-syscall.h"
34 #include "targ-vals.h"
38 loader_write_mem (SIM_DESC sd
,
40 const unsigned char *buf
,
43 SIM_CPU
*cpu
= MSP430_CPU (sd
);
44 return sim_core_write_buffer (sd
, cpu
, write_map
, buf
, taddr
, bytes
);
48 msp430_pc_fetch (SIM_CPU
*cpu
)
50 return cpu
->state
.regs
[0];
54 msp430_pc_store (SIM_CPU
*cpu
, sim_cia newpc
)
56 cpu
->state
.regs
[0] = newpc
;
60 lookup_symbol (SIM_DESC sd
, const char *name
)
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
);
67 if (symbol_table
== NULL
)
71 storage_needed
= bfd_get_symtab_upper_bound (abfd
);
72 if (storage_needed
<= 0)
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
);
80 for (i
= 0; i
< number_of_symbols
; i
++)
81 if (strcmp (symbol_table
[i
]->name
, name
) == 0)
83 long val
= symbol_table
[i
]->section
->vma
+ symbol_table
[i
]->value
;
90 msp430_reg_fetch (SIM_CPU
*cpu
, int regno
, unsigned char *buf
, int len
)
92 if (0 <= regno
&& regno
< 16)
96 int val
= cpu
->state
.regs
[regno
];
98 buf
[1] = (val
>> 8) & 0xff;
103 int val
= cpu
->state
.regs
[regno
];
105 buf
[1] = (val
>> 8) & 0xff;
106 buf
[2] = (val
>> 16) & 0x0f; /* Registers are only 20 bits wide. */
118 msp430_reg_store (SIM_CPU
*cpu
, int regno
, unsigned char *buf
, int len
)
120 if (0 <= regno
&& regno
< 16)
124 cpu
->state
.regs
[regno
] = (buf
[1] << 8) | buf
[0];
130 cpu
->state
.regs
[regno
] = ((buf
[2] << 16) & 0xf0000)
131 | (buf
[1] << 8) | buf
[0];
140 msp430_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
142 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
146 sim_open (SIM_OPEN_KIND kind
,
147 struct host_callback_struct
*callback
,
151 SIM_DESC sd
= sim_state_alloc (kind
, callback
);
153 struct bfd
*prog_bfd
;
155 /* Initialise the simulator. */
157 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
163 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
169 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
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
;
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. */
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
)
203 prog_bfd
= sim_load_file (sd
, argv
[0], callback
,
207 1 /* use LMA instead of VMA */,
209 /* Allow prog_bfd to be NULL - this is needed by the GDB testsuite. */
211 /* Establish any remaining configuration options. */
212 if (sim_config (sd
) != SIM_RC_OK
)
218 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
224 /* CPU specific initialization. */
225 assert (MAX_NR_PROCESSORS
== 1);
226 msp430_initialize_cpu (sd
, MSP430_CPU (sd
));
228 msp430_trace_init (STATE_PROG_BFD (sd
));
230 if (prog_bfd
!= NULL
)
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_");
242 sim_close (SIM_DESC sd
,
245 free (STATE_SYMBOL_TABLE (sd
));
250 sim_create_inferior (SIM_DESC sd
,
255 unsigned char resetv
[2];
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];
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
);
267 sim_pc_set (MSP430_CPU (sd
), new_pc
);
268 msp430_pc_store (MSP430_CPU (sd
), new_pc
);
277 } Get_Byte_Local_Data
;
280 msp430_getbyte (void *vld
)
282 Get_Byte_Local_Data
*ld
= (Get_Byte_Local_Data
*)vld
;
284 SIM_DESC sd
= ld
->sd
;
286 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, ld
->gb_addr
, 1);
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)
299 "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8",
300 "R9", "R10", "R11", "R12", "R13", "R14", "R15"
304 trace_reg_put (SIM_DESC sd
, int n
, unsigned int v
)
306 TRACE_REGISTER (MSP430_CPU (sd
), "PUT: %#x -> %s", v
, register_names
[n
]);
311 trace_reg_get (SIM_DESC sd
, int n
)
313 TRACE_REGISTER (MSP430_CPU (sd
), "GET: %s -> %#x", register_names
[n
], REG (n
));
317 #define REG_PUT(N,V) trace_reg_put (sd, N, V)
318 #define REG_GET(N) trace_reg_get (sd, N)
320 /* Hardware multiply (and accumulate) support. */
323 zero_ext (unsigned int v
, unsigned int bits
)
325 v
&= ((1 << bits
) - 1);
329 static signed long long
330 sign_ext (signed long long v
, unsigned int bits
)
332 signed long long sb
= 1LL << (bits
-1); /* Sign bit. */
333 signed long long mb
= (1LL << (bits
-1)) - 1LL; /* Mantissa bits. */
343 get_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
)
345 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
348 unsigned char buf
[4];
353 case MSP430_Operand_Immediate
:
356 case MSP430_Operand_Register
:
357 rv
= REG_GET (op
->reg
);
359 case MSP430_Operand_Indirect
:
360 case MSP430_Operand_Indirect_Postinc
:
362 if (op
->reg
!= MSR_None
)
364 int reg
= REG_GET (op
->reg
);
365 int sign
= opc
->ofs_430x
? 20 : 16;
367 /* Index values are signed. */
368 if (addr
& (1 << (sign
- 1)))
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
)
379 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on read\n", addr
);
388 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 1);
392 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 2);
393 rv
= buf
[0] | (buf
[1] << 8);
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);
401 assert (! opc
->size
);
405 /* Hack - MSP430X5438 serial port status register. */
409 if (addr
>= 0x130 && addr
<= 0x15B)
414 switch (HWMULT (sd
, hwmult_type
))
418 rv
= zero_ext (HWMULT (sd
, hwmult_result
), 16);
422 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
), 16);
428 switch (HWMULT (sd
, hwmult_type
))
432 rv
= zero_ext (HWMULT (sd
, hwmult_result
) >> 16, 16);
437 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
) >> 16, 16);
443 switch (HWMULT (sd
, hwmult_type
))
449 rv
= HWMULT (sd
, hwmult_signed_result
) < 0 ? -1 : 0;
452 rv
= 0; /* FIXME: Should be carry of last accumulate. */
455 rv
= HWMULT (sd
, hwmult_signed_accumulator
) < 0 ? -1 : 0;
461 rv
= zero_ext (HWMULT (sd
, hw32mult_result
), 16);
465 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 16, 16);
469 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 32, 16);
473 switch (HWMULT (sd
, hw32mult_type
))
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;
481 fprintf (stderr
, "unimplemented HW MULT read from %x!\n", addr
);
486 TRACE_MEMORY (MSP430_CPU (sd
), "GET: [%#x].%d -> %#x", addr
, opc
->size
,
491 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
515 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
516 REG_PUT (op
->reg
, REG_GET (op
->reg
) + incval
);
522 put_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
, int val
)
524 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
527 unsigned char buf
[4];
548 case MSP430_Operand_Register
:
550 REG_PUT (op
->reg
, val
);
552 case MSP430_Operand_Indirect
:
553 case MSP430_Operand_Indirect_Postinc
:
555 if (op
->reg
!= MSR_None
)
557 int reg
= REG_GET (op
->reg
);
558 int sign
= opc
->ofs_430x
? 20 : 16;
560 /* Index values are signed. */
561 if (addr
& (1 << (sign
- 1)))
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
)
572 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on write\n", addr
);
579 TRACE_MEMORY (MSP430_CPU (sd
), "PUT: [%#x].%d <- %#x", addr
, opc
->size
,
582 /* Hack - MSP430X5438 serial port transmit register. */
586 if (addr
>= 0x130 && addr
<= 0x15B)
590 /* Hardware Multiply emulation. */
591 assert (opc
->size
== 16);
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;
600 case 0x138: HWMULT (sd
, hwmult_op2
) = val
;
601 switch (HWMULT (sd
, hwmult_type
))
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;
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;
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
);
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
);
636 /* Copy into LOW result... */
637 switch (HWMULT (sd
, hwmult_type
))
641 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_result
) = zero_ext (val
, 16);
642 HWMULT (sd
, hwmult_signed_accumulator
) = sign_ext (val
, 16);
646 HWMULT (sd
, hwmult_signed_accumulator
) = HWMULT (sd
, hwmult_result
) = sign_ext (val
, 16);
647 HWMULT (sd
, hwmult_accumulator
) = zero_ext (val
, 16);
653 HWMULT (sd
, hw32mult_op1
) = val
;
654 HWMULT (sd
, hw32mult_type
) = UNSIGN_64
;
657 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
660 HWMULT (sd
, hw32mult_op1
) = val
;
661 HWMULT (sd
, hw32mult_type
) = SIGN_64
;
664 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
667 HWMULT (sd
, hw32mult_op2
) = val
;
671 HWMULT (sd
, hw32mult_op2
) = (HWMULT (sd
, hw32mult_op2
) & 0xFFFF) | (val
<< 16);
672 switch (HWMULT (sd
, hw32mult_type
))
675 HWMULT (sd
, hw32mult_result
) = HWMULT (sd
, hw32mult_op1
) * HWMULT (sd
, hw32mult_op2
);
678 HWMULT (sd
, hw32mult_result
) = sign_ext (HWMULT (sd
, hw32mult_op1
), 32)
679 * sign_ext (HWMULT (sd
, hw32mult_op2
), 32);
685 fprintf (stderr
, "unimplemented HW MULT write to %x!\n", addr
);
694 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 1);
699 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 2);
707 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 4);
710 assert (! opc
->size
);
715 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
739 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
741 int new_val
= REG_GET (op
->reg
) + incval
;
742 /* SP is always word-aligned. */
743 if (op
->reg
== MSR_SP
&& (new_val
& 1))
745 REG_PUT (op
->reg
, new_val
);
752 mem_put_val (SIM_DESC sd
, int addr
, int val
, int bits
)
754 MSP430_Opcode_Decoded opc
;
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
);
764 mem_get_val (SIM_DESC sd
, int addr
, int bits
)
766 MSP430_Opcode_Decoded opc
;
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);
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)
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)
792 msp430_cio (SIM_DESC sd
)
794 /* A block of data at __CIOBUF__ describes the I/O operation to
797 unsigned char raw_parms
[13];
798 unsigned char parms
[8];
801 unsigned char buffer
[512];
803 long fd
, addr
, len
, rv
;
805 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
806 MSP430_CPU (sd
)->state
.cio_buffer
, 5);
810 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
811 MSP430_CPU (sd
)->state
.cio_buffer
+ 3, 8);
813 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
814 MSP430_CPU (sd
)->state
.cio_buffer
+ 11, length
);
822 rv
= write (fd
, buffer
, len
);
823 parms
[0] = rv
& 0xff;
829 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
830 MSP430_CPU (sd
)->state
.cio_buffer
+ 4, 8);
832 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
833 MSP430_CPU (sd
)->state
.cio_buffer
+ 12, ret_buflen
);
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))
841 msp430_dis_read (bfd_vma memaddr
,
844 struct disassemble_info
*dinfo
)
846 SIM_DESC sd
= dinfo
->private_data
;
847 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, myaddr
, memaddr
, length
);
851 #define DO_ALU(OP,SOP,MORE) \
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); \
861 #define SIGN (1 << (opcode->size - 1))
862 #define POS(x) (((x) & SIGN) ? 0 : 1)
863 #define NEG(x) (((x) & SIGN) ? 1 : 0)
865 #define SX(v) sign_ext (v, opcode->size)
866 #define ZX(v) zero_ext (v, opcode->size)
871 static char buf
[2][6];
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' : '-';
885 /* Random number that won't show up in our usual logic. */
886 #define MAGIC_OVERFLOW 0x55000F
889 do_flags (SIM_DESC sd
,
890 MSP430_Opcode_Decoded
*opcode
,
891 int vnz_val
, /* Signed result. */
897 int signbit
= 1 << (opcode
->size
- 1);
899 f
&= ~opcode
->flags_0
;
900 f
&= ~opcode
->flags_set
;
901 f
|= opcode
->flags_1
;
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
)
909 if (vnz_val
!= SX (vnz_val
))
910 new_f
|= MSP430_FLAG_V
;
914 new_f
|= MSP430_FLAG_V
;
916 new_f
|= MSP430_FLAG_C
;
918 new_f
= f
| (new_f
& opcode
->flags_set
);
920 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s -> %s", flags2string (SR
),
921 flags2string (new_f
));
923 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s", flags2string (new_f
));
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)
930 /* These two assume unsigned 16-bit (four digit) words.
931 Mask off unwanted bits for byte operations. */
934 bcd_to_binary (int v
)
936 int r
= ( ((v
>> 0) & 0xf) * 1
937 + ((v
>> 4) & 0xf) * 10
938 + ((v
>> 8) & 0xf) * 100
939 + ((v
>> 12) & 0xf) * 1000);
944 binary_to_bcd (int v
)
946 int r
= ( ((v
/ 1) % 10) << 0
947 | ((v
/ 10) % 10) << 4
948 | ((v
/ 100) % 10) << 8
949 | ((v
/ 1000) % 10) << 12);
954 cond_string (int cond
)
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. */
984 maybe_perform_syscall (SIM_DESC sd
, int call_addr
)
986 if (call_addr
== 0x00160)
990 for (i
= 0; i
< 16; i
++)
993 fprintf (stderr
, "\t");
994 fprintf (stderr
, "R%-2d %05x ", i
, MSP430_CPU (sd
)->state
.regs
[i
]);
997 int sp
= SP
+ (3 - (i
/ 4)) * 2;
998 unsigned char buf
[2];
1000 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, sp
, 2);
1002 fprintf (stderr
, "\tSP%+d: %04x", sp
- SP
,
1003 buf
[0] + buf
[1] * 256);
1009 fprintf (stderr
, flags
& 0x100 ? " V" : " -");
1010 fprintf (stderr
, flags
& 0x004 ? "N" : "-");
1011 fprintf (stderr
, flags
& 0x002 ? "Z" : "-");
1012 fprintf (stderr
, flags
& 0x001 ? "C" : "-");
1015 fprintf (stderr
, "\n");
1021 if ((call_addr
& ~0x3f) == 0x00180)
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];
1030 MSP430_CPU (sd
)->state
.regs
[12] = sim_syscall (MSP430_CPU (sd
),
1031 syscall_num
, arg1
, arg2
,
1040 msp430_step_once (SIM_DESC sd
)
1042 Get_Byte_Local_Data ld
;
1043 unsigned char buf
[100];
1046 unsigned int opcode_pc
;
1047 MSP430_Opcode_Decoded opcode_buf
;
1048 MSP430_Opcode_Decoded
*opcode
= &opcode_buf
;
1050 int u1
, u2
, uresult
;
1056 int op_bytes
, op_bits
;
1061 if (opcode_pc
< 0x10)
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],
1070 if (PC
== MSP430_CPU (sd
)->state
.cio_breakpoint
1071 && STATE_OPEN_KIND (sd
) != SIM_OPEN_DEBUG
)
1076 opsize
= msp430_decode_opcode (MSP430_CPU (sd
)->state
.regs
[0],
1077 opcode
, msp430_getbyte
, &ld
);
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],
1088 if (opcode
->repeat_reg
)
1089 n_repeats
= (MSP430_CPU (sd
)->state
.regs
[opcode
->repeats
] & 0x000f) + 1;
1091 n_repeats
= opcode
->repeats
+ 1;
1093 op_bits
= opcode
->size
;
1108 if (TRACE_INSN_P (MSP430_CPU (sd
)))
1110 disassemble_info info
;
1111 unsigned char b
[10];
1113 msp430_trace_one (opcode_pc
);
1115 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, b
, opcode_pc
, opsize
);
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");
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, "");
1141 /* Double-operand instructions. */
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)
1151 /* This is the designated software breakpoint instruction. */
1153 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1154 MSP430_CPU (sd
)->state
.regs
[0],
1155 sim_stopped
, SIM_SIGTRAP
);
1160 /* Otherwise, do the move. */
1161 for (rept
= 0; rept
< n_repeats
; rept
++)
1169 for (rept
= 0; rept
< n_repeats
; rept
++)
1171 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
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
);
1181 FLAGS (result
, uresult
!= ZX (uresult
));
1186 for (rept
= 0; rept
< n_repeats
; rept
++)
1194 TRACE_ALU (MSP430_CPU (sd
), "ADD: %#x + %#x = %#x",
1197 FLAGS (result
, uresult
!= ZX (uresult
));
1202 for (rept
= 0; rept
< n_repeats
; rept
++)
1204 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
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
);
1214 FLAGS (result
, uresult
!= ZX (uresult
));
1219 for (rept
= 0; rept
< n_repeats
; rept
++)
1225 uresult
= ZX (~u2
) + u1
+ 1;
1226 result
= SX (uresult
);
1227 TRACE_ALU (MSP430_CPU (sd
), "SUB: %#x - %#x = %#x",
1230 FLAGS (result
, uresult
!= ZX (uresult
));
1235 for (rept
= 0; rept
< n_repeats
; rept
++)
1241 uresult
= ZX (~u2
) + u1
+ 1;
1243 TRACE_ALU (MSP430_CPU (sd
), "CMP: %#x - %#x = %x",
1245 FLAGS (result
, uresult
!= ZX (uresult
));
1250 for (rept
= 0; rept
< n_repeats
; rept
++)
1252 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
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
);
1260 FLAGS (result
, uresult
> ((opcode
->size
== 8) ? 99 : 9999));
1265 for (rept
= 0; rept
< n_repeats
; rept
++)
1270 TRACE_ALU (MSP430_CPU (sd
), "AND: %#x & %#x = %#x",
1273 FLAGS (uresult
, uresult
!= 0);
1278 for (rept
= 0; rept
< n_repeats
; rept
++)
1283 TRACE_ALU (MSP430_CPU (sd
), "BIT: %#x & %#x -> %#x",
1285 FLAGS (uresult
, uresult
!= 0);
1290 for (rept
= 0; rept
< n_repeats
; rept
++)
1294 uresult
= u1
& ~ u2
;
1295 TRACE_ALU (MSP430_CPU (sd
), "BIC: %#x & ~ %#x = %#x",
1302 for (rept
= 0; rept
< n_repeats
; rept
++)
1307 TRACE_ALU (MSP430_CPU (sd
), "BIS: %#x | %#x = %#x",
1314 for (rept
= 0; rept
< n_repeats
; rept
++)
1316 s1
= 1 << (opcode
->size
- 1);
1320 TRACE_ALU (MSP430_CPU (sd
), "XOR: %#x & %#x = %#x",
1323 FLAGSV (uresult
, uresult
!= 0, (u1
& s1
) && (u2
& s1
));
1327 /* Single-operand instructions. Note: the decoder puts the same
1328 operand in SRC as in DEST, for our convenience. */
1331 for (rept
= 0; rept
< n_repeats
; rept
++)
1334 carry_to_use
= u1
& 1;
1336 if (SR
& MSP430_FLAG_C
)
1337 uresult
|= (1 << (opcode
->size
- 1));
1338 TRACE_ALU (MSP430_CPU (sd
), "RRC: %#x >>= %#x",
1341 FLAGS (uresult
, carry_to_use
);
1346 for (rept
= 0; rept
< n_repeats
; rept
++)
1349 uresult
= ((u1
>> 8) & 0x00ff) | ((u1
<< 8) & 0xff00);
1350 TRACE_ALU (MSP430_CPU (sd
), "SWPB: %#x -> %#x",
1357 for (rept
= 0; rept
< n_repeats
; rept
++)
1361 s1
= 1 << (opcode
->size
- 1);
1362 uresult
= (u1
>> 1) | (u1
& s1
);
1363 TRACE_ALU (MSP430_CPU (sd
), "RRA: %#x >>= %#x",
1371 for (rept
= 0; rept
< n_repeats
; rept
++)
1375 uresult
= (u1
>> 1);
1376 TRACE_ALU (MSP430_CPU (sd
), "RRU: %#x >>= %#x",
1384 for (rept
= 0; rept
< n_repeats
; rept
++)
1388 uresult
= u1
| 0xfff00;
1390 uresult
= u1
& 0x000ff;
1391 TRACE_ALU (MSP430_CPU (sd
), "SXT: %#x -> %#x",
1399 for (rept
= 0; rept
< n_repeats
; rept
++)
1403 new_sp
= REG_GET (MSR_SP
) - op_bytes
;
1404 /* SP is always word-aligned. */
1407 REG_PUT (MSR_SP
, new_sp
);
1409 mem_put_val (sd
, SP
, u1
, op_bits
);
1410 if (opcode
->op
[1].type
== MSP430_Operand_Register
)
1411 opcode
->op
[1].reg
--;
1416 for (rept
= 0; rept
< n_repeats
; rept
++)
1420 u1
= mem_get_val (sd
, SP
, op_bits
);
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. */
1428 REG_PUT (MSR_SP
, new_sp
);
1435 if (maybe_perform_syscall (sd
, u1
))
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",
1442 REG_PUT (MSR_PC
, u1
);
1446 u1
= mem_get_val (sd
, SP
, 16);
1449 PC
= mem_get_val (sd
, SP
, 16);
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",
1464 switch (opcode
->cond
)
1467 u1
= (SR
& MSP430_FLAG_Z
) ? 0 : 1;
1470 u1
= (SR
& MSP430_FLAG_Z
) ? 1 : 0;
1473 u1
= (SR
& MSP430_FLAG_C
) ? 0 : 1;
1476 u1
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1479 u1
= (SR
& MSP430_FLAG_N
) ? 1 : 0;
1482 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 1 : 0;
1485 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 0 : 1;
1494 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x -> %#x sr %#x, taken",
1495 cond_string (opcode
->cond
), PC
, i
, SR
);
1497 if (PC
== opcode_pc
)
1501 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x to %#x sr %#x, not taken",
1502 cond_string (opcode
->cond
), PC
, i
, SR
);
1506 fprintf (stderr
, "error: unexpected opcode id %d\n", opcode
->id
);
1512 sim_engine_run (SIM_DESC sd
,
1519 msp430_step_once (sd
);
1520 if (sim_events_tick (sd
))
1521 sim_events_process (sd
);