1 /* Simulator for TI MSP430 and MSP430X
3 Copyright (C) 2013-2019 Free Software Foundation, Inc.
4 Contributed by Red Hat.
5 Based on sim/bfin/bfin-sim.c which was contributed by Analog Devices, Inc.
7 This file is part of simulators.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
29 #include "opcode/msp430-decode.h"
31 #include "sim-syscall.h"
32 #include "targ-vals.h"
35 msp430_pc_fetch (SIM_CPU
*cpu
)
37 return cpu
->state
.regs
[0];
41 msp430_pc_store (SIM_CPU
*cpu
, sim_cia newpc
)
43 cpu
->state
.regs
[0] = newpc
;
47 msp430_reg_fetch (SIM_CPU
*cpu
, int regno
, unsigned char *buf
, int len
)
49 if (0 <= regno
&& regno
< 16)
53 int val
= cpu
->state
.regs
[regno
];
55 buf
[1] = (val
>> 8) & 0xff;
60 int val
= cpu
->state
.regs
[regno
];
62 buf
[1] = (val
>> 8) & 0xff;
63 buf
[2] = (val
>> 16) & 0x0f; /* Registers are only 20 bits wide. */
75 msp430_reg_store (SIM_CPU
*cpu
, int regno
, unsigned char *buf
, int len
)
77 if (0 <= regno
&& regno
< 16)
81 cpu
->state
.regs
[regno
] = (buf
[1] << 8) | buf
[0];
87 cpu
->state
.regs
[regno
] = ((buf
[2] << 16) & 0xf0000)
88 | (buf
[1] << 8) | buf
[0];
97 msp430_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
99 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
103 sim_open (SIM_OPEN_KIND kind
,
104 struct host_callback_struct
*callback
,
108 SIM_DESC sd
= sim_state_alloc (kind
, callback
);
111 /* Initialise the simulator. */
113 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
119 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
125 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
131 CPU_PC_FETCH (MSP430_CPU (sd
)) = msp430_pc_fetch
;
132 CPU_PC_STORE (MSP430_CPU (sd
)) = msp430_pc_store
;
133 CPU_REG_FETCH (MSP430_CPU (sd
)) = msp430_reg_fetch
;
134 CPU_REG_STORE (MSP430_CPU (sd
)) = msp430_reg_store
;
136 /* Allocate memory if none specified by user.
137 Note - these values match the memory regions in the libgloss/msp430/msp430[xl]-sim.ld scripts. */
138 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x2, 1) == 0)
139 sim_do_commandf (sd
, "memory-region 0,0x20"); /* Needed by the GDB testsuite. */
140 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x500, 1) == 0)
141 sim_do_commandf (sd
, "memory-region 0x500,0xfa00"); /* RAM and/or ROM */
142 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0xfffe, 1) == 0)
143 sim_do_commandf (sd
, "memory-region 0xffc0,0x40"); /* VECTORS. */
144 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x10000, 1) == 0)
145 sim_do_commandf (sd
, "memory-region 0x10000,0x80000"); /* HIGH FLASH RAM. */
146 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x90000, 1) == 0)
147 sim_do_commandf (sd
, "memory-region 0x90000,0x70000"); /* HIGH ROM. */
149 /* Check for/establish the a reference program image. */
150 if (sim_analyze_program (sd
,
151 (STATE_PROG_ARGV (sd
) != NULL
152 ? *STATE_PROG_ARGV (sd
)
153 : NULL
), abfd
) != SIM_RC_OK
)
159 /* Establish any remaining configuration options. */
160 if (sim_config (sd
) != SIM_RC_OK
)
166 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
172 /* CPU specific initialization. */
173 assert (MAX_NR_PROCESSORS
== 1);
174 msp430_initialize_cpu (sd
, MSP430_CPU (sd
));
176 MSP430_CPU (sd
)->state
.cio_breakpoint
= trace_sym_value (sd
, "C$$IO$$");
177 MSP430_CPU (sd
)->state
.cio_buffer
= trace_sym_value (sd
, "__CIOBUF__");
178 if (MSP430_CPU (sd
)->state
.cio_buffer
== -1)
179 MSP430_CPU (sd
)->state
.cio_buffer
= trace_sym_value (sd
, "_CIOBUF_");
185 sim_create_inferior (SIM_DESC sd
,
190 unsigned char resetv
[2];
194 /* Set the PC to the default reset vector if available. */
195 c
= sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, resetv
, 0xfffe, 2);
196 new_pc
= resetv
[0] + 256 * resetv
[1];
198 /* If the reset vector isn't initialized, then use the ELF entry. */
199 if (abfd
!= NULL
&& !new_pc
)
200 new_pc
= bfd_get_start_address (abfd
);
202 sim_pc_set (MSP430_CPU (sd
), new_pc
);
203 msp430_pc_store (MSP430_CPU (sd
), new_pc
);
212 } Get_Byte_Local_Data
;
215 msp430_getbyte (void *vld
)
217 Get_Byte_Local_Data
*ld
= (Get_Byte_Local_Data
*)vld
;
219 SIM_DESC sd
= ld
->sd
;
221 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, ld
->gb_addr
, 1);
226 #define REG(N) MSP430_CPU (sd)->state.regs[(N)]
227 #define PC REG(MSR_PC)
228 #define SP REG(MSR_SP)
229 #define SR REG(MSR_SR)
234 "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8",
235 "R9", "R10", "R11", "R12", "R13", "R14", "R15"
239 trace_reg_put (SIM_DESC sd
, int n
, unsigned int v
)
241 TRACE_REGISTER (MSP430_CPU (sd
), "PUT: %#x -> %s", v
, register_names
[n
]);
246 trace_reg_get (SIM_DESC sd
, int n
)
248 TRACE_REGISTER (MSP430_CPU (sd
), "GET: %s -> %#x", register_names
[n
], REG (n
));
252 #define REG_PUT(N,V) trace_reg_put (sd, N, V)
253 #define REG_GET(N) trace_reg_get (sd, N)
255 /* Hardware multiply (and accumulate) support. */
258 zero_ext (unsigned int v
, unsigned int bits
)
260 v
&= ((1 << bits
) - 1);
264 static signed long long
265 sign_ext (signed long long v
, unsigned int bits
)
267 signed long long sb
= 1LL << (bits
-1); /* Sign bit. */
268 signed long long mb
= (1LL << (bits
-1)) - 1LL; /* Mantissa bits. */
278 get_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
)
280 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
283 unsigned char buf
[4];
288 case MSP430_Operand_Immediate
:
291 case MSP430_Operand_Register
:
292 rv
= REG_GET (op
->reg
);
294 case MSP430_Operand_Indirect
:
295 case MSP430_Operand_Indirect_Postinc
:
297 if (op
->reg
!= MSR_None
)
299 int reg
= REG_GET (op
->reg
);
300 int sign
= opc
->ofs_430x
? 20 : 16;
302 /* Index values are signed. */
303 if (addr
& (1 << (sign
- 1)))
304 addr
|= -(1 << sign
);
308 /* For MSP430 instructions the sum is limited to 16 bits if the
309 address in the index register is less than 64k even if we are
310 running on an MSP430X CPU. This is for MSP430 compatibility. */
311 if (reg
< 0x10000 && ! opc
->ofs_430x
)
314 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on read\n", addr
);
323 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 1);
327 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 2);
328 rv
= buf
[0] | (buf
[1] << 8);
332 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 4);
333 rv
= buf
[0] | (buf
[1] << 8) | (buf
[2] << 16) | (buf
[3] << 24);
336 assert (! opc
->size
);
340 /* Hack - MSP430X5438 serial port status register. */
344 if ((addr
>= 0x130 && addr
<= 0x15B)
345 || (addr
>= 0x4C0 && addr
<= 0x4EB))
351 switch (HWMULT (sd
, hwmult_type
))
355 rv
= zero_ext (HWMULT (sd
, hwmult_result
), 16);
359 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
), 16);
366 switch (HWMULT (sd
, hwmult_type
))
370 rv
= zero_ext (HWMULT (sd
, hwmult_result
) >> 16, 16);
375 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
) >> 16, 16);
382 switch (HWMULT (sd
, hwmult_type
))
388 rv
= HWMULT (sd
, hwmult_signed_result
) < 0 ? -1 : 0;
391 rv
= 0; /* FIXME: Should be carry of last accumulate. */
394 rv
= HWMULT (sd
, hwmult_signed_accumulator
) < 0 ? -1 : 0;
401 rv
= zero_ext (HWMULT (sd
, hw32mult_result
), 16);
406 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 16, 16);
411 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 32, 16);
416 switch (HWMULT (sd
, hw32mult_type
))
418 case UNSIGN_64
: rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 48, 16); break;
419 case SIGN_64
: rv
= sign_ext (HWMULT (sd
, hw32mult_result
) >> 48, 16); break;
424 fprintf (stderr
, "unimplemented HW MULT read from %x!\n", addr
);
429 TRACE_MEMORY (MSP430_CPU (sd
), "GET: [%#x].%d -> %#x", addr
, opc
->size
,
434 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
458 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
459 REG_PUT (op
->reg
, REG_GET (op
->reg
) + incval
);
465 put_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
, int val
)
467 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
470 unsigned char buf
[4];
491 case MSP430_Operand_Register
:
493 REG_PUT (op
->reg
, val
);
495 case MSP430_Operand_Indirect
:
496 case MSP430_Operand_Indirect_Postinc
:
498 if (op
->reg
!= MSR_None
)
500 int reg
= REG_GET (op
->reg
);
501 int sign
= opc
->ofs_430x
? 20 : 16;
503 /* Index values are signed. */
504 if (addr
& (1 << (sign
- 1)))
505 addr
|= -(1 << sign
);
509 /* For MSP430 instructions the sum is limited to 16 bits if the
510 address in the index register is less than 64k even if we are
511 running on an MSP430X CPU. This is for MSP430 compatibility. */
512 if (reg
< 0x10000 && ! opc
->ofs_430x
)
515 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on write\n", addr
);
522 TRACE_MEMORY (MSP430_CPU (sd
), "PUT: [%#x].%d <- %#x", addr
, opc
->size
,
525 /* Hack - MSP430X5438 serial port transmit register. */
529 if ((addr
>= 0x130 && addr
<= 0x15B)
530 || (addr
>= 0x4C0 && addr
<= 0x4EB))
534 /* Hardware Multiply emulation. */
535 assert (opc
->size
== 16);
541 HWMULT (sd
, hwmult_op1
) = val
;
542 HWMULT (sd
, hwmult_type
) = UNSIGN_32
;
547 HWMULT (sd
, hwmult_op1
) = val
;
548 HWMULT (sd
, hwmult_type
) = SIGN_32
;
553 HWMULT (sd
, hwmult_op1
) = val
;
554 HWMULT (sd
, hwmult_type
) = UNSIGN_MAC_32
;
559 HWMULT (sd
, hwmult_op1
) = val
;
560 HWMULT (sd
, hwmult_type
) = SIGN_MAC_32
;
565 HWMULT (sd
, hwmult_op2
) = val
;
566 switch (HWMULT (sd
, hwmult_type
))
569 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
570 HWMULT (sd
, hwmult_signed_result
) = (signed) HWMULT (sd
, hwmult_result
);
571 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
575 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
576 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
577 HWMULT (sd
, hwmult_signed_result
) = a
* b
;
578 HWMULT (sd
, hwmult_result
) = (unsigned) HWMULT (sd
, hwmult_signed_result
);
579 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
583 HWMULT (sd
, hwmult_accumulator
) += HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
584 HWMULT (sd
, hwmult_signed_accumulator
) += HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
585 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
586 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
590 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
591 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
592 HWMULT (sd
, hwmult_accumulator
) += a
* b
;
593 HWMULT (sd
, hwmult_signed_accumulator
) += a
* b
;
594 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
595 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
602 /* Copy into LOW result... */
603 switch (HWMULT (sd
, hwmult_type
))
607 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_result
) = zero_ext (val
, 16);
608 HWMULT (sd
, hwmult_signed_accumulator
) = sign_ext (val
, 16);
612 HWMULT (sd
, hwmult_signed_accumulator
) = HWMULT (sd
, hwmult_result
) = sign_ext (val
, 16);
613 HWMULT (sd
, hwmult_accumulator
) = zero_ext (val
, 16);
620 HWMULT (sd
, hw32mult_op1
) = val
;
621 HWMULT (sd
, hw32mult_type
) = UNSIGN_64
;
626 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
631 HWMULT (sd
, hw32mult_op1
) = val
;
632 HWMULT (sd
, hw32mult_type
) = SIGN_64
;
637 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
642 HWMULT (sd
, hw32mult_op2
) = val
;
647 HWMULT (sd
, hw32mult_op2
) = (HWMULT (sd
, hw32mult_op2
) & 0xFFFF) | (val
<< 16);
648 switch (HWMULT (sd
, hw32mult_type
))
651 HWMULT (sd
, hw32mult_result
) = HWMULT (sd
, hw32mult_op1
) * HWMULT (sd
, hw32mult_op2
);
654 HWMULT (sd
, hw32mult_result
) = sign_ext (HWMULT (sd
, hw32mult_op1
), 32)
655 * sign_ext (HWMULT (sd
, hw32mult_op2
), 32);
661 fprintf (stderr
, "unimplemented HW MULT write to %x!\n", addr
);
670 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 1);
675 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 2);
683 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 4);
686 assert (! opc
->size
);
691 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
715 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
717 int new_val
= REG_GET (op
->reg
) + incval
;
718 /* SP is always word-aligned. */
719 if (op
->reg
== MSR_SP
&& (new_val
& 1))
721 REG_PUT (op
->reg
, new_val
);
728 mem_put_val (SIM_DESC sd
, int addr
, int val
, int bits
)
730 MSP430_Opcode_Decoded opc
;
733 opc
.op
[0].type
= MSP430_Operand_Indirect
;
734 opc
.op
[0].addend
= addr
;
735 opc
.op
[0].reg
= MSR_None
;
736 put_op (sd
, &opc
, 0, val
);
740 mem_get_val (SIM_DESC sd
, int addr
, int bits
)
742 MSP430_Opcode_Decoded opc
;
745 opc
.op
[0].type
= MSP430_Operand_Indirect
;
746 opc
.op
[0].addend
= addr
;
747 opc
.op
[0].reg
= MSR_None
;
748 return get_op (sd
, &opc
, 0);
751 #define CIO_OPEN (0xF0)
752 #define CIO_CLOSE (0xF1)
753 #define CIO_READ (0xF2)
754 #define CIO_WRITE (0xF3)
755 #define CIO_LSEEK (0xF4)
756 #define CIO_UNLINK (0xF5)
757 #define CIO_GETENV (0xF6)
758 #define CIO_RENAME (0xF7)
759 #define CIO_GETTIME (0xF8)
760 #define CIO_GETCLK (0xF9)
761 #define CIO_SYNC (0xFF)
763 #define CIO_I(n) (parms[(n)] + parms[(n)+1] * 256)
764 #define CIO_L(n) (parms[(n)] + parms[(n)+1] * 256 \
765 + parms[(n)+2] * 65536 + parms[(n)+3] * 16777216)
768 msp430_cio (SIM_DESC sd
)
770 /* A block of data at __CIOBUF__ describes the I/O operation to
773 unsigned char raw_parms
[13];
774 unsigned char parms
[8];
777 unsigned char buffer
[512];
779 long fd
, addr
, len
, rv
;
781 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
782 MSP430_CPU (sd
)->state
.cio_buffer
, 5);
786 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
787 MSP430_CPU (sd
)->state
.cio_buffer
+ 3, 8);
789 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
790 MSP430_CPU (sd
)->state
.cio_buffer
+ 11, length
);
798 rv
= write (fd
, buffer
, len
);
799 parms
[0] = rv
& 0xff;
805 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
806 MSP430_CPU (sd
)->state
.cio_buffer
+ 4, 8);
808 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
809 MSP430_CPU (sd
)->state
.cio_buffer
+ 12, ret_buflen
);
812 #define SRC get_op (sd, opcode, 1)
813 #define DSRC get_op (sd, opcode, 0)
814 #define DEST(V) put_op (sd, opcode, 0, (V))
816 #define DO_ALU(OP,SOP,MORE) \
820 int result = s1 OP s2 MORE; \
821 TRACE_ALU (MSP430_CPU (sd), "ALU: %#x %s %#x %s = %#x", s1, SOP, \
822 s2, #MORE, result); \
826 #define SIGN (1 << (opcode->size - 1))
827 #define POS(x) (((x) & SIGN) ? 0 : 1)
828 #define NEG(x) (((x) & SIGN) ? 1 : 0)
830 #define SX(v) sign_ext (v, opcode->size)
831 #define ZX(v) zero_ext (v, opcode->size)
836 static char buf
[2][6];
842 bp
[0] = f
& MSP430_FLAG_V
? 'V' : '-';
843 bp
[1] = f
& MSP430_FLAG_N
? 'N' : '-';
844 bp
[2] = f
& MSP430_FLAG_Z
? 'Z' : '-';
845 bp
[3] = f
& MSP430_FLAG_C
? 'C' : '-';
850 /* Random number that won't show up in our usual logic. */
851 #define MAGIC_OVERFLOW 0x55000F
854 do_flags (SIM_DESC sd
,
855 MSP430_Opcode_Decoded
*opcode
,
856 int vnz_val
, /* Signed result. */
862 int signbit
= 1 << (opcode
->size
- 1);
864 f
&= ~opcode
->flags_0
;
865 f
&= ~opcode
->flags_set
;
866 f
|= opcode
->flags_1
;
868 if (vnz_val
& signbit
)
869 new_f
|= MSP430_FLAG_N
;
870 if (! (vnz_val
& ((signbit
<< 1) - 1)))
871 new_f
|= MSP430_FLAG_Z
;
872 if (overflow
== MAGIC_OVERFLOW
)
874 if (vnz_val
!= SX (vnz_val
))
875 new_f
|= MSP430_FLAG_V
;
879 new_f
|= MSP430_FLAG_V
;
881 new_f
|= MSP430_FLAG_C
;
883 new_f
= f
| (new_f
& opcode
->flags_set
);
885 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s -> %s", flags2string (SR
),
886 flags2string (new_f
));
888 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s", flags2string (new_f
));
892 #define FLAGS(vnz,c) do_flags (sd, opcode, vnz, c, MAGIC_OVERFLOW)
893 #define FLAGSV(vnz,c,v) do_flags (sd, opcode, vnz, c, v)
895 /* These two assume unsigned 16-bit (four digit) words.
896 Mask off unwanted bits for byte operations. */
899 bcd_to_binary (int v
)
901 int r
= ( ((v
>> 0) & 0xf) * 1
902 + ((v
>> 4) & 0xf) * 10
903 + ((v
>> 8) & 0xf) * 100
904 + ((v
>> 12) & 0xf) * 1000);
909 binary_to_bcd (int v
)
911 int r
= ( ((v
/ 1) % 10) << 0
912 | ((v
/ 10) % 10) << 4
913 | ((v
/ 100) % 10) << 8
914 | ((v
/ 1000) % 10) << 12);
919 cond_string (int cond
)
944 /* Checks a CALL to address CALL_ADDR. If this is a special
945 syscall address then the call is simulated and non-zero is
946 returned. Otherwise 0 is returned. */
949 maybe_perform_syscall (SIM_DESC sd
, int call_addr
)
951 if (call_addr
== 0x00160)
955 for (i
= 0; i
< 16; i
++)
958 fprintf (stderr
, "\t");
959 fprintf (stderr
, "R%-2d %05x ", i
, MSP430_CPU (sd
)->state
.regs
[i
]);
962 int sp
= SP
+ (3 - (i
/ 4)) * 2;
963 unsigned char buf
[2];
965 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, sp
, 2);
967 fprintf (stderr
, "\tSP%+d: %04x", sp
- SP
,
968 buf
[0] + buf
[1] * 256);
974 fprintf (stderr
, flags
& 0x100 ? " V" : " -");
975 fprintf (stderr
, flags
& 0x004 ? "N" : "-");
976 fprintf (stderr
, flags
& 0x002 ? "Z" : "-");
977 fprintf (stderr
, flags
& 0x001 ? "C" : "-");
980 fprintf (stderr
, "\n");
986 if ((call_addr
& ~0x3f) == 0x00180)
989 int arg1
, arg2
, arg3
, arg4
;
990 int syscall_num
= call_addr
& 0x3f;
992 /* syscall_num == 2 is used for the variadic function "open".
993 The arguments are set up differently for variadic functions.
994 See slaa534.pdf distributed by TI. */
995 if (syscall_num
== 2)
997 arg1
= MSP430_CPU (sd
)->state
.regs
[12];
998 arg2
= mem_get_val (sd
, SP
, 16);
999 arg3
= mem_get_val (sd
, SP
+ 2, 16);
1000 arg4
= mem_get_val (sd
, SP
+ 4, 16);
1004 arg1
= MSP430_CPU (sd
)->state
.regs
[12];
1005 arg2
= MSP430_CPU (sd
)->state
.regs
[13];
1006 arg3
= MSP430_CPU (sd
)->state
.regs
[14];
1007 arg4
= MSP430_CPU (sd
)->state
.regs
[15];
1010 MSP430_CPU (sd
)->state
.regs
[12] = sim_syscall (MSP430_CPU (sd
),
1011 syscall_num
, arg1
, arg2
,
1020 msp430_step_once (SIM_DESC sd
)
1022 Get_Byte_Local_Data ld
;
1023 unsigned char buf
[100];
1026 unsigned int opcode_pc
;
1027 MSP430_Opcode_Decoded opcode_buf
;
1028 MSP430_Opcode_Decoded
*opcode
= &opcode_buf
;
1030 int u1
= 0, u2
, uresult
;
1036 int op_bytes
= 0, op_bits
;
1041 if (opcode_pc
< 0x10)
1043 fprintf (stderr
, "Fault: PC(%#x) is less than 0x10\n", opcode_pc
);
1044 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1045 MSP430_CPU (sd
)->state
.regs
[0],
1050 if (PC
== MSP430_CPU (sd
)->state
.cio_breakpoint
1051 && STATE_OPEN_KIND (sd
) != SIM_OPEN_DEBUG
)
1056 opsize
= msp430_decode_opcode (MSP430_CPU (sd
)->state
.regs
[0],
1057 opcode
, msp430_getbyte
, &ld
);
1061 fprintf (stderr
, "Fault: undecodable opcode at %#x\n", opcode_pc
);
1062 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1063 MSP430_CPU (sd
)->state
.regs
[0],
1068 if (opcode
->repeat_reg
)
1069 n_repeats
= (MSP430_CPU (sd
)->state
.regs
[opcode
->repeats
] & 0x000f) + 1;
1071 n_repeats
= opcode
->repeats
+ 1;
1073 op_bits
= opcode
->size
;
1088 if (TRACE_ANY_P (MSP430_CPU (sd
)))
1089 trace_prefix (sd
, MSP430_CPU (sd
), NULL_CIA
, opcode_pc
,
1090 TRACE_LINENUM_P (MSP430_CPU (sd
)), NULL
, 0, " ");
1092 TRACE_DISASM (MSP430_CPU (sd
), opcode_pc
);
1100 /* Double-operand instructions. */
1102 if (opcode
->n_bytes
== 2
1103 && opcode
->op
[0].type
== MSP430_Operand_Register
1104 && opcode
->op
[0].reg
== MSR_CG
1105 && opcode
->op
[1].type
== MSP430_Operand_Immediate
1106 && opcode
->op
[1].addend
== 0
1107 /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK. */
1108 && opcode
->size
== 8)
1110 /* This is the designated software breakpoint instruction. */
1112 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1113 MSP430_CPU (sd
)->state
.regs
[0],
1114 sim_stopped
, SIM_SIGTRAP
);
1119 /* Otherwise, do the move. */
1120 for (rept
= 0; rept
< n_repeats
; rept
++)
1128 for (rept
= 0; rept
< n_repeats
; rept
++)
1130 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1135 uresult
= u1
+ u2
+ carry_to_use
;
1136 result
= s1
+ s2
+ carry_to_use
;
1137 TRACE_ALU (MSP430_CPU (sd
), "ADDC: %#x + %#x + %d = %#x",
1138 u1
, u2
, carry_to_use
, uresult
);
1140 FLAGS (result
, uresult
!= ZX (uresult
));
1145 for (rept
= 0; rept
< n_repeats
; rept
++)
1153 TRACE_ALU (MSP430_CPU (sd
), "ADD: %#x + %#x = %#x",
1156 FLAGS (result
, uresult
!= ZX (uresult
));
1161 for (rept
= 0; rept
< n_repeats
; rept
++)
1163 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1168 uresult
= ZX (~u2
) + u1
+ carry_to_use
;
1169 result
= s1
- s2
+ (carry_to_use
- 1);
1170 TRACE_ALU (MSP430_CPU (sd
), "SUBC: %#x - %#x + %d = %#x",
1171 u1
, u2
, carry_to_use
, uresult
);
1173 FLAGS (result
, uresult
!= ZX (uresult
));
1178 for (rept
= 0; rept
< n_repeats
; rept
++)
1184 uresult
= ZX (~u2
) + u1
+ 1;
1185 result
= SX (uresult
);
1186 TRACE_ALU (MSP430_CPU (sd
), "SUB: %#x - %#x = %#x",
1189 FLAGS (result
, uresult
!= ZX (uresult
));
1194 for (rept
= 0; rept
< n_repeats
; rept
++)
1200 uresult
= ZX (~u2
) + u1
+ 1;
1202 TRACE_ALU (MSP430_CPU (sd
), "CMP: %#x - %#x = %x",
1204 FLAGS (result
, uresult
!= ZX (uresult
));
1209 for (rept
= 0; rept
< n_repeats
; rept
++)
1211 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1214 uresult
= bcd_to_binary (u1
) + bcd_to_binary (u2
) + carry_to_use
;
1215 result
= binary_to_bcd (uresult
);
1216 TRACE_ALU (MSP430_CPU (sd
), "DADD: %#x + %#x + %d = %#x",
1217 u1
, u2
, carry_to_use
, result
);
1219 FLAGS (result
, uresult
> ((opcode
->size
== 8) ? 99 : 9999));
1224 for (rept
= 0; rept
< n_repeats
; rept
++)
1229 TRACE_ALU (MSP430_CPU (sd
), "AND: %#x & %#x = %#x",
1232 FLAGS (uresult
, uresult
!= 0);
1237 for (rept
= 0; rept
< n_repeats
; rept
++)
1242 TRACE_ALU (MSP430_CPU (sd
), "BIT: %#x & %#x -> %#x",
1244 FLAGS (uresult
, uresult
!= 0);
1249 for (rept
= 0; rept
< n_repeats
; rept
++)
1253 uresult
= u1
& ~ u2
;
1254 TRACE_ALU (MSP430_CPU (sd
), "BIC: %#x & ~ %#x = %#x",
1261 for (rept
= 0; rept
< n_repeats
; rept
++)
1266 TRACE_ALU (MSP430_CPU (sd
), "BIS: %#x | %#x = %#x",
1273 for (rept
= 0; rept
< n_repeats
; rept
++)
1275 s1
= 1 << (opcode
->size
- 1);
1279 TRACE_ALU (MSP430_CPU (sd
), "XOR: %#x & %#x = %#x",
1282 FLAGSV (uresult
, uresult
!= 0, (u1
& s1
) && (u2
& s1
));
1286 /* Single-operand instructions. Note: the decoder puts the same
1287 operand in SRC as in DEST, for our convenience. */
1290 for (rept
= 0; rept
< n_repeats
; rept
++)
1293 carry_to_use
= u1
& 1;
1295 if (SR
& MSP430_FLAG_C
)
1296 uresult
|= (1 << (opcode
->size
- 1));
1297 TRACE_ALU (MSP430_CPU (sd
), "RRC: %#x >>= %#x",
1300 FLAGS (uresult
, carry_to_use
);
1305 for (rept
= 0; rept
< n_repeats
; rept
++)
1308 uresult
= ((u1
>> 8) & 0x00ff) | ((u1
<< 8) & 0xff00);
1309 TRACE_ALU (MSP430_CPU (sd
), "SWPB: %#x -> %#x",
1316 for (rept
= 0; rept
< n_repeats
; rept
++)
1320 s1
= 1 << (opcode
->size
- 1);
1321 uresult
= (u1
>> 1) | (u1
& s1
);
1322 TRACE_ALU (MSP430_CPU (sd
), "RRA: %#x >>= %#x",
1330 for (rept
= 0; rept
< n_repeats
; rept
++)
1334 uresult
= (u1
>> 1);
1335 TRACE_ALU (MSP430_CPU (sd
), "RRU: %#x >>= %#x",
1343 for (rept
= 0; rept
< n_repeats
; rept
++)
1347 uresult
= u1
| 0xfff00;
1349 uresult
= u1
& 0x000ff;
1350 TRACE_ALU (MSP430_CPU (sd
), "SXT: %#x -> %#x",
1358 for (rept
= 0; rept
< n_repeats
; rept
++)
1362 new_sp
= REG_GET (MSR_SP
) - op_bytes
;
1363 /* SP is always word-aligned. */
1366 REG_PUT (MSR_SP
, new_sp
);
1368 mem_put_val (sd
, SP
, u1
, op_bits
);
1369 if (opcode
->op
[1].type
== MSP430_Operand_Register
)
1370 opcode
->op
[1].reg
--;
1375 for (rept
= 0; rept
< n_repeats
; rept
++)
1379 u1
= mem_get_val (sd
, SP
, op_bits
);
1381 if (opcode
->op
[0].type
== MSP430_Operand_Register
)
1382 opcode
->op
[0].reg
++;
1383 new_sp
= REG_GET (MSR_SP
) + op_bytes
;
1384 /* SP is always word-aligned. */
1387 REG_PUT (MSR_SP
, new_sp
);
1394 if (maybe_perform_syscall (sd
, u1
))
1397 REG_PUT (MSR_SP
, REG_GET (MSR_SP
) - op_bytes
);
1398 mem_put_val (sd
, SP
, PC
, op_bits
);
1399 TRACE_ALU (MSP430_CPU (sd
), "CALL: func %#x ret %#x, sp %#x",
1401 REG_PUT (MSR_PC
, u1
);
1405 u1
= mem_get_val (sd
, SP
, 16);
1408 PC
= mem_get_val (sd
, SP
, 16);
1410 /* Emulate the RETI action of the 20-bit CPUX architecure.
1411 This is safe for 16-bit CPU architectures as well, since the top
1412 8-bits of SR will have been written to the stack here, and will
1413 have been read as 0. */
1414 PC
|= (u1
& 0xF000) << 4;
1415 TRACE_ALU (MSP430_CPU (sd
), "RETI: pc %#x sr %#x",
1423 switch (opcode
->cond
)
1426 u1
= (SR
& MSP430_FLAG_Z
) ? 0 : 1;
1429 u1
= (SR
& MSP430_FLAG_Z
) ? 1 : 0;
1432 u1
= (SR
& MSP430_FLAG_C
) ? 0 : 1;
1435 u1
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1438 u1
= (SR
& MSP430_FLAG_N
) ? 1 : 0;
1441 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 1 : 0;
1444 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 0 : 1;
1453 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x -> %#x sr %#x, taken",
1454 cond_string (opcode
->cond
), PC
, i
, SR
);
1456 if (PC
== opcode_pc
)
1460 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x to %#x sr %#x, not taken",
1461 cond_string (opcode
->cond
), PC
, i
, SR
);
1465 fprintf (stderr
, "error: unexpected opcode id %d\n", opcode
->id
);
1471 sim_engine_run (SIM_DESC sd
,
1478 msp430_step_once (sd
);
1479 if (sim_events_tick (sd
))
1480 sim_events_process (sd
);