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 TRACE_VPU (MSP430_CPU (sd
), "PUT: %#x -> %s", v
, register_names
[n
]);
310 trace_reg_get (SIM_DESC sd
, int n
)
312 TRACE_VPU (MSP430_CPU (sd
), "GET: %s -> %#x", register_names
[n
], REG (n
));
316 #define REG_PUT(N,V) trace_reg_put (sd, N, V)
317 #define REG_GET(N) trace_reg_get (sd, N)
319 /* Hardware multiply (and accumulate) support. */
322 zero_ext (unsigned int v
, unsigned int bits
)
324 v
&= ((1 << bits
) - 1);
328 static signed long long
329 sign_ext (signed long long v
, unsigned int bits
)
331 signed long long sb
= 1LL << (bits
-1); /* Sign bit. */
332 signed long long mb
= (1LL << (bits
-1)) - 1LL; /* Mantissa bits. */
342 get_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
)
344 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
347 unsigned char buf
[4];
352 case MSP430_Operand_Immediate
:
355 case MSP430_Operand_Register
:
356 rv
= REG_GET (op
->reg
);
358 case MSP430_Operand_Indirect
:
359 case MSP430_Operand_Indirect_Postinc
:
361 if (op
->reg
!= MSR_None
)
363 int reg
= REG_GET (op
->reg
);
364 int sign
= opc
->ofs_430x
? 20 : 16;
366 /* Index values are signed. */
367 if (addr
& (1 << (sign
- 1)))
372 /* For MSP430 instructions the sum is limited to 16 bits if the
373 address in the index register is less than 64k even if we are
374 running on an MSP430X CPU. This is for MSP430 compatibility. */
375 if (reg
< 0x10000 && ! opc
->ofs_430x
)
378 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on read\n", addr
);
387 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 1);
391 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 2);
392 rv
= buf
[0] | (buf
[1] << 8);
396 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 4);
397 rv
= buf
[0] | (buf
[1] << 8) | (buf
[2] << 16) | (buf
[3] << 24);
400 assert (! opc
->size
);
404 /* Hack - MSP430X5438 serial port status register. */
408 if (addr
>= 0x130 && addr
<= 0x15B)
413 switch (HWMULT (sd
, hwmult_type
))
417 rv
= zero_ext (HWMULT (sd
, hwmult_result
), 16);
421 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
), 16);
427 switch (HWMULT (sd
, hwmult_type
))
431 rv
= zero_ext (HWMULT (sd
, hwmult_result
) >> 16, 16);
436 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
) >> 16, 16);
442 switch (HWMULT (sd
, hwmult_type
))
448 rv
= HWMULT (sd
, hwmult_signed_result
) < 0 ? -1 : 0;
451 rv
= 0; /* FIXME: Should be carry of last accumulate. */
454 rv
= HWMULT (sd
, hwmult_signed_accumulator
) < 0 ? -1 : 0;
460 rv
= zero_ext (HWMULT (sd
, hw32mult_result
), 16);
464 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 16, 16);
468 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 32, 16);
472 switch (HWMULT (sd
, hw32mult_type
))
474 case UNSIGN_64
: rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 48, 16); break;
475 case SIGN_64
: rv
= sign_ext (HWMULT (sd
, hw32mult_result
) >> 48, 16); break;
480 fprintf (stderr
, "unimplemented HW MULT read from %x!\n", addr
);
485 TRACE_MEMORY (MSP430_CPU (sd
), "GET: [%#x].%d -> %#x", addr
, opc
->size
,
490 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
514 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
515 REG_PUT (op
->reg
, REG_GET (op
->reg
) + incval
);
521 put_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
, int val
)
523 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
526 unsigned char buf
[4];
547 case MSP430_Operand_Register
:
549 REG_PUT (op
->reg
, val
);
551 case MSP430_Operand_Indirect
:
552 case MSP430_Operand_Indirect_Postinc
:
554 if (op
->reg
!= MSR_None
)
556 int reg
= REG_GET (op
->reg
);
557 int sign
= opc
->ofs_430x
? 20 : 16;
559 /* Index values are signed. */
560 if (addr
& (1 << (sign
- 1)))
565 /* For MSP430 instructions the sum is limited to 16 bits if the
566 address in the index register is less than 64k even if we are
567 running on an MSP430X CPU. This is for MSP430 compatibility. */
568 if (reg
< 0x10000 && ! opc
->ofs_430x
)
571 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on write\n", addr
);
578 TRACE_MEMORY (MSP430_CPU (sd
), "PUT: [%#x].%d <- %#x", addr
, opc
->size
,
581 /* Hack - MSP430X5438 serial port transmit register. */
585 if (addr
>= 0x130 && addr
<= 0x15B)
589 /* Hardware Multiply emulation. */
590 assert (opc
->size
== 16);
594 case 0x130: HWMULT (sd
, hwmult_op1
) = val
; HWMULT (sd
, hwmult_type
) = UNSIGN_32
; break;
595 case 0x132: HWMULT (sd
, hwmult_op1
) = val
; HWMULT (sd
, hwmult_type
) = SIGN_32
; break;
596 case 0x134: HWMULT (sd
, hwmult_op1
) = val
; HWMULT (sd
, hwmult_type
) = UNSIGN_MAC_32
; break;
597 case 0x136: HWMULT (sd
, hwmult_op1
) = val
; HWMULT (sd
, hwmult_type
) = SIGN_MAC_32
; break;
599 case 0x138: HWMULT (sd
, hwmult_op2
) = val
;
600 switch (HWMULT (sd
, hwmult_type
))
603 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
604 HWMULT (sd
, hwmult_signed_result
) = (signed) HWMULT (sd
, hwmult_result
);
605 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
609 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
610 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
611 HWMULT (sd
, hwmult_signed_result
) = a
* b
;
612 HWMULT (sd
, hwmult_result
) = (unsigned) HWMULT (sd
, hwmult_signed_result
);
613 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
617 HWMULT (sd
, hwmult_accumulator
) += HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
618 HWMULT (sd
, hwmult_signed_accumulator
) += HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
619 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
620 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
624 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
625 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
626 HWMULT (sd
, hwmult_accumulator
) += a
* b
;
627 HWMULT (sd
, hwmult_signed_accumulator
) += a
* b
;
628 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
629 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
635 /* Copy into LOW result... */
636 switch (HWMULT (sd
, hwmult_type
))
640 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_result
) = zero_ext (val
, 16);
641 HWMULT (sd
, hwmult_signed_accumulator
) = sign_ext (val
, 16);
645 HWMULT (sd
, hwmult_signed_accumulator
) = HWMULT (sd
, hwmult_result
) = sign_ext (val
, 16);
646 HWMULT (sd
, hwmult_accumulator
) = zero_ext (val
, 16);
652 HWMULT (sd
, hw32mult_op1
) = val
;
653 HWMULT (sd
, hw32mult_type
) = UNSIGN_64
;
656 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
659 HWMULT (sd
, hw32mult_op1
) = val
;
660 HWMULT (sd
, hw32mult_type
) = SIGN_64
;
663 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
666 HWMULT (sd
, hw32mult_op2
) = val
;
670 HWMULT (sd
, hw32mult_op2
) = (HWMULT (sd
, hw32mult_op2
) & 0xFFFF) | (val
<< 16);
671 switch (HWMULT (sd
, hw32mult_type
))
674 HWMULT (sd
, hw32mult_result
) = HWMULT (sd
, hw32mult_op1
) * HWMULT (sd
, hw32mult_op2
);
677 HWMULT (sd
, hw32mult_result
) = sign_ext (HWMULT (sd
, hw32mult_op1
), 32)
678 * sign_ext (HWMULT (sd
, hw32mult_op2
), 32);
684 fprintf (stderr
, "unimplemented HW MULT write to %x!\n", addr
);
693 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 1);
698 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 2);
706 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 4);
709 assert (! opc
->size
);
714 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
738 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
740 int new_val
= REG_GET (op
->reg
) + incval
;
741 /* SP is always word-aligned. */
742 if (op
->reg
== MSR_SP
&& (new_val
& 1))
744 REG_PUT (op
->reg
, new_val
);
751 mem_put_val (SIM_DESC sd
, int addr
, int val
, int bits
)
753 MSP430_Opcode_Decoded opc
;
756 opc
.op
[0].type
= MSP430_Operand_Indirect
;
757 opc
.op
[0].addend
= addr
;
758 opc
.op
[0].reg
= MSR_None
;
759 put_op (sd
, &opc
, 0, val
);
763 mem_get_val (SIM_DESC sd
, int addr
, int bits
)
765 MSP430_Opcode_Decoded opc
;
768 opc
.op
[0].type
= MSP430_Operand_Indirect
;
769 opc
.op
[0].addend
= addr
;
770 opc
.op
[0].reg
= MSR_None
;
771 return get_op (sd
, &opc
, 0);
774 #define CIO_OPEN (0xF0)
775 #define CIO_CLOSE (0xF1)
776 #define CIO_READ (0xF2)
777 #define CIO_WRITE (0xF3)
778 #define CIO_LSEEK (0xF4)
779 #define CIO_UNLINK (0xF5)
780 #define CIO_GETENV (0xF6)
781 #define CIO_RENAME (0xF7)
782 #define CIO_GETTIME (0xF8)
783 #define CIO_GETCLK (0xF9)
784 #define CIO_SYNC (0xFF)
786 #define CIO_I(n) (parms[(n)] + parms[(n)+1] * 256)
787 #define CIO_L(n) (parms[(n)] + parms[(n)+1] * 256 \
788 + parms[(n)+2] * 65536 + parms[(n)+3] * 16777216)
791 msp430_cio (SIM_DESC sd
)
793 /* A block of data at __CIOBUF__ describes the I/O operation to
796 unsigned char raw_parms
[13];
797 unsigned char parms
[8];
800 unsigned char buffer
[512];
802 long fd
, addr
, len
, rv
;
804 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
805 MSP430_CPU (sd
)->state
.cio_buffer
, 5);
809 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
810 MSP430_CPU (sd
)->state
.cio_buffer
+ 3, 8);
812 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
813 MSP430_CPU (sd
)->state
.cio_buffer
+ 11, length
);
821 rv
= write (fd
, buffer
, len
);
822 parms
[0] = rv
& 0xff;
828 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
829 MSP430_CPU (sd
)->state
.cio_buffer
+ 4, 8);
831 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
832 MSP430_CPU (sd
)->state
.cio_buffer
+ 12, ret_buflen
);
835 #define SRC get_op (sd, opcode, 1)
836 #define DSRC get_op (sd, opcode, 0)
837 #define DEST(V) put_op (sd, opcode, 0, (V))
840 msp430_dis_read (bfd_vma memaddr
,
843 struct disassemble_info
*dinfo
)
845 SIM_DESC sd
= dinfo
->private_data
;
846 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, myaddr
, memaddr
, length
);
850 #define DO_ALU(OP,SOP,MORE) \
854 int result = s1 OP s2 MORE; \
855 TRACE_ALU (MSP430_CPU (sd), "ALU: %#x %s %#x %s = %#x", s1, SOP, \
856 s2, #MORE, result); \
860 #define SIGN (1 << (opcode->size - 1))
861 #define POS(x) (((x) & SIGN) ? 0 : 1)
862 #define NEG(x) (((x) & SIGN) ? 1 : 0)
864 #define SX(v) sign_ext (v, opcode->size)
865 #define ZX(v) zero_ext (v, opcode->size)
870 static char buf
[2][6];
876 bp
[0] = f
& MSP430_FLAG_V
? 'V' : '-';
877 bp
[1] = f
& MSP430_FLAG_N
? 'N' : '-';
878 bp
[2] = f
& MSP430_FLAG_Z
? 'Z' : '-';
879 bp
[3] = f
& MSP430_FLAG_C
? 'C' : '-';
884 /* Random number that won't show up in our usual logic. */
885 #define MAGIC_OVERFLOW 0x55000F
888 do_flags (SIM_DESC sd
,
889 MSP430_Opcode_Decoded
*opcode
,
890 int vnz_val
, /* Signed result. */
896 int signbit
= 1 << (opcode
->size
- 1);
898 f
&= ~opcode
->flags_0
;
899 f
&= ~opcode
->flags_set
;
900 f
|= opcode
->flags_1
;
902 if (vnz_val
& signbit
)
903 new_f
|= MSP430_FLAG_N
;
904 if (! (vnz_val
& ((signbit
<< 1) - 1)))
905 new_f
|= MSP430_FLAG_Z
;
906 if (overflow
== MAGIC_OVERFLOW
)
908 if (vnz_val
!= SX (vnz_val
))
909 new_f
|= MSP430_FLAG_V
;
913 new_f
|= MSP430_FLAG_V
;
915 new_f
|= MSP430_FLAG_C
;
917 new_f
= f
| (new_f
& opcode
->flags_set
);
919 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s -> %s", flags2string (SR
),
920 flags2string (new_f
));
922 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s", flags2string (new_f
));
926 #define FLAGS(vnz,c) do_flags (sd, opcode, vnz, c, MAGIC_OVERFLOW)
927 #define FLAGSV(vnz,c,v) do_flags (sd, opcode, vnz, c, v)
929 /* These two assume unsigned 16-bit (four digit) words.
930 Mask off unwanted bits for byte operations. */
933 bcd_to_binary (int v
)
935 int r
= ( ((v
>> 0) & 0xf) * 1
936 + ((v
>> 4) & 0xf) * 10
937 + ((v
>> 8) & 0xf) * 100
938 + ((v
>> 12) & 0xf) * 1000);
943 binary_to_bcd (int v
)
945 int r
= ( ((v
/ 1) % 10) << 0
946 | ((v
/ 10) % 10) << 4
947 | ((v
/ 100) % 10) << 8
948 | ((v
/ 1000) % 10) << 12);
953 syscall_read_mem (host_callback
*cb
, struct cb_syscall
*sc
,
954 unsigned long taddr
, char *buf
, int bytes
)
956 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
957 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
959 return sim_core_read_buffer (sd
, cpu
, read_map
, buf
, taddr
, bytes
);
963 syscall_write_mem (host_callback
*cb
, struct cb_syscall
*sc
,
964 unsigned long taddr
, const char *buf
, int bytes
)
966 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
967 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
969 return sim_core_write_buffer (sd
, cpu
, write_map
, buf
, taddr
, bytes
);
973 cond_string (int cond
)
998 /* Checks a CALL to address CALL_ADDR. If this is a special
999 syscall address then the call is simulated and non-zero is
1000 returned. Otherwise 0 is returned. */
1003 maybe_perform_syscall (SIM_DESC sd
, int call_addr
)
1005 if (call_addr
== 0x00160)
1009 for (i
= 0; i
< 16; i
++)
1012 fprintf (stderr
, "\t");
1013 fprintf (stderr
, "R%-2d %05x ", i
, MSP430_CPU (sd
)->state
.regs
[i
]);
1016 int sp
= SP
+ (3 - (i
/ 4)) * 2;
1017 unsigned char buf
[2];
1019 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, sp
, 2);
1021 fprintf (stderr
, "\tSP%+d: %04x", sp
- SP
,
1022 buf
[0] + buf
[1] * 256);
1028 fprintf (stderr
, flags
& 0x100 ? " V" : " -");
1029 fprintf (stderr
, flags
& 0x004 ? "N" : "-");
1030 fprintf (stderr
, flags
& 0x002 ? "Z" : "-");
1031 fprintf (stderr
, flags
& 0x001 ? "C" : "-");
1034 fprintf (stderr
, "\n");
1040 if ((call_addr
& ~0x3f) == 0x00180)
1043 int syscall_num
= call_addr
& 0x3f;
1044 host_callback
*cb
= STATE_CALLBACK (sd
);
1047 CB_SYSCALL_INIT (&sc
);
1049 sc
.func
= syscall_num
;
1050 sc
.arg1
= MSP430_CPU (sd
)->state
.regs
[12];
1051 sc
.arg2
= MSP430_CPU (sd
)->state
.regs
[13];
1052 sc
.arg3
= MSP430_CPU (sd
)->state
.regs
[14];
1053 sc
.arg4
= MSP430_CPU (sd
)->state
.regs
[15];
1055 if (TRACE_SYSCALL_P (MSP430_CPU (sd
)))
1057 const char *syscall_name
= "*unknown*";
1059 switch (syscall_num
)
1061 case TARGET_SYS_exit
:
1062 syscall_name
= "exit(%d)";
1064 case TARGET_SYS_open
:
1065 syscall_name
= "open(%#x,%#x)";
1067 case TARGET_SYS_close
:
1068 syscall_name
= "close(%d)";
1070 case TARGET_SYS_read
:
1071 syscall_name
= "read(%d,%#x,%d)";
1073 case TARGET_SYS_write
:
1074 syscall_name
= "write(%d,%#x,%d)";
1077 trace_generic (sd
, MSP430_CPU (sd
), TRACE_SYSCALL_IDX
,
1078 syscall_name
, sc
.arg1
, sc
.arg2
, sc
.arg3
, sc
.arg4
);
1081 /* Handle SYS_exit here. */
1082 if (syscall_num
== 1)
1084 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1085 MSP430_CPU (sd
)->state
.regs
[0],
1086 sim_exited
, sc
.arg1
);
1091 sc
.p2
= MSP430_CPU (sd
);
1092 sc
.read_mem
= syscall_read_mem
;
1093 sc
.write_mem
= syscall_write_mem
;
1095 cb_syscall (cb
, &sc
);
1097 TRACE_SYSCALL (MSP430_CPU (sd
), "returns %ld", sc
.result
);
1099 MSP430_CPU (sd
)->state
.regs
[12] = sc
.result
;
1107 msp430_step_once (SIM_DESC sd
)
1109 Get_Byte_Local_Data ld
;
1110 unsigned char buf
[100];
1113 unsigned int opcode_pc
;
1114 MSP430_Opcode_Decoded opcode_buf
;
1115 MSP430_Opcode_Decoded
*opcode
= &opcode_buf
;
1117 int u1
, u2
, uresult
;
1123 int op_bytes
, op_bits
;
1128 if (opcode_pc
< 0x10)
1130 fprintf (stderr
, "Fault: PC(%#x) is less than 0x10\n", opcode_pc
);
1131 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1132 MSP430_CPU (sd
)->state
.regs
[0],
1137 if (PC
== MSP430_CPU (sd
)->state
.cio_breakpoint
1138 && STATE_OPEN_KIND (sd
) != SIM_OPEN_DEBUG
)
1143 opsize
= msp430_decode_opcode (MSP430_CPU (sd
)->state
.regs
[0],
1144 opcode
, msp430_getbyte
, &ld
);
1148 fprintf (stderr
, "Fault: undecodable opcode at %#x\n", opcode_pc
);
1149 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1150 MSP430_CPU (sd
)->state
.regs
[0],
1155 if (opcode
->repeat_reg
)
1156 n_repeats
= (MSP430_CPU (sd
)->state
.regs
[opcode
->repeats
] & 0x000f) + 1;
1158 n_repeats
= opcode
->repeats
+ 1;
1160 op_bits
= opcode
->size
;
1175 if (TRACE_INSN_P (MSP430_CPU (sd
)))
1177 disassemble_info info
;
1178 unsigned char b
[10];
1180 msp430_trace_one (opcode_pc
);
1182 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, b
, opcode_pc
, opsize
);
1184 init_disassemble_info (&info
, stderr
, (fprintf_ftype
) fprintf
);
1185 info
.private_data
= sd
;
1186 info
.read_memory_func
= msp430_dis_read
;
1187 fprintf (stderr
, "%#8x ", opcode_pc
);
1188 for (i
= 0; i
< opsize
; i
+= 2)
1189 fprintf (stderr
, " %02x%02x", b
[i
+1], b
[i
]);
1190 for (; i
< 6; i
+= 2)
1191 fprintf (stderr
, " ");
1192 fprintf (stderr
, " ");
1193 print_insn_msp430 (opcode_pc
, &info
);
1194 fprintf (stderr
, "\n");
1198 if (TRACE_ANY_P (MSP430_CPU (sd
)))
1199 trace_prefix (sd
, MSP430_CPU (sd
), NULL_CIA
, opcode_pc
,
1200 TRACE_LINENUM_P (MSP430_CPU (sd
)), NULL
, 0, "");
1208 /* Double-operand instructions. */
1210 if (opcode
->n_bytes
== 2
1211 && opcode
->op
[0].type
== MSP430_Operand_Register
1212 && opcode
->op
[0].reg
== MSR_CG
1213 && opcode
->op
[1].type
== MSP430_Operand_Immediate
1214 && opcode
->op
[1].addend
== 0
1215 /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK. */
1216 && opcode
->size
== 8)
1218 /* This is the designated software breakpoint instruction. */
1220 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1221 MSP430_CPU (sd
)->state
.regs
[0],
1222 sim_stopped
, SIM_SIGTRAP
);
1227 /* Otherwise, do the move. */
1228 for (rept
= 0; rept
< n_repeats
; rept
++)
1236 for (rept
= 0; rept
< n_repeats
; rept
++)
1238 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1243 uresult
= u1
+ u2
+ carry_to_use
;
1244 result
= s1
+ s2
+ carry_to_use
;
1245 TRACE_ALU (MSP430_CPU (sd
), "ADDC: %#x + %#x + %d = %#x",
1246 u1
, u2
, carry_to_use
, uresult
);
1248 FLAGS (result
, uresult
!= ZX (uresult
));
1253 for (rept
= 0; rept
< n_repeats
; rept
++)
1261 TRACE_ALU (MSP430_CPU (sd
), "ADD: %#x + %#x = %#x",
1264 FLAGS (result
, uresult
!= ZX (uresult
));
1269 for (rept
= 0; rept
< n_repeats
; rept
++)
1271 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1276 uresult
= ZX (~u2
) + u1
+ carry_to_use
;
1277 result
= s1
- s2
+ (carry_to_use
- 1);
1278 TRACE_ALU (MSP430_CPU (sd
), "SUBC: %#x - %#x + %d = %#x",
1279 u1
, u2
, carry_to_use
, uresult
);
1281 FLAGS (result
, uresult
!= ZX (uresult
));
1286 for (rept
= 0; rept
< n_repeats
; rept
++)
1292 uresult
= ZX (~u2
) + u1
+ 1;
1293 result
= SX (uresult
);
1294 TRACE_ALU (MSP430_CPU (sd
), "SUB: %#x - %#x = %#x",
1297 FLAGS (result
, uresult
!= ZX (uresult
));
1302 for (rept
= 0; rept
< n_repeats
; rept
++)
1308 uresult
= ZX (~u2
) + u1
+ 1;
1310 TRACE_ALU (MSP430_CPU (sd
), "CMP: %#x - %#x = %x",
1312 FLAGS (result
, uresult
!= ZX (uresult
));
1317 for (rept
= 0; rept
< n_repeats
; rept
++)
1319 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1322 uresult
= bcd_to_binary (u1
) + bcd_to_binary (u2
) + carry_to_use
;
1323 result
= binary_to_bcd (uresult
);
1324 TRACE_ALU (MSP430_CPU (sd
), "DADD: %#x + %#x + %d = %#x",
1325 u1
, u2
, carry_to_use
, result
);
1327 FLAGS (result
, uresult
> ((opcode
->size
== 8) ? 99 : 9999));
1332 for (rept
= 0; rept
< n_repeats
; rept
++)
1337 TRACE_ALU (MSP430_CPU (sd
), "AND: %#x & %#x = %#x",
1340 FLAGS (uresult
, uresult
!= 0);
1345 for (rept
= 0; rept
< n_repeats
; rept
++)
1350 TRACE_ALU (MSP430_CPU (sd
), "BIT: %#x & %#x -> %#x",
1352 FLAGS (uresult
, uresult
!= 0);
1357 for (rept
= 0; rept
< n_repeats
; rept
++)
1361 uresult
= u1
& ~ u2
;
1362 TRACE_ALU (MSP430_CPU (sd
), "BIC: %#x & ~ %#x = %#x",
1369 for (rept
= 0; rept
< n_repeats
; rept
++)
1374 TRACE_ALU (MSP430_CPU (sd
), "BIS: %#x | %#x = %#x",
1381 for (rept
= 0; rept
< n_repeats
; rept
++)
1383 s1
= 1 << (opcode
->size
- 1);
1387 TRACE_ALU (MSP430_CPU (sd
), "XOR: %#x & %#x = %#x",
1390 FLAGSV (uresult
, uresult
!= 0, (u1
& s1
) && (u2
& s1
));
1394 /* Single-operand instructions. Note: the decoder puts the same
1395 operand in SRC as in DEST, for our convenience. */
1398 for (rept
= 0; rept
< n_repeats
; rept
++)
1401 carry_to_use
= u1
& 1;
1403 if (SR
& MSP430_FLAG_C
)
1404 uresult
|= (1 << (opcode
->size
- 1));
1405 TRACE_ALU (MSP430_CPU (sd
), "RRC: %#x >>= %#x",
1408 FLAGS (uresult
, carry_to_use
);
1413 for (rept
= 0; rept
< n_repeats
; rept
++)
1416 uresult
= ((u1
>> 8) & 0x00ff) | ((u1
<< 8) & 0xff00);
1417 TRACE_ALU (MSP430_CPU (sd
), "SWPB: %#x -> %#x",
1424 for (rept
= 0; rept
< n_repeats
; rept
++)
1428 s1
= 1 << (opcode
->size
- 1);
1429 uresult
= (u1
>> 1) | (u1
& s1
);
1430 TRACE_ALU (MSP430_CPU (sd
), "RRA: %#x >>= %#x",
1438 for (rept
= 0; rept
< n_repeats
; rept
++)
1442 uresult
= (u1
>> 1);
1443 TRACE_ALU (MSP430_CPU (sd
), "RRU: %#x >>= %#x",
1451 for (rept
= 0; rept
< n_repeats
; rept
++)
1455 uresult
= u1
| 0xfff00;
1457 uresult
= u1
& 0x000ff;
1458 TRACE_ALU (MSP430_CPU (sd
), "SXT: %#x -> %#x",
1466 for (rept
= 0; rept
< n_repeats
; rept
++)
1470 new_sp
= REG_GET (MSR_SP
) - op_bytes
;
1471 /* SP is always word-aligned. */
1474 REG_PUT (MSR_SP
, new_sp
);
1476 mem_put_val (sd
, SP
, u1
, op_bits
);
1477 if (opcode
->op
[1].type
== MSP430_Operand_Register
)
1478 opcode
->op
[1].reg
--;
1483 for (rept
= 0; rept
< n_repeats
; rept
++)
1487 u1
= mem_get_val (sd
, SP
, op_bits
);
1489 if (opcode
->op
[0].type
== MSP430_Operand_Register
)
1490 opcode
->op
[0].reg
++;
1491 new_sp
= REG_GET (MSR_SP
) + op_bytes
;
1492 /* SP is always word-aligned. */
1495 REG_PUT (MSR_SP
, new_sp
);
1502 if (maybe_perform_syscall (sd
, u1
))
1505 REG_PUT (MSR_SP
, REG_GET (MSR_SP
) - op_bytes
);
1506 mem_put_val (sd
, SP
, PC
, op_bits
);
1507 TRACE_ALU (MSP430_CPU (sd
), "CALL: func %#x ret %#x, sp %#x",
1509 REG_PUT (MSR_PC
, u1
);
1513 u1
= mem_get_val (sd
, SP
, 16);
1516 PC
= mem_get_val (sd
, SP
, 16);
1518 /* Emulate the RETI action of the 20-bit CPUX architecure.
1519 This is safe for 16-bit CPU architectures as well, since the top
1520 8-bits of SR will have been written to the stack here, and will
1521 have been read as 0. */
1522 PC
|= (u1
& 0xF000) << 4;
1523 TRACE_ALU (MSP430_CPU (sd
), "RETI: pc %#x sr %#x",
1531 switch (opcode
->cond
)
1534 u1
= (SR
& MSP430_FLAG_Z
) ? 0 : 1;
1537 u1
= (SR
& MSP430_FLAG_Z
) ? 1 : 0;
1540 u1
= (SR
& MSP430_FLAG_C
) ? 0 : 1;
1543 u1
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1546 u1
= (SR
& MSP430_FLAG_N
) ? 1 : 0;
1549 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 1 : 0;
1552 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 0 : 1;
1561 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x -> %#x sr %#x, taken",
1562 cond_string (opcode
->cond
), PC
, i
, SR
);
1564 if (PC
== opcode_pc
)
1568 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x to %#x sr %#x, not taken",
1569 cond_string (opcode
->cond
), PC
, i
, SR
);
1573 fprintf (stderr
, "error: unexpected opcode id %d\n", opcode
->id
);
1579 sim_engine_run (SIM_DESC sd
,
1586 msp430_step_once (sd
);
1587 if (sim_events_tick (sd
))
1588 sim_events_process (sd
);