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 msp430_sim_close (SIM_DESC sd
, int quitting
)
244 free (STATE_SYMBOL_TABLE (sd
));
248 sim_create_inferior (SIM_DESC sd
,
253 unsigned char resetv
[2];
257 /* Set the PC to the default reset vector if available. */
258 c
= sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, resetv
, 0xfffe, 2);
259 new_pc
= resetv
[0] + 256 * resetv
[1];
261 /* If the reset vector isn't initialized, then use the ELF entry. */
262 if (abfd
!= NULL
&& !new_pc
)
263 new_pc
= bfd_get_start_address (abfd
);
265 sim_pc_set (MSP430_CPU (sd
), new_pc
);
266 msp430_pc_store (MSP430_CPU (sd
), new_pc
);
275 } Get_Byte_Local_Data
;
278 msp430_getbyte (void *vld
)
280 Get_Byte_Local_Data
*ld
= (Get_Byte_Local_Data
*)vld
;
282 SIM_DESC sd
= ld
->sd
;
284 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, ld
->gb_addr
, 1);
289 #define REG(N) MSP430_CPU (sd)->state.regs[(N)]
290 #define PC REG(MSR_PC)
291 #define SP REG(MSR_SP)
292 #define SR REG(MSR_SR)
297 "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8",
298 "R9", "R10", "R11", "R12", "R13", "R14", "R15"
302 trace_reg_put (SIM_DESC sd
, int n
, unsigned int v
)
304 TRACE_REGISTER (MSP430_CPU (sd
), "PUT: %#x -> %s", v
, register_names
[n
]);
309 trace_reg_get (SIM_DESC sd
, int n
)
311 TRACE_REGISTER (MSP430_CPU (sd
), "GET: %s -> %#x", register_names
[n
], REG (n
));
315 #define REG_PUT(N,V) trace_reg_put (sd, N, V)
316 #define REG_GET(N) trace_reg_get (sd, N)
318 /* Hardware multiply (and accumulate) support. */
321 zero_ext (unsigned int v
, unsigned int bits
)
323 v
&= ((1 << bits
) - 1);
327 static signed long long
328 sign_ext (signed long long v
, unsigned int bits
)
330 signed long long sb
= 1LL << (bits
-1); /* Sign bit. */
331 signed long long mb
= (1LL << (bits
-1)) - 1LL; /* Mantissa bits. */
341 get_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
)
343 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
346 unsigned char buf
[4];
351 case MSP430_Operand_Immediate
:
354 case MSP430_Operand_Register
:
355 rv
= REG_GET (op
->reg
);
357 case MSP430_Operand_Indirect
:
358 case MSP430_Operand_Indirect_Postinc
:
360 if (op
->reg
!= MSR_None
)
362 int reg
= REG_GET (op
->reg
);
363 int sign
= opc
->ofs_430x
? 20 : 16;
365 /* Index values are signed. */
366 if (addr
& (1 << (sign
- 1)))
371 /* For MSP430 instructions the sum is limited to 16 bits if the
372 address in the index register is less than 64k even if we are
373 running on an MSP430X CPU. This is for MSP430 compatibility. */
374 if (reg
< 0x10000 && ! opc
->ofs_430x
)
377 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on read\n", addr
);
386 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 1);
390 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 2);
391 rv
= buf
[0] | (buf
[1] << 8);
395 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 4);
396 rv
= buf
[0] | (buf
[1] << 8) | (buf
[2] << 16) | (buf
[3] << 24);
399 assert (! opc
->size
);
403 /* Hack - MSP430X5438 serial port status register. */
407 if (addr
>= 0x130 && addr
<= 0x15B)
412 switch (HWMULT (sd
, hwmult_type
))
416 rv
= zero_ext (HWMULT (sd
, hwmult_result
), 16);
420 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
), 16);
426 switch (HWMULT (sd
, hwmult_type
))
430 rv
= zero_ext (HWMULT (sd
, hwmult_result
) >> 16, 16);
435 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
) >> 16, 16);
441 switch (HWMULT (sd
, hwmult_type
))
447 rv
= HWMULT (sd
, hwmult_signed_result
) < 0 ? -1 : 0;
450 rv
= 0; /* FIXME: Should be carry of last accumulate. */
453 rv
= HWMULT (sd
, hwmult_signed_accumulator
) < 0 ? -1 : 0;
459 rv
= zero_ext (HWMULT (sd
, hw32mult_result
), 16);
463 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 16, 16);
467 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 32, 16);
471 switch (HWMULT (sd
, hw32mult_type
))
473 case UNSIGN_64
: rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 48, 16); break;
474 case SIGN_64
: rv
= sign_ext (HWMULT (sd
, hw32mult_result
) >> 48, 16); break;
479 fprintf (stderr
, "unimplemented HW MULT read from %x!\n", addr
);
484 TRACE_MEMORY (MSP430_CPU (sd
), "GET: [%#x].%d -> %#x", addr
, opc
->size
,
489 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
513 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
514 REG_PUT (op
->reg
, REG_GET (op
->reg
) + incval
);
520 put_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
, int val
)
522 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
525 unsigned char buf
[4];
546 case MSP430_Operand_Register
:
548 REG_PUT (op
->reg
, val
);
550 case MSP430_Operand_Indirect
:
551 case MSP430_Operand_Indirect_Postinc
:
553 if (op
->reg
!= MSR_None
)
555 int reg
= REG_GET (op
->reg
);
556 int sign
= opc
->ofs_430x
? 20 : 16;
558 /* Index values are signed. */
559 if (addr
& (1 << (sign
- 1)))
564 /* For MSP430 instructions the sum is limited to 16 bits if the
565 address in the index register is less than 64k even if we are
566 running on an MSP430X CPU. This is for MSP430 compatibility. */
567 if (reg
< 0x10000 && ! opc
->ofs_430x
)
570 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on write\n", addr
);
577 TRACE_MEMORY (MSP430_CPU (sd
), "PUT: [%#x].%d <- %#x", addr
, opc
->size
,
580 /* Hack - MSP430X5438 serial port transmit register. */
584 if (addr
>= 0x130 && addr
<= 0x15B)
588 /* Hardware Multiply emulation. */
589 assert (opc
->size
== 16);
593 case 0x130: HWMULT (sd
, hwmult_op1
) = val
; HWMULT (sd
, hwmult_type
) = UNSIGN_32
; break;
594 case 0x132: HWMULT (sd
, hwmult_op1
) = val
; HWMULT (sd
, hwmult_type
) = SIGN_32
; break;
595 case 0x134: HWMULT (sd
, hwmult_op1
) = val
; HWMULT (sd
, hwmult_type
) = UNSIGN_MAC_32
; break;
596 case 0x136: HWMULT (sd
, hwmult_op1
) = val
; HWMULT (sd
, hwmult_type
) = SIGN_MAC_32
; break;
598 case 0x138: HWMULT (sd
, hwmult_op2
) = val
;
599 switch (HWMULT (sd
, hwmult_type
))
602 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
603 HWMULT (sd
, hwmult_signed_result
) = (signed) HWMULT (sd
, hwmult_result
);
604 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
608 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
609 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
610 HWMULT (sd
, hwmult_signed_result
) = a
* b
;
611 HWMULT (sd
, hwmult_result
) = (unsigned) HWMULT (sd
, hwmult_signed_result
);
612 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
616 HWMULT (sd
, hwmult_accumulator
) += HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
617 HWMULT (sd
, hwmult_signed_accumulator
) += HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
618 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
619 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
623 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
624 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
625 HWMULT (sd
, hwmult_accumulator
) += a
* b
;
626 HWMULT (sd
, hwmult_signed_accumulator
) += a
* b
;
627 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
628 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
634 /* Copy into LOW result... */
635 switch (HWMULT (sd
, hwmult_type
))
639 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_result
) = zero_ext (val
, 16);
640 HWMULT (sd
, hwmult_signed_accumulator
) = sign_ext (val
, 16);
644 HWMULT (sd
, hwmult_signed_accumulator
) = HWMULT (sd
, hwmult_result
) = sign_ext (val
, 16);
645 HWMULT (sd
, hwmult_accumulator
) = zero_ext (val
, 16);
651 HWMULT (sd
, hw32mult_op1
) = val
;
652 HWMULT (sd
, hw32mult_type
) = UNSIGN_64
;
655 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
658 HWMULT (sd
, hw32mult_op1
) = val
;
659 HWMULT (sd
, hw32mult_type
) = SIGN_64
;
662 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
665 HWMULT (sd
, hw32mult_op2
) = val
;
669 HWMULT (sd
, hw32mult_op2
) = (HWMULT (sd
, hw32mult_op2
) & 0xFFFF) | (val
<< 16);
670 switch (HWMULT (sd
, hw32mult_type
))
673 HWMULT (sd
, hw32mult_result
) = HWMULT (sd
, hw32mult_op1
) * HWMULT (sd
, hw32mult_op2
);
676 HWMULT (sd
, hw32mult_result
) = sign_ext (HWMULT (sd
, hw32mult_op1
), 32)
677 * sign_ext (HWMULT (sd
, hw32mult_op2
), 32);
683 fprintf (stderr
, "unimplemented HW MULT write to %x!\n", addr
);
692 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 1);
697 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 2);
705 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 4);
708 assert (! opc
->size
);
713 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
737 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
739 int new_val
= REG_GET (op
->reg
) + incval
;
740 /* SP is always word-aligned. */
741 if (op
->reg
== MSR_SP
&& (new_val
& 1))
743 REG_PUT (op
->reg
, new_val
);
750 mem_put_val (SIM_DESC sd
, int addr
, int val
, int bits
)
752 MSP430_Opcode_Decoded opc
;
755 opc
.op
[0].type
= MSP430_Operand_Indirect
;
756 opc
.op
[0].addend
= addr
;
757 opc
.op
[0].reg
= MSR_None
;
758 put_op (sd
, &opc
, 0, val
);
762 mem_get_val (SIM_DESC sd
, int addr
, int bits
)
764 MSP430_Opcode_Decoded opc
;
767 opc
.op
[0].type
= MSP430_Operand_Indirect
;
768 opc
.op
[0].addend
= addr
;
769 opc
.op
[0].reg
= MSR_None
;
770 return get_op (sd
, &opc
, 0);
773 #define CIO_OPEN (0xF0)
774 #define CIO_CLOSE (0xF1)
775 #define CIO_READ (0xF2)
776 #define CIO_WRITE (0xF3)
777 #define CIO_LSEEK (0xF4)
778 #define CIO_UNLINK (0xF5)
779 #define CIO_GETENV (0xF6)
780 #define CIO_RENAME (0xF7)
781 #define CIO_GETTIME (0xF8)
782 #define CIO_GETCLK (0xF9)
783 #define CIO_SYNC (0xFF)
785 #define CIO_I(n) (parms[(n)] + parms[(n)+1] * 256)
786 #define CIO_L(n) (parms[(n)] + parms[(n)+1] * 256 \
787 + parms[(n)+2] * 65536 + parms[(n)+3] * 16777216)
790 msp430_cio (SIM_DESC sd
)
792 /* A block of data at __CIOBUF__ describes the I/O operation to
795 unsigned char raw_parms
[13];
796 unsigned char parms
[8];
799 unsigned char buffer
[512];
801 long fd
, addr
, len
, rv
;
803 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
804 MSP430_CPU (sd
)->state
.cio_buffer
, 5);
808 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
809 MSP430_CPU (sd
)->state
.cio_buffer
+ 3, 8);
811 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
812 MSP430_CPU (sd
)->state
.cio_buffer
+ 11, length
);
820 rv
= write (fd
, buffer
, len
);
821 parms
[0] = rv
& 0xff;
827 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
828 MSP430_CPU (sd
)->state
.cio_buffer
+ 4, 8);
830 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
831 MSP430_CPU (sd
)->state
.cio_buffer
+ 12, ret_buflen
);
834 #define SRC get_op (sd, opcode, 1)
835 #define DSRC get_op (sd, opcode, 0)
836 #define DEST(V) put_op (sd, opcode, 0, (V))
839 msp430_dis_read (bfd_vma memaddr
,
842 struct disassemble_info
*dinfo
)
844 SIM_DESC sd
= dinfo
->private_data
;
845 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, myaddr
, memaddr
, length
);
849 #define DO_ALU(OP,SOP,MORE) \
853 int result = s1 OP s2 MORE; \
854 TRACE_ALU (MSP430_CPU (sd), "ALU: %#x %s %#x %s = %#x", s1, SOP, \
855 s2, #MORE, result); \
859 #define SIGN (1 << (opcode->size - 1))
860 #define POS(x) (((x) & SIGN) ? 0 : 1)
861 #define NEG(x) (((x) & SIGN) ? 1 : 0)
863 #define SX(v) sign_ext (v, opcode->size)
864 #define ZX(v) zero_ext (v, opcode->size)
869 static char buf
[2][6];
875 bp
[0] = f
& MSP430_FLAG_V
? 'V' : '-';
876 bp
[1] = f
& MSP430_FLAG_N
? 'N' : '-';
877 bp
[2] = f
& MSP430_FLAG_Z
? 'Z' : '-';
878 bp
[3] = f
& MSP430_FLAG_C
? 'C' : '-';
883 /* Random number that won't show up in our usual logic. */
884 #define MAGIC_OVERFLOW 0x55000F
887 do_flags (SIM_DESC sd
,
888 MSP430_Opcode_Decoded
*opcode
,
889 int vnz_val
, /* Signed result. */
895 int signbit
= 1 << (opcode
->size
- 1);
897 f
&= ~opcode
->flags_0
;
898 f
&= ~opcode
->flags_set
;
899 f
|= opcode
->flags_1
;
901 if (vnz_val
& signbit
)
902 new_f
|= MSP430_FLAG_N
;
903 if (! (vnz_val
& ((signbit
<< 1) - 1)))
904 new_f
|= MSP430_FLAG_Z
;
905 if (overflow
== MAGIC_OVERFLOW
)
907 if (vnz_val
!= SX (vnz_val
))
908 new_f
|= MSP430_FLAG_V
;
912 new_f
|= MSP430_FLAG_V
;
914 new_f
|= MSP430_FLAG_C
;
916 new_f
= f
| (new_f
& opcode
->flags_set
);
918 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s -> %s", flags2string (SR
),
919 flags2string (new_f
));
921 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s", flags2string (new_f
));
925 #define FLAGS(vnz,c) do_flags (sd, opcode, vnz, c, MAGIC_OVERFLOW)
926 #define FLAGSV(vnz,c,v) do_flags (sd, opcode, vnz, c, v)
928 /* These two assume unsigned 16-bit (four digit) words.
929 Mask off unwanted bits for byte operations. */
932 bcd_to_binary (int v
)
934 int r
= ( ((v
>> 0) & 0xf) * 1
935 + ((v
>> 4) & 0xf) * 10
936 + ((v
>> 8) & 0xf) * 100
937 + ((v
>> 12) & 0xf) * 1000);
942 binary_to_bcd (int v
)
944 int r
= ( ((v
/ 1) % 10) << 0
945 | ((v
/ 10) % 10) << 4
946 | ((v
/ 100) % 10) << 8
947 | ((v
/ 1000) % 10) << 12);
952 cond_string (int cond
)
977 /* Checks a CALL to address CALL_ADDR. If this is a special
978 syscall address then the call is simulated and non-zero is
979 returned. Otherwise 0 is returned. */
982 maybe_perform_syscall (SIM_DESC sd
, int call_addr
)
984 if (call_addr
== 0x00160)
988 for (i
= 0; i
< 16; i
++)
991 fprintf (stderr
, "\t");
992 fprintf (stderr
, "R%-2d %05x ", i
, MSP430_CPU (sd
)->state
.regs
[i
]);
995 int sp
= SP
+ (3 - (i
/ 4)) * 2;
996 unsigned char buf
[2];
998 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, sp
, 2);
1000 fprintf (stderr
, "\tSP%+d: %04x", sp
- SP
,
1001 buf
[0] + buf
[1] * 256);
1007 fprintf (stderr
, flags
& 0x100 ? " V" : " -");
1008 fprintf (stderr
, flags
& 0x004 ? "N" : "-");
1009 fprintf (stderr
, flags
& 0x002 ? "Z" : "-");
1010 fprintf (stderr
, flags
& 0x001 ? "C" : "-");
1013 fprintf (stderr
, "\n");
1019 if ((call_addr
& ~0x3f) == 0x00180)
1022 int syscall_num
= call_addr
& 0x3f;
1023 int arg1
= MSP430_CPU (sd
)->state
.regs
[12];
1024 int arg2
= MSP430_CPU (sd
)->state
.regs
[13];
1025 int arg3
= MSP430_CPU (sd
)->state
.regs
[14];
1026 int arg4
= MSP430_CPU (sd
)->state
.regs
[15];
1028 MSP430_CPU (sd
)->state
.regs
[12] = sim_syscall (MSP430_CPU (sd
),
1029 syscall_num
, arg1
, arg2
,
1038 msp430_step_once (SIM_DESC sd
)
1040 Get_Byte_Local_Data ld
;
1041 unsigned char buf
[100];
1044 unsigned int opcode_pc
;
1045 MSP430_Opcode_Decoded opcode_buf
;
1046 MSP430_Opcode_Decoded
*opcode
= &opcode_buf
;
1048 int u1
, u2
, uresult
;
1054 int op_bytes
, op_bits
;
1059 if (opcode_pc
< 0x10)
1061 fprintf (stderr
, "Fault: PC(%#x) is less than 0x10\n", opcode_pc
);
1062 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1063 MSP430_CPU (sd
)->state
.regs
[0],
1068 if (PC
== MSP430_CPU (sd
)->state
.cio_breakpoint
1069 && STATE_OPEN_KIND (sd
) != SIM_OPEN_DEBUG
)
1074 opsize
= msp430_decode_opcode (MSP430_CPU (sd
)->state
.regs
[0],
1075 opcode
, msp430_getbyte
, &ld
);
1079 fprintf (stderr
, "Fault: undecodable opcode at %#x\n", opcode_pc
);
1080 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1081 MSP430_CPU (sd
)->state
.regs
[0],
1086 if (opcode
->repeat_reg
)
1087 n_repeats
= (MSP430_CPU (sd
)->state
.regs
[opcode
->repeats
] & 0x000f) + 1;
1089 n_repeats
= opcode
->repeats
+ 1;
1091 op_bits
= opcode
->size
;
1106 if (TRACE_INSN_P (MSP430_CPU (sd
)))
1108 disassemble_info info
;
1109 unsigned char b
[10];
1111 msp430_trace_one (opcode_pc
);
1113 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, b
, opcode_pc
, opsize
);
1115 init_disassemble_info (&info
, stderr
, (fprintf_ftype
) fprintf
);
1116 info
.private_data
= sd
;
1117 info
.read_memory_func
= msp430_dis_read
;
1118 fprintf (stderr
, "%#8x ", opcode_pc
);
1119 for (i
= 0; i
< opsize
; i
+= 2)
1120 fprintf (stderr
, " %02x%02x", b
[i
+1], b
[i
]);
1121 for (; i
< 6; i
+= 2)
1122 fprintf (stderr
, " ");
1123 fprintf (stderr
, " ");
1124 print_insn_msp430 (opcode_pc
, &info
);
1125 fprintf (stderr
, "\n");
1129 if (TRACE_ANY_P (MSP430_CPU (sd
)))
1130 trace_prefix (sd
, MSP430_CPU (sd
), NULL_CIA
, opcode_pc
,
1131 TRACE_LINENUM_P (MSP430_CPU (sd
)), NULL
, 0, "");
1139 /* Double-operand instructions. */
1141 if (opcode
->n_bytes
== 2
1142 && opcode
->op
[0].type
== MSP430_Operand_Register
1143 && opcode
->op
[0].reg
== MSR_CG
1144 && opcode
->op
[1].type
== MSP430_Operand_Immediate
1145 && opcode
->op
[1].addend
== 0
1146 /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK. */
1147 && opcode
->size
== 8)
1149 /* This is the designated software breakpoint instruction. */
1151 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1152 MSP430_CPU (sd
)->state
.regs
[0],
1153 sim_stopped
, SIM_SIGTRAP
);
1158 /* Otherwise, do the move. */
1159 for (rept
= 0; rept
< n_repeats
; rept
++)
1167 for (rept
= 0; rept
< n_repeats
; rept
++)
1169 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1174 uresult
= u1
+ u2
+ carry_to_use
;
1175 result
= s1
+ s2
+ carry_to_use
;
1176 TRACE_ALU (MSP430_CPU (sd
), "ADDC: %#x + %#x + %d = %#x",
1177 u1
, u2
, carry_to_use
, uresult
);
1179 FLAGS (result
, uresult
!= ZX (uresult
));
1184 for (rept
= 0; rept
< n_repeats
; rept
++)
1192 TRACE_ALU (MSP430_CPU (sd
), "ADD: %#x + %#x = %#x",
1195 FLAGS (result
, uresult
!= ZX (uresult
));
1200 for (rept
= 0; rept
< n_repeats
; rept
++)
1202 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1207 uresult
= ZX (~u2
) + u1
+ carry_to_use
;
1208 result
= s1
- s2
+ (carry_to_use
- 1);
1209 TRACE_ALU (MSP430_CPU (sd
), "SUBC: %#x - %#x + %d = %#x",
1210 u1
, u2
, carry_to_use
, uresult
);
1212 FLAGS (result
, uresult
!= ZX (uresult
));
1217 for (rept
= 0; rept
< n_repeats
; rept
++)
1223 uresult
= ZX (~u2
) + u1
+ 1;
1224 result
= SX (uresult
);
1225 TRACE_ALU (MSP430_CPU (sd
), "SUB: %#x - %#x = %#x",
1228 FLAGS (result
, uresult
!= ZX (uresult
));
1233 for (rept
= 0; rept
< n_repeats
; rept
++)
1239 uresult
= ZX (~u2
) + u1
+ 1;
1241 TRACE_ALU (MSP430_CPU (sd
), "CMP: %#x - %#x = %x",
1243 FLAGS (result
, uresult
!= ZX (uresult
));
1248 for (rept
= 0; rept
< n_repeats
; rept
++)
1250 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1253 uresult
= bcd_to_binary (u1
) + bcd_to_binary (u2
) + carry_to_use
;
1254 result
= binary_to_bcd (uresult
);
1255 TRACE_ALU (MSP430_CPU (sd
), "DADD: %#x + %#x + %d = %#x",
1256 u1
, u2
, carry_to_use
, result
);
1258 FLAGS (result
, uresult
> ((opcode
->size
== 8) ? 99 : 9999));
1263 for (rept
= 0; rept
< n_repeats
; rept
++)
1268 TRACE_ALU (MSP430_CPU (sd
), "AND: %#x & %#x = %#x",
1271 FLAGS (uresult
, uresult
!= 0);
1276 for (rept
= 0; rept
< n_repeats
; rept
++)
1281 TRACE_ALU (MSP430_CPU (sd
), "BIT: %#x & %#x -> %#x",
1283 FLAGS (uresult
, uresult
!= 0);
1288 for (rept
= 0; rept
< n_repeats
; rept
++)
1292 uresult
= u1
& ~ u2
;
1293 TRACE_ALU (MSP430_CPU (sd
), "BIC: %#x & ~ %#x = %#x",
1300 for (rept
= 0; rept
< n_repeats
; rept
++)
1305 TRACE_ALU (MSP430_CPU (sd
), "BIS: %#x | %#x = %#x",
1312 for (rept
= 0; rept
< n_repeats
; rept
++)
1314 s1
= 1 << (opcode
->size
- 1);
1318 TRACE_ALU (MSP430_CPU (sd
), "XOR: %#x & %#x = %#x",
1321 FLAGSV (uresult
, uresult
!= 0, (u1
& s1
) && (u2
& s1
));
1325 /* Single-operand instructions. Note: the decoder puts the same
1326 operand in SRC as in DEST, for our convenience. */
1329 for (rept
= 0; rept
< n_repeats
; rept
++)
1332 carry_to_use
= u1
& 1;
1334 if (SR
& MSP430_FLAG_C
)
1335 uresult
|= (1 << (opcode
->size
- 1));
1336 TRACE_ALU (MSP430_CPU (sd
), "RRC: %#x >>= %#x",
1339 FLAGS (uresult
, carry_to_use
);
1344 for (rept
= 0; rept
< n_repeats
; rept
++)
1347 uresult
= ((u1
>> 8) & 0x00ff) | ((u1
<< 8) & 0xff00);
1348 TRACE_ALU (MSP430_CPU (sd
), "SWPB: %#x -> %#x",
1355 for (rept
= 0; rept
< n_repeats
; rept
++)
1359 s1
= 1 << (opcode
->size
- 1);
1360 uresult
= (u1
>> 1) | (u1
& s1
);
1361 TRACE_ALU (MSP430_CPU (sd
), "RRA: %#x >>= %#x",
1369 for (rept
= 0; rept
< n_repeats
; rept
++)
1373 uresult
= (u1
>> 1);
1374 TRACE_ALU (MSP430_CPU (sd
), "RRU: %#x >>= %#x",
1382 for (rept
= 0; rept
< n_repeats
; rept
++)
1386 uresult
= u1
| 0xfff00;
1388 uresult
= u1
& 0x000ff;
1389 TRACE_ALU (MSP430_CPU (sd
), "SXT: %#x -> %#x",
1397 for (rept
= 0; rept
< n_repeats
; rept
++)
1401 new_sp
= REG_GET (MSR_SP
) - op_bytes
;
1402 /* SP is always word-aligned. */
1405 REG_PUT (MSR_SP
, new_sp
);
1407 mem_put_val (sd
, SP
, u1
, op_bits
);
1408 if (opcode
->op
[1].type
== MSP430_Operand_Register
)
1409 opcode
->op
[1].reg
--;
1414 for (rept
= 0; rept
< n_repeats
; rept
++)
1418 u1
= mem_get_val (sd
, SP
, op_bits
);
1420 if (opcode
->op
[0].type
== MSP430_Operand_Register
)
1421 opcode
->op
[0].reg
++;
1422 new_sp
= REG_GET (MSR_SP
) + op_bytes
;
1423 /* SP is always word-aligned. */
1426 REG_PUT (MSR_SP
, new_sp
);
1433 if (maybe_perform_syscall (sd
, u1
))
1436 REG_PUT (MSR_SP
, REG_GET (MSR_SP
) - op_bytes
);
1437 mem_put_val (sd
, SP
, PC
, op_bits
);
1438 TRACE_ALU (MSP430_CPU (sd
), "CALL: func %#x ret %#x, sp %#x",
1440 REG_PUT (MSR_PC
, u1
);
1444 u1
= mem_get_val (sd
, SP
, 16);
1447 PC
= mem_get_val (sd
, SP
, 16);
1449 /* Emulate the RETI action of the 20-bit CPUX architecure.
1450 This is safe for 16-bit CPU architectures as well, since the top
1451 8-bits of SR will have been written to the stack here, and will
1452 have been read as 0. */
1453 PC
|= (u1
& 0xF000) << 4;
1454 TRACE_ALU (MSP430_CPU (sd
), "RETI: pc %#x sr %#x",
1462 switch (opcode
->cond
)
1465 u1
= (SR
& MSP430_FLAG_Z
) ? 0 : 1;
1468 u1
= (SR
& MSP430_FLAG_Z
) ? 1 : 0;
1471 u1
= (SR
& MSP430_FLAG_C
) ? 0 : 1;
1474 u1
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1477 u1
= (SR
& MSP430_FLAG_N
) ? 1 : 0;
1480 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 1 : 0;
1483 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 0 : 1;
1492 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x -> %#x sr %#x, taken",
1493 cond_string (opcode
->cond
), PC
, i
, SR
);
1495 if (PC
== opcode_pc
)
1499 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x to %#x sr %#x, not taken",
1500 cond_string (opcode
->cond
), PC
, i
, SR
);
1504 fprintf (stderr
, "error: unexpected opcode id %d\n", opcode
->id
);
1510 sim_engine_run (SIM_DESC sd
,
1517 msp430_step_once (sd
);
1518 if (sim_events_tick (sd
))
1519 sim_events_process (sd
);