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"
33 #include "targ-vals.h"
37 loader_write_mem (SIM_DESC sd
,
39 const unsigned char *buf
,
42 SIM_CPU
*cpu
= MSP430_CPU (sd
);
43 return sim_core_write_buffer (sd
, cpu
, write_map
, buf
, taddr
, bytes
);
47 msp430_pc_fetch (SIM_CPU
*cpu
)
49 return cpu
->state
.regs
[0];
53 msp430_pc_store (SIM_CPU
*cpu
, sim_cia newpc
)
55 cpu
->state
.regs
[0] = newpc
;
59 lookup_symbol (SIM_DESC sd
, const char *name
)
61 struct bfd
*abfd
= STATE_PROG_BFD (sd
);
62 asymbol
**symbol_table
= STATE_SYMBOL_TABLE (sd
);
63 long number_of_symbols
= STATE_NUM_SYMBOLS (sd
);
66 if (symbol_table
== NULL
)
70 storage_needed
= bfd_get_symtab_upper_bound (abfd
);
71 if (storage_needed
<= 0)
74 STATE_SYMBOL_TABLE (sd
) = symbol_table
= xmalloc (storage_needed
);
75 STATE_NUM_SYMBOLS (sd
) = number_of_symbols
=
76 bfd_canonicalize_symtab (abfd
, symbol_table
);
79 for (i
= 0; i
< number_of_symbols
; i
++)
80 if (strcmp (symbol_table
[i
]->name
, name
) == 0)
82 long val
= symbol_table
[i
]->section
->vma
+ symbol_table
[i
]->value
;
89 msp430_reg_fetch (SIM_CPU
*cpu
, int regno
, unsigned char *buf
, int len
)
91 if (0 <= regno
&& regno
< 16)
95 int val
= cpu
->state
.regs
[regno
];
97 buf
[1] = (val
>> 8) & 0xff;
102 int val
= cpu
->state
.regs
[regno
];
104 buf
[1] = (val
>> 8) & 0xff;
105 buf
[2] = (val
>> 16) & 0x0f; /* Registers are only 20 bits wide. */
117 msp430_reg_store (SIM_CPU
*cpu
, int regno
, unsigned char *buf
, int len
)
119 if (0 <= regno
&& regno
< 16)
123 cpu
->state
.regs
[regno
] = (buf
[1] << 8) | buf
[0];
129 cpu
->state
.regs
[regno
] = ((buf
[2] << 16) & 0xf0000)
130 | (buf
[1] << 8) | buf
[0];
139 msp430_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
141 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
145 sim_open (SIM_OPEN_KIND kind
,
146 struct host_callback_struct
*callback
,
150 SIM_DESC sd
= sim_state_alloc (kind
, callback
);
152 struct bfd
*prog_bfd
;
154 /* Initialise the simulator. */
156 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
162 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
168 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
174 CPU_PC_FETCH (MSP430_CPU (sd
)) = msp430_pc_fetch
;
175 CPU_PC_STORE (MSP430_CPU (sd
)) = msp430_pc_store
;
176 CPU_REG_FETCH (MSP430_CPU (sd
)) = msp430_reg_fetch
;
177 CPU_REG_STORE (MSP430_CPU (sd
)) = msp430_reg_store
;
179 /* Allocate memory if none specified by user.
180 Note - these values match the memory regions in the libgloss/msp430/msp430[xl]-sim.ld scripts. */
181 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x2, 1) == 0)
182 sim_do_commandf (sd
, "memory-region 0,0x20"); /* Needed by the GDB testsuite. */
183 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x200, 1) == 0)
184 sim_do_commandf (sd
, "memory-region 0x200,0xfd00"); /* RAM and/or ROM */
185 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0xfffe, 1) == 0)
186 sim_do_commandf (sd
, "memory-region 0xffc0,0x40"); /* VECTORS. */
187 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x10000, 1) == 0)
188 sim_do_commandf (sd
, "memory-region 0x10000,0x80000"); /* HIGH FLASH RAM. */
189 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x90000, 1) == 0)
190 sim_do_commandf (sd
, "memory-region 0x90000,0x70000"); /* HIGH ROM. */
192 /* Check for/establish the a reference program image. */
193 if (sim_analyze_program (sd
,
194 (STATE_PROG_ARGV (sd
) != NULL
195 ? *STATE_PROG_ARGV (sd
)
196 : NULL
), abfd
) != SIM_RC_OK
)
202 prog_bfd
= sim_load_file (sd
, argv
[0], callback
,
206 1 /* use LMA instead of VMA */,
208 /* Allow prog_bfd to be NULL - this is needed by the GDB testsuite. */
210 /* Establish any remaining configuration options. */
211 if (sim_config (sd
) != SIM_RC_OK
)
217 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
223 /* CPU specific initialization. */
224 assert (MAX_NR_PROCESSORS
== 1);
225 msp430_initialize_cpu (sd
, MSP430_CPU (sd
));
227 msp430_trace_init (STATE_PROG_BFD (sd
));
229 if (prog_bfd
!= NULL
)
231 MSP430_CPU (sd
)->state
.cio_breakpoint
= lookup_symbol (sd
, "C$$IO$$");
232 MSP430_CPU (sd
)->state
.cio_buffer
= lookup_symbol (sd
, "__CIOBUF__");
233 if (MSP430_CPU (sd
)->state
.cio_buffer
== -1)
234 MSP430_CPU (sd
)->state
.cio_buffer
= lookup_symbol (sd
, "_CIOBUF_");
241 sim_close (SIM_DESC sd
,
244 free (STATE_SYMBOL_TABLE (sd
));
249 sim_create_inferior (SIM_DESC sd
,
254 unsigned char resetv
[2];
258 /* Set the PC to the default reset vector if available. */
259 c
= sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, resetv
, 0xfffe, 2);
260 new_pc
= resetv
[0] + 256 * resetv
[1];
262 /* If the reset vector isn't initialized, then use the ELF entry. */
263 if (abfd
!= NULL
&& !new_pc
)
264 new_pc
= bfd_get_start_address (abfd
);
266 sim_pc_set (MSP430_CPU (sd
), new_pc
);
267 msp430_pc_store (MSP430_CPU (sd
), new_pc
);
276 } Get_Byte_Local_Data
;
279 msp430_getbyte (void *vld
)
281 Get_Byte_Local_Data
*ld
= (Get_Byte_Local_Data
*)vld
;
283 SIM_DESC sd
= ld
->sd
;
285 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, ld
->gb_addr
, 1);
290 #define REG(N) MSP430_CPU (sd)->state.regs[(N)]
291 #define PC REG(MSR_PC)
292 #define SP REG(MSR_SP)
293 #define SR REG(MSR_SR)
298 "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8",
299 "R9", "R10", "R11", "R12", "R13", "R14", "R15"
303 trace_reg_put (SIM_DESC sd
, int n
, unsigned int v
)
305 if (TRACE_VPU_P (MSP430_CPU (sd
)))
306 trace_generic (sd
, MSP430_CPU (sd
), TRACE_VPU_IDX
,
307 "PUT: %#x -> %s", v
, register_names
[n
]);
312 trace_reg_get (SIM_DESC sd
, int n
)
314 if (TRACE_VPU_P (MSP430_CPU (sd
)))
315 trace_generic (sd
, MSP430_CPU (sd
), TRACE_VPU_IDX
,
316 "GET: %s -> %#x", register_names
[n
], REG (n
));
320 #define REG_PUT(N,V) trace_reg_put (sd, N, V)
321 #define REG_GET(N) trace_reg_get (sd, N)
323 /* Hardware multiply (and accumulate) support. */
326 zero_ext (unsigned int v
, unsigned int bits
)
328 v
&= ((1 << bits
) - 1);
332 static signed long long
333 sign_ext (signed long long v
, unsigned int bits
)
335 signed long long sb
= 1LL << (bits
-1); /* Sign bit. */
336 signed long long mb
= (1LL << (bits
-1)) - 1LL; /* Mantissa bits. */
346 get_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
)
348 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
351 unsigned char buf
[4];
356 case MSP430_Operand_Immediate
:
359 case MSP430_Operand_Register
:
360 rv
= REG_GET (op
->reg
);
362 case MSP430_Operand_Indirect
:
363 case MSP430_Operand_Indirect_Postinc
:
365 if (op
->reg
!= MSR_None
)
367 int reg
= REG_GET (op
->reg
);
368 int sign
= opc
->ofs_430x
? 20 : 16;
370 /* Index values are signed. */
371 if (addr
& (1 << (sign
- 1)))
376 /* For MSP430 instructions the sum is limited to 16 bits if the
377 address in the index register is less than 64k even if we are
378 running on an MSP430X CPU. This is for MSP430 compatibility. */
379 if (reg
< 0x10000 && ! opc
->ofs_430x
)
382 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on read\n", addr
);
391 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 1);
395 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 2);
396 rv
= buf
[0] | (buf
[1] << 8);
400 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 4);
401 rv
= buf
[0] | (buf
[1] << 8) | (buf
[2] << 16) | (buf
[3] << 24);
404 assert (! opc
->size
);
408 /* Hack - MSP430X5438 serial port status register. */
412 if (addr
>= 0x130 && addr
<= 0x15B)
417 switch (HWMULT (sd
, hwmult_type
))
421 rv
= zero_ext (HWMULT (sd
, hwmult_result
), 16);
425 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
), 16);
431 switch (HWMULT (sd
, hwmult_type
))
435 rv
= zero_ext (HWMULT (sd
, hwmult_result
) >> 16, 16);
440 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
) >> 16, 16);
446 switch (HWMULT (sd
, hwmult_type
))
452 rv
= HWMULT (sd
, hwmult_signed_result
) < 0 ? -1 : 0;
455 rv
= 0; /* FIXME: Should be carry of last accumulate. */
458 rv
= HWMULT (sd
, hwmult_signed_accumulator
) < 0 ? -1 : 0;
464 rv
= zero_ext (HWMULT (sd
, hw32mult_result
), 16);
468 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 16, 16);
472 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 32, 16);
476 switch (HWMULT (sd
, hw32mult_type
))
478 case UNSIGN_64
: rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 48, 16); break;
479 case SIGN_64
: rv
= sign_ext (HWMULT (sd
, hw32mult_result
) >> 48, 16); break;
484 fprintf (stderr
, "unimplemented HW MULT read from %x!\n", addr
);
489 if (TRACE_MEMORY_P (MSP430_CPU (sd
)))
490 trace_generic (sd
, MSP430_CPU (sd
), TRACE_MEMORY_IDX
,
491 "GET: [%#x].%d -> %#x", addr
, opc
->size
, rv
);
495 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
519 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
520 REG_PUT (op
->reg
, REG_GET (op
->reg
) + incval
);
526 put_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
, int val
)
528 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
531 unsigned char buf
[4];
552 case MSP430_Operand_Register
:
554 REG_PUT (op
->reg
, val
);
556 case MSP430_Operand_Indirect
:
557 case MSP430_Operand_Indirect_Postinc
:
559 if (op
->reg
!= MSR_None
)
561 int reg
= REG_GET (op
->reg
);
562 int sign
= opc
->ofs_430x
? 20 : 16;
564 /* Index values are signed. */
565 if (addr
& (1 << (sign
- 1)))
570 /* For MSP430 instructions the sum is limited to 16 bits if the
571 address in the index register is less than 64k even if we are
572 running on an MSP430X CPU. This is for MSP430 compatibility. */
573 if (reg
< 0x10000 && ! opc
->ofs_430x
)
576 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on write\n", addr
);
583 if (TRACE_MEMORY_P (MSP430_CPU (sd
)))
584 trace_generic (sd
, MSP430_CPU (sd
), TRACE_MEMORY_IDX
,
585 "PUT: [%#x].%d <- %#x", addr
, opc
->size
, val
);
587 /* Hack - MSP430X5438 serial port transmit register. */
591 if (addr
>= 0x130 && addr
<= 0x15B)
595 /* Hardware Multiply emulation. */
596 assert (opc
->size
== 16);
600 case 0x130: HWMULT (sd
, hwmult_op1
) = val
; HWMULT (sd
, hwmult_type
) = UNSIGN_32
; break;
601 case 0x132: HWMULT (sd
, hwmult_op1
) = val
; HWMULT (sd
, hwmult_type
) = SIGN_32
; break;
602 case 0x134: HWMULT (sd
, hwmult_op1
) = val
; HWMULT (sd
, hwmult_type
) = UNSIGN_MAC_32
; break;
603 case 0x136: HWMULT (sd
, hwmult_op1
) = val
; HWMULT (sd
, hwmult_type
) = SIGN_MAC_32
; break;
605 case 0x138: HWMULT (sd
, hwmult_op2
) = val
;
606 switch (HWMULT (sd
, hwmult_type
))
609 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
610 HWMULT (sd
, hwmult_signed_result
) = (signed) HWMULT (sd
, hwmult_result
);
611 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
615 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
616 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
617 HWMULT (sd
, hwmult_signed_result
) = a
* b
;
618 HWMULT (sd
, hwmult_result
) = (unsigned) HWMULT (sd
, hwmult_signed_result
);
619 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
623 HWMULT (sd
, hwmult_accumulator
) += HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
624 HWMULT (sd
, hwmult_signed_accumulator
) += HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
625 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
626 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
630 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
631 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
632 HWMULT (sd
, hwmult_accumulator
) += a
* b
;
633 HWMULT (sd
, hwmult_signed_accumulator
) += a
* b
;
634 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
635 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
641 /* Copy into LOW result... */
642 switch (HWMULT (sd
, hwmult_type
))
646 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_result
) = zero_ext (val
, 16);
647 HWMULT (sd
, hwmult_signed_accumulator
) = sign_ext (val
, 16);
651 HWMULT (sd
, hwmult_signed_accumulator
) = HWMULT (sd
, hwmult_result
) = sign_ext (val
, 16);
652 HWMULT (sd
, hwmult_accumulator
) = zero_ext (val
, 16);
658 HWMULT (sd
, hw32mult_op1
) = val
;
659 HWMULT (sd
, hw32mult_type
) = UNSIGN_64
;
662 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
665 HWMULT (sd
, hw32mult_op1
) = val
;
666 HWMULT (sd
, hw32mult_type
) = SIGN_64
;
669 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
672 HWMULT (sd
, hw32mult_op2
) = val
;
676 HWMULT (sd
, hw32mult_op2
) = (HWMULT (sd
, hw32mult_op2
) & 0xFFFF) | (val
<< 16);
677 switch (HWMULT (sd
, hw32mult_type
))
680 HWMULT (sd
, hw32mult_result
) = HWMULT (sd
, hw32mult_op1
) * HWMULT (sd
, hw32mult_op2
);
683 HWMULT (sd
, hw32mult_result
) = sign_ext (HWMULT (sd
, hw32mult_op1
), 32)
684 * sign_ext (HWMULT (sd
, hw32mult_op2
), 32);
690 fprintf (stderr
, "unimplemented HW MULT write to %x!\n", addr
);
699 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 1);
704 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 2);
712 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 4);
715 assert (! opc
->size
);
720 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
744 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
746 int new_val
= REG_GET (op
->reg
) + incval
;
747 /* SP is always word-aligned. */
748 if (op
->reg
== MSR_SP
&& (new_val
& 1))
750 REG_PUT (op
->reg
, new_val
);
757 mem_put_val (SIM_DESC sd
, int addr
, int val
, int bits
)
759 MSP430_Opcode_Decoded opc
;
762 opc
.op
[0].type
= MSP430_Operand_Indirect
;
763 opc
.op
[0].addend
= addr
;
764 opc
.op
[0].reg
= MSR_None
;
765 put_op (sd
, &opc
, 0, val
);
769 mem_get_val (SIM_DESC sd
, int addr
, int bits
)
771 MSP430_Opcode_Decoded opc
;
774 opc
.op
[0].type
= MSP430_Operand_Indirect
;
775 opc
.op
[0].addend
= addr
;
776 opc
.op
[0].reg
= MSR_None
;
777 return get_op (sd
, &opc
, 0);
780 #define CIO_OPEN (0xF0)
781 #define CIO_CLOSE (0xF1)
782 #define CIO_READ (0xF2)
783 #define CIO_WRITE (0xF3)
784 #define CIO_LSEEK (0xF4)
785 #define CIO_UNLINK (0xF5)
786 #define CIO_GETENV (0xF6)
787 #define CIO_RENAME (0xF7)
788 #define CIO_GETTIME (0xF8)
789 #define CIO_GETCLK (0xF9)
790 #define CIO_SYNC (0xFF)
792 #define CIO_I(n) (parms[(n)] + parms[(n)+1] * 256)
793 #define CIO_L(n) (parms[(n)] + parms[(n)+1] * 256 \
794 + parms[(n)+2] * 65536 + parms[(n)+3] * 16777216)
797 msp430_cio (SIM_DESC sd
)
799 /* A block of data at __CIOBUF__ describes the I/O operation to
802 unsigned char raw_parms
[13];
803 unsigned char parms
[8];
806 unsigned char buffer
[512];
808 long fd
, addr
, len
, rv
;
810 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
811 MSP430_CPU (sd
)->state
.cio_buffer
, 5);
815 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
816 MSP430_CPU (sd
)->state
.cio_buffer
+ 3, 8);
818 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
819 MSP430_CPU (sd
)->state
.cio_buffer
+ 11, length
);
827 rv
= write (fd
, buffer
, len
);
828 parms
[0] = rv
& 0xff;
834 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
835 MSP430_CPU (sd
)->state
.cio_buffer
+ 4, 8);
837 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
838 MSP430_CPU (sd
)->state
.cio_buffer
+ 12, ret_buflen
);
841 #define SRC get_op (sd, opcode, 1)
842 #define DSRC get_op (sd, opcode, 0)
843 #define DEST(V) put_op (sd, opcode, 0, (V))
846 msp430_dis_read (bfd_vma memaddr
,
849 struct disassemble_info
*dinfo
)
851 SIM_DESC sd
= dinfo
->private_data
;
852 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, myaddr
, memaddr
, length
);
856 #define DO_ALU(OP,SOP,MORE) \
860 int result = s1 OP s2 MORE; \
861 if (TRACE_ALU_P (MSP430_CPU (sd))) \
862 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, \
863 "ALU: %#x %s %#x %s = %#x", s1, SOP, s2, #MORE, result); \
867 #define SIGN (1 << (opcode->size - 1))
868 #define POS(x) (((x) & SIGN) ? 0 : 1)
869 #define NEG(x) (((x) & SIGN) ? 1 : 0)
871 #define SX(v) sign_ext (v, opcode->size)
872 #define ZX(v) zero_ext (v, opcode->size)
877 static char buf
[2][6];
883 bp
[0] = f
& MSP430_FLAG_V
? 'V' : '-';
884 bp
[1] = f
& MSP430_FLAG_N
? 'N' : '-';
885 bp
[2] = f
& MSP430_FLAG_Z
? 'Z' : '-';
886 bp
[3] = f
& MSP430_FLAG_C
? 'C' : '-';
891 /* Random number that won't show up in our usual logic. */
892 #define MAGIC_OVERFLOW 0x55000F
895 do_flags (SIM_DESC sd
,
896 MSP430_Opcode_Decoded
*opcode
,
897 int vnz_val
, /* Signed result. */
903 int signbit
= 1 << (opcode
->size
- 1);
905 f
&= ~opcode
->flags_0
;
906 f
&= ~opcode
->flags_set
;
907 f
|= opcode
->flags_1
;
909 if (vnz_val
& signbit
)
910 new_f
|= MSP430_FLAG_N
;
911 if (! (vnz_val
& ((signbit
<< 1) - 1)))
912 new_f
|= MSP430_FLAG_Z
;
913 if (overflow
== MAGIC_OVERFLOW
)
915 if (vnz_val
!= SX (vnz_val
))
916 new_f
|= MSP430_FLAG_V
;
920 new_f
|= MSP430_FLAG_V
;
922 new_f
|= MSP430_FLAG_C
;
924 new_f
= f
| (new_f
& opcode
->flags_set
);
925 if (TRACE_ALU_P (MSP430_CPU (sd
)))
928 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
929 "FLAGS: %s -> %s", flags2string (SR
),
930 flags2string (new_f
));
932 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
933 "FLAGS: %s", flags2string (new_f
));
938 #define FLAGS(vnz,c) do_flags (sd, opcode, vnz, c, MAGIC_OVERFLOW)
939 #define FLAGSV(vnz,c,v) do_flags (sd, opcode, vnz, c, v)
941 /* These two assume unsigned 16-bit (four digit) words.
942 Mask off unwanted bits for byte operations. */
945 bcd_to_binary (int v
)
947 int r
= ( ((v
>> 0) & 0xf) * 1
948 + ((v
>> 4) & 0xf) * 10
949 + ((v
>> 8) & 0xf) * 100
950 + ((v
>> 12) & 0xf) * 1000);
955 binary_to_bcd (int v
)
957 int r
= ( ((v
/ 1) % 10) << 0
958 | ((v
/ 10) % 10) << 4
959 | ((v
/ 100) % 10) << 8
960 | ((v
/ 1000) % 10) << 12);
965 syscall_read_mem (host_callback
*cb
, struct cb_syscall
*sc
,
966 unsigned long taddr
, char *buf
, int bytes
)
968 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
969 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
971 return sim_core_read_buffer (sd
, cpu
, read_map
, buf
, taddr
, bytes
);
975 syscall_write_mem (host_callback
*cb
, struct cb_syscall
*sc
,
976 unsigned long taddr
, const char *buf
, int bytes
)
978 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
979 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
981 return sim_core_write_buffer (sd
, cpu
, write_map
, buf
, taddr
, bytes
);
985 cond_string (int cond
)
1010 /* Checks a CALL to address CALL_ADDR. If this is a special
1011 syscall address then the call is simulated and non-zero is
1012 returned. Otherwise 0 is returned. */
1015 maybe_perform_syscall (SIM_DESC sd
, int call_addr
)
1017 if (call_addr
== 0x00160)
1021 for (i
= 0; i
< 16; i
++)
1024 fprintf (stderr
, "\t");
1025 fprintf (stderr
, "R%-2d %05x ", i
, MSP430_CPU (sd
)->state
.regs
[i
]);
1028 int sp
= SP
+ (3 - (i
/ 4)) * 2;
1029 unsigned char buf
[2];
1031 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, sp
, 2);
1033 fprintf (stderr
, "\tSP%+d: %04x", sp
- SP
,
1034 buf
[0] + buf
[1] * 256);
1040 fprintf (stderr
, flags
& 0x100 ? " V" : " -");
1041 fprintf (stderr
, flags
& 0x004 ? "N" : "-");
1042 fprintf (stderr
, flags
& 0x002 ? "Z" : "-");
1043 fprintf (stderr
, flags
& 0x001 ? "C" : "-");
1046 fprintf (stderr
, "\n");
1052 if ((call_addr
& ~0x3f) == 0x00180)
1055 int syscall_num
= call_addr
& 0x3f;
1056 host_callback
*cb
= STATE_CALLBACK (sd
);
1059 CB_SYSCALL_INIT (&sc
);
1061 sc
.func
= syscall_num
;
1062 sc
.arg1
= MSP430_CPU (sd
)->state
.regs
[12];
1063 sc
.arg2
= MSP430_CPU (sd
)->state
.regs
[13];
1064 sc
.arg3
= MSP430_CPU (sd
)->state
.regs
[14];
1065 sc
.arg4
= MSP430_CPU (sd
)->state
.regs
[15];
1067 if (TRACE_SYSCALL_P (MSP430_CPU (sd
)))
1069 const char *syscall_name
= "*unknown*";
1071 switch (syscall_num
)
1073 case TARGET_SYS_exit
:
1074 syscall_name
= "exit(%d)";
1076 case TARGET_SYS_open
:
1077 syscall_name
= "open(%#x,%#x)";
1079 case TARGET_SYS_close
:
1080 syscall_name
= "close(%d)";
1082 case TARGET_SYS_read
:
1083 syscall_name
= "read(%d,%#x,%d)";
1085 case TARGET_SYS_write
:
1086 syscall_name
= "write(%d,%#x,%d)";
1089 trace_generic (sd
, MSP430_CPU (sd
), TRACE_SYSCALL_IDX
,
1090 syscall_name
, sc
.arg1
, sc
.arg2
, sc
.arg3
, sc
.arg4
);
1093 /* Handle SYS_exit here. */
1094 if (syscall_num
== 1)
1096 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1097 MSP430_CPU (sd
)->state
.regs
[0],
1098 sim_exited
, sc
.arg1
);
1103 sc
.p2
= MSP430_CPU (sd
);
1104 sc
.read_mem
= syscall_read_mem
;
1105 sc
.write_mem
= syscall_write_mem
;
1107 cb_syscall (cb
, &sc
);
1109 if (TRACE_SYSCALL_P (MSP430_CPU (sd
)))
1110 trace_generic (sd
, MSP430_CPU (sd
), TRACE_SYSCALL_IDX
,
1111 "returns %ld", sc
.result
);
1113 MSP430_CPU (sd
)->state
.regs
[12] = sc
.result
;
1121 msp430_step_once (SIM_DESC sd
)
1123 Get_Byte_Local_Data ld
;
1124 unsigned char buf
[100];
1127 unsigned int opcode_pc
;
1128 MSP430_Opcode_Decoded opcode_buf
;
1129 MSP430_Opcode_Decoded
*opcode
= &opcode_buf
;
1131 int u1
, u2
, uresult
;
1137 int op_bytes
, op_bits
;
1142 if (opcode_pc
< 0x10)
1144 fprintf (stderr
, "Fault: PC(%#x) is less than 0x10\n", opcode_pc
);
1145 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1146 MSP430_CPU (sd
)->state
.regs
[0],
1151 if (PC
== MSP430_CPU (sd
)->state
.cio_breakpoint
1152 && STATE_OPEN_KIND (sd
) != SIM_OPEN_DEBUG
)
1157 opsize
= msp430_decode_opcode (MSP430_CPU (sd
)->state
.regs
[0],
1158 opcode
, msp430_getbyte
, &ld
);
1162 fprintf (stderr
, "Fault: undecodable opcode at %#x\n", opcode_pc
);
1163 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1164 MSP430_CPU (sd
)->state
.regs
[0],
1169 if (opcode
->repeat_reg
)
1170 n_repeats
= (MSP430_CPU (sd
)->state
.regs
[opcode
->repeats
] & 0x000f) + 1;
1172 n_repeats
= opcode
->repeats
+ 1;
1174 op_bits
= opcode
->size
;
1189 if (TRACE_INSN_P (MSP430_CPU (sd
)))
1191 disassemble_info info
;
1192 unsigned char b
[10];
1194 msp430_trace_one (opcode_pc
);
1196 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, b
, opcode_pc
, opsize
);
1198 init_disassemble_info (&info
, stderr
, (fprintf_ftype
) fprintf
);
1199 info
.private_data
= sd
;
1200 info
.read_memory_func
= msp430_dis_read
;
1201 fprintf (stderr
, "%#8x ", opcode_pc
);
1202 for (i
= 0; i
< opsize
; i
+= 2)
1203 fprintf (stderr
, " %02x%02x", b
[i
+1], b
[i
]);
1204 for (; i
< 6; i
+= 2)
1205 fprintf (stderr
, " ");
1206 fprintf (stderr
, " ");
1207 print_insn_msp430 (opcode_pc
, &info
);
1208 fprintf (stderr
, "\n");
1212 if (TRACE_ANY_P (MSP430_CPU (sd
)))
1213 trace_prefix (sd
, MSP430_CPU (sd
), NULL_CIA
, opcode_pc
,
1214 TRACE_LINENUM_P (MSP430_CPU (sd
)), NULL
, 0, "");
1222 /* Double-operand instructions. */
1224 if (opcode
->n_bytes
== 2
1225 && opcode
->op
[0].type
== MSP430_Operand_Register
1226 && opcode
->op
[0].reg
== MSR_CG
1227 && opcode
->op
[1].type
== MSP430_Operand_Immediate
1228 && opcode
->op
[1].addend
== 0
1229 /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK. */
1230 && opcode
->size
== 8)
1232 /* This is the designated software breakpoint instruction. */
1234 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1235 MSP430_CPU (sd
)->state
.regs
[0],
1236 sim_stopped
, SIM_SIGTRAP
);
1241 /* Otherwise, do the move. */
1242 for (rept
= 0; rept
< n_repeats
; rept
++)
1250 for (rept
= 0; rept
< n_repeats
; rept
++)
1252 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1257 uresult
= u1
+ u2
+ carry_to_use
;
1258 result
= s1
+ s2
+ carry_to_use
;
1259 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1260 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1261 "ADDC: %#x + %#x + %d = %#x",
1262 u1
, u2
, carry_to_use
, uresult
);
1264 FLAGS (result
, uresult
!= ZX (uresult
));
1269 for (rept
= 0; rept
< n_repeats
; rept
++)
1277 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1278 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1279 "ADD: %#x + %#x = %#x",
1282 FLAGS (result
, uresult
!= ZX (uresult
));
1287 for (rept
= 0; rept
< n_repeats
; rept
++)
1289 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1294 uresult
= ZX (~u2
) + u1
+ carry_to_use
;
1295 result
= s1
- s2
+ (carry_to_use
- 1);
1296 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1297 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1298 "SUBC: %#x - %#x + %d = %#x",
1299 u1
, u2
, carry_to_use
, uresult
);
1301 FLAGS (result
, uresult
!= ZX (uresult
));
1306 for (rept
= 0; rept
< n_repeats
; rept
++)
1312 uresult
= ZX (~u2
) + u1
+ 1;
1313 result
= SX (uresult
);
1314 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1315 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1316 "SUB: %#x - %#x = %#x",
1319 FLAGS (result
, uresult
!= ZX (uresult
));
1324 for (rept
= 0; rept
< n_repeats
; rept
++)
1330 uresult
= ZX (~u2
) + u1
+ 1;
1332 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1333 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1334 "CMP: %#x - %#x = %x",
1336 FLAGS (result
, uresult
!= ZX (uresult
));
1341 for (rept
= 0; rept
< n_repeats
; rept
++)
1343 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1346 uresult
= bcd_to_binary (u1
) + bcd_to_binary (u2
) + carry_to_use
;
1347 result
= binary_to_bcd (uresult
);
1348 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1349 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1350 "DADD: %#x + %#x + %d = %#x",
1351 u1
, u2
, carry_to_use
, result
);
1353 FLAGS (result
, uresult
> ((opcode
->size
== 8) ? 99 : 9999));
1358 for (rept
= 0; rept
< n_repeats
; rept
++)
1363 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1364 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1365 "AND: %#x & %#x = %#x",
1368 FLAGS (uresult
, uresult
!= 0);
1373 for (rept
= 0; rept
< n_repeats
; rept
++)
1378 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1379 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1380 "BIT: %#x & %#x -> %#x",
1382 FLAGS (uresult
, uresult
!= 0);
1387 for (rept
= 0; rept
< n_repeats
; rept
++)
1391 uresult
= u1
& ~ u2
;
1392 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1393 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1394 "BIC: %#x & ~ %#x = %#x",
1401 for (rept
= 0; rept
< n_repeats
; rept
++)
1406 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1407 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1408 "BIS: %#x | %#x = %#x",
1415 for (rept
= 0; rept
< n_repeats
; rept
++)
1417 s1
= 1 << (opcode
->size
- 1);
1421 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1422 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1423 "XOR: %#x & %#x = %#x",
1426 FLAGSV (uresult
, uresult
!= 0, (u1
& s1
) && (u2
& s1
));
1430 /* Single-operand instructions. Note: the decoder puts the same
1431 operand in SRC as in DEST, for our convenience. */
1434 for (rept
= 0; rept
< n_repeats
; rept
++)
1437 carry_to_use
= u1
& 1;
1439 if (SR
& MSP430_FLAG_C
)
1440 uresult
|= (1 << (opcode
->size
- 1));
1441 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1442 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1446 FLAGS (uresult
, carry_to_use
);
1451 for (rept
= 0; rept
< n_repeats
; rept
++)
1454 uresult
= ((u1
>> 8) & 0x00ff) | ((u1
<< 8) & 0xff00);
1455 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1456 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1464 for (rept
= 0; rept
< n_repeats
; rept
++)
1468 s1
= 1 << (opcode
->size
- 1);
1469 uresult
= (u1
>> 1) | (u1
& s1
);
1470 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1471 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1480 for (rept
= 0; rept
< n_repeats
; rept
++)
1484 uresult
= (u1
>> 1);
1485 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1486 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1495 for (rept
= 0; rept
< n_repeats
; rept
++)
1499 uresult
= u1
| 0xfff00;
1501 uresult
= u1
& 0x000ff;
1502 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1503 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1512 for (rept
= 0; rept
< n_repeats
; rept
++)
1516 new_sp
= REG_GET (MSR_SP
) - op_bytes
;
1517 /* SP is always word-aligned. */
1520 REG_PUT (MSR_SP
, new_sp
);
1522 mem_put_val (sd
, SP
, u1
, op_bits
);
1523 if (opcode
->op
[1].type
== MSP430_Operand_Register
)
1524 opcode
->op
[1].reg
--;
1529 for (rept
= 0; rept
< n_repeats
; rept
++)
1533 u1
= mem_get_val (sd
, SP
, op_bits
);
1535 if (opcode
->op
[0].type
== MSP430_Operand_Register
)
1536 opcode
->op
[0].reg
++;
1537 new_sp
= REG_GET (MSR_SP
) + op_bytes
;
1538 /* SP is always word-aligned. */
1541 REG_PUT (MSR_SP
, new_sp
);
1548 if (maybe_perform_syscall (sd
, u1
))
1551 REG_PUT (MSR_SP
, REG_GET (MSR_SP
) - op_bytes
);
1552 mem_put_val (sd
, SP
, PC
, op_bits
);
1553 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1554 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1555 "CALL: func %#x ret %#x, sp %#x",
1557 REG_PUT (MSR_PC
, u1
);
1561 u1
= mem_get_val (sd
, SP
, 16);
1564 PC
= mem_get_val (sd
, SP
, 16);
1566 /* Emulate the RETI action of the 20-bit CPUX architecure.
1567 This is safe for 16-bit CPU architectures as well, since the top
1568 8-bits of SR will have been written to the stack here, and will
1569 have been read as 0. */
1570 PC
|= (u1
& 0xF000) << 4;
1571 if (TRACE_ALU_P (MSP430_CPU (sd
)))
1572 trace_generic (sd
, MSP430_CPU (sd
), TRACE_ALU_IDX
,
1573 "RETI: pc %#x sr %#x",
1581 switch (opcode
->cond
)
1584 u1
= (SR
& MSP430_FLAG_Z
) ? 0 : 1;
1587 u1
= (SR
& MSP430_FLAG_Z
) ? 1 : 0;
1590 u1
= (SR
& MSP430_FLAG_C
) ? 0 : 1;
1593 u1
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1596 u1
= (SR
& MSP430_FLAG_N
) ? 1 : 0;
1599 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 1 : 0;
1602 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 0 : 1;
1611 if (TRACE_BRANCH_P (MSP430_CPU (sd
)))
1612 trace_generic (sd
, MSP430_CPU (sd
), TRACE_BRANCH_IDX
,
1613 "J%s: pc %#x -> %#x sr %#x, taken",
1614 cond_string (opcode
->cond
), PC
, i
, SR
);
1616 if (PC
== opcode_pc
)
1620 if (TRACE_BRANCH_P (MSP430_CPU (sd
)))
1621 trace_generic (sd
, MSP430_CPU (sd
), TRACE_BRANCH_IDX
,
1622 "J%s: pc %#x to %#x sr %#x, not taken",
1623 cond_string (opcode
->cond
), PC
, i
, SR
);
1627 fprintf (stderr
, "error: unexpected opcode id %d\n", opcode
->id
);
1633 sim_engine_run (SIM_DESC sd
,
1640 msp430_step_once (sd
);
1641 if (sim_events_tick (sd
))
1642 sim_events_process (sd
);