1 /* Simulator for TI MSP430 and MSP430X
3 Copyright (C) 2013-2021 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/>. */
22 /* This must come before any other includes. */
31 #include "opcode/msp430-decode.h"
33 #include "sim-syscall.h"
34 #include "targ-vals.h"
37 msp430_pc_fetch (SIM_CPU
*cpu
)
39 return cpu
->state
.regs
[0];
43 msp430_pc_store (SIM_CPU
*cpu
, sim_cia newpc
)
45 cpu
->state
.regs
[0] = newpc
;
49 msp430_reg_fetch (SIM_CPU
*cpu
, int regno
, unsigned char *buf
, int len
)
51 if (0 <= regno
&& regno
< 16)
55 int val
= cpu
->state
.regs
[regno
];
57 buf
[1] = (val
>> 8) & 0xff;
62 int val
= cpu
->state
.regs
[regno
];
64 buf
[1] = (val
>> 8) & 0xff;
65 buf
[2] = (val
>> 16) & 0x0f; /* Registers are only 20 bits wide. */
77 msp430_reg_store (SIM_CPU
*cpu
, int regno
, unsigned char *buf
, int len
)
79 if (0 <= regno
&& regno
< 16)
83 cpu
->state
.regs
[regno
] = (buf
[1] << 8) | buf
[0];
89 cpu
->state
.regs
[regno
] = ((buf
[2] << 16) & 0xf0000)
90 | (buf
[1] << 8) | buf
[0];
99 msp430_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
101 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
105 sim_open (SIM_OPEN_KIND kind
,
106 struct host_callback_struct
*callback
,
110 SIM_DESC sd
= sim_state_alloc (kind
, callback
);
113 /* Initialise the simulator. */
115 /* Set default options before parsing user options. */
116 current_target_byte_order
= BFD_ENDIAN_LITTLE
;
118 if (sim_cpu_alloc_all (sd
, 1) != SIM_RC_OK
)
124 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
130 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
136 CPU_PC_FETCH (MSP430_CPU (sd
)) = msp430_pc_fetch
;
137 CPU_PC_STORE (MSP430_CPU (sd
)) = msp430_pc_store
;
138 CPU_REG_FETCH (MSP430_CPU (sd
)) = msp430_reg_fetch
;
139 CPU_REG_STORE (MSP430_CPU (sd
)) = msp430_reg_store
;
141 /* Allocate memory if none specified by user.
142 Note - these values match the memory regions in the libgloss/msp430/msp430[xl]-sim.ld scripts. */
143 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x2, 1) == 0)
144 sim_do_commandf (sd
, "memory-region 0,0x20"); /* Needed by the GDB testsuite. */
145 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x500, 1) == 0)
146 sim_do_commandf (sd
, "memory-region 0x500,0xfac0"); /* RAM and/or ROM */
147 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0xfffe, 1) == 0)
148 sim_do_commandf (sd
, "memory-region 0xffc0,0x40"); /* VECTORS. */
149 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x10000, 1) == 0)
150 sim_do_commandf (sd
, "memory-region 0x10000,0x80000"); /* HIGH FLASH RAM. */
151 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x90000, 1) == 0)
152 sim_do_commandf (sd
, "memory-region 0x90000,0x70000"); /* HIGH ROM. */
154 /* Check for/establish the a reference program image. */
155 if (sim_analyze_program (sd
,
156 (STATE_PROG_ARGV (sd
) != NULL
157 ? *STATE_PROG_ARGV (sd
)
158 : NULL
), abfd
) != SIM_RC_OK
)
164 /* Establish any remaining configuration options. */
165 if (sim_config (sd
) != SIM_RC_OK
)
171 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
177 /* CPU specific initialization. */
178 assert (MAX_NR_PROCESSORS
== 1);
179 msp430_initialize_cpu (sd
, MSP430_CPU (sd
));
181 MSP430_CPU (sd
)->state
.cio_breakpoint
= trace_sym_value (sd
, "C$$IO$$");
182 MSP430_CPU (sd
)->state
.cio_buffer
= trace_sym_value (sd
, "__CIOBUF__");
183 if (MSP430_CPU (sd
)->state
.cio_buffer
== -1)
184 MSP430_CPU (sd
)->state
.cio_buffer
= trace_sym_value (sd
, "_CIOBUF_");
190 sim_create_inferior (SIM_DESC sd
,
195 unsigned char resetv
[2];
199 /* Set the PC to the default reset vector if available. */
200 c
= sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, resetv
, 0xfffe, 2);
201 new_pc
= resetv
[0] + 256 * resetv
[1];
203 /* If the reset vector isn't initialized, then use the ELF entry. */
204 if (abfd
!= NULL
&& !new_pc
)
205 new_pc
= bfd_get_start_address (abfd
);
207 sim_pc_set (MSP430_CPU (sd
), new_pc
);
208 msp430_pc_store (MSP430_CPU (sd
), new_pc
);
217 } Get_Byte_Local_Data
;
220 msp430_getbyte (void *vld
)
222 Get_Byte_Local_Data
*ld
= (Get_Byte_Local_Data
*)vld
;
224 SIM_DESC sd
= ld
->sd
;
226 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, ld
->gb_addr
, 1);
231 #define REG(N) MSP430_CPU (sd)->state.regs[(N)]
232 #define PC REG(MSR_PC)
233 #define SP REG(MSR_SP)
234 #define SR REG(MSR_SR)
239 "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8",
240 "R9", "R10", "R11", "R12", "R13", "R14", "R15"
244 trace_reg_put (SIM_DESC sd
, int n
, unsigned int v
)
246 TRACE_REGISTER (MSP430_CPU (sd
), "PUT: %#x -> %s", v
, register_names
[n
]);
251 trace_reg_get (SIM_DESC sd
, int n
)
253 TRACE_REGISTER (MSP430_CPU (sd
), "GET: %s -> %#x", register_names
[n
], REG (n
));
257 #define REG_PUT(N,V) trace_reg_put (sd, N, V)
258 #define REG_GET(N) trace_reg_get (sd, N)
260 /* Hardware multiply (and accumulate) support. */
263 zero_ext (unsigned int v
, unsigned int bits
)
265 v
&= ((1 << bits
) - 1);
269 static signed long long
270 sign_ext (signed long long v
, unsigned int bits
)
272 signed long long sb
= 1LL << (bits
-1); /* Sign bit. */
273 signed long long mb
= (1LL << (bits
-1)) - 1LL; /* Mantissa bits. */
283 get_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
)
285 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
288 unsigned char buf
[4];
293 case MSP430_Operand_Immediate
:
296 case MSP430_Operand_Register
:
297 rv
= REG_GET (op
->reg
);
299 case MSP430_Operand_Indirect
:
300 case MSP430_Operand_Indirect_Postinc
:
302 if (op
->reg
!= MSR_None
)
304 int reg
= REG_GET (op
->reg
);
305 int sign
= opc
->ofs_430x
? 20 : 16;
307 /* Index values are signed. */
308 if (addr
& (1 << (sign
- 1)))
309 addr
|= -(1 << sign
);
313 /* For MSP430 instructions the sum is limited to 16 bits if the
314 address in the index register is less than 64k even if we are
315 running on an MSP430X CPU. This is for MSP430 compatibility. */
316 if (reg
< 0x10000 && ! opc
->ofs_430x
)
319 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on read\n", addr
);
328 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 1);
332 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 2);
333 rv
= buf
[0] | (buf
[1] << 8);
337 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 4);
338 rv
= buf
[0] | (buf
[1] << 8) | (buf
[2] << 16) | (buf
[3] << 24);
341 assert (! opc
->size
);
345 /* Hack - MSP430X5438 serial port status register. */
349 if ((addr
>= 0x130 && addr
<= 0x15B)
350 || (addr
>= 0x4C0 && addr
<= 0x4EB))
356 switch (HWMULT (sd
, hwmult_type
))
360 rv
= zero_ext (HWMULT (sd
, hwmult_result
), 16);
364 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
), 16);
371 switch (HWMULT (sd
, hwmult_type
))
375 rv
= zero_ext (HWMULT (sd
, hwmult_result
) >> 16, 16);
380 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
) >> 16, 16);
387 switch (HWMULT (sd
, hwmult_type
))
393 rv
= HWMULT (sd
, hwmult_signed_result
) < 0 ? -1 : 0;
396 rv
= 0; /* FIXME: Should be carry of last accumulate. */
399 rv
= HWMULT (sd
, hwmult_signed_accumulator
) < 0 ? -1 : 0;
406 rv
= zero_ext (HWMULT (sd
, hw32mult_result
), 16);
411 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 16, 16);
416 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 32, 16);
421 switch (HWMULT (sd
, hw32mult_type
))
423 case UNSIGN_64
: rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 48, 16); break;
424 case SIGN_64
: rv
= sign_ext (HWMULT (sd
, hw32mult_result
) >> 48, 16); break;
429 fprintf (stderr
, "unimplemented HW MULT read from %x!\n", addr
);
434 TRACE_MEMORY (MSP430_CPU (sd
), "GET: [%#x].%d -> %#x", addr
, opc
->size
,
439 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
463 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
464 REG_PUT (op
->reg
, REG_GET (op
->reg
) + incval
);
470 put_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
, int val
)
472 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
475 unsigned char buf
[4];
496 case MSP430_Operand_Register
:
498 REG_PUT (op
->reg
, val
);
500 case MSP430_Operand_Indirect
:
501 case MSP430_Operand_Indirect_Postinc
:
503 if (op
->reg
!= MSR_None
)
505 int reg
= REG_GET (op
->reg
);
506 int sign
= opc
->ofs_430x
? 20 : 16;
508 /* Index values are signed. */
509 if (addr
& (1 << (sign
- 1)))
510 addr
|= -(1 << sign
);
514 /* For MSP430 instructions the sum is limited to 16 bits if the
515 address in the index register is less than 64k even if we are
516 running on an MSP430X CPU. This is for MSP430 compatibility. */
517 if (reg
< 0x10000 && ! opc
->ofs_430x
)
520 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on write\n", addr
);
527 TRACE_MEMORY (MSP430_CPU (sd
), "PUT: [%#x].%d <- %#x", addr
, opc
->size
,
530 /* Hack - MSP430X5438 serial port transmit register. */
534 if ((addr
>= 0x130 && addr
<= 0x15B)
535 || (addr
>= 0x4C0 && addr
<= 0x4EB))
539 /* Hardware Multiply emulation. */
540 assert (opc
->size
== 16);
546 HWMULT (sd
, hwmult_op1
) = val
;
547 HWMULT (sd
, hwmult_type
) = UNSIGN_32
;
552 HWMULT (sd
, hwmult_op1
) = val
;
553 HWMULT (sd
, hwmult_type
) = SIGN_32
;
558 HWMULT (sd
, hwmult_op1
) = val
;
559 HWMULT (sd
, hwmult_type
) = UNSIGN_MAC_32
;
564 HWMULT (sd
, hwmult_op1
) = val
;
565 HWMULT (sd
, hwmult_type
) = SIGN_MAC_32
;
570 HWMULT (sd
, hwmult_op2
) = val
;
571 switch (HWMULT (sd
, hwmult_type
))
574 a
= HWMULT (sd
, hwmult_op1
);
575 b
= HWMULT (sd
, hwmult_op2
);
576 /* For unsigned 32-bit multiplication of 16-bit operands, an
577 explicit cast is required to prevent any implicit
579 HWMULT (sd
, hwmult_result
) = (unsigned32
) a
* (unsigned32
) b
;
580 HWMULT (sd
, hwmult_signed_result
) = a
* b
;
581 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
585 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
586 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
587 HWMULT (sd
, hwmult_signed_result
) = a
* b
;
588 HWMULT (sd
, hwmult_result
) = (unsigned32
) a
* (unsigned32
) b
;
589 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
593 a
= HWMULT (sd
, hwmult_op1
);
594 b
= HWMULT (sd
, hwmult_op2
);
595 HWMULT (sd
, hwmult_accumulator
)
596 += (unsigned32
) a
* (unsigned32
) b
;
597 HWMULT (sd
, hwmult_signed_accumulator
) += a
* b
;
598 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
599 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
603 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
604 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
605 HWMULT (sd
, hwmult_accumulator
)
606 += (unsigned32
) a
* (unsigned32
) b
;
607 HWMULT (sd
, hwmult_signed_accumulator
) += a
* b
;
608 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
609 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
616 /* Copy into LOW result... */
617 switch (HWMULT (sd
, hwmult_type
))
621 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_result
) = zero_ext (val
, 16);
622 HWMULT (sd
, hwmult_signed_accumulator
) = sign_ext (val
, 16);
626 HWMULT (sd
, hwmult_signed_accumulator
) = HWMULT (sd
, hwmult_result
) = sign_ext (val
, 16);
627 HWMULT (sd
, hwmult_accumulator
) = zero_ext (val
, 16);
634 HWMULT (sd
, hw32mult_op1
) = val
;
635 HWMULT (sd
, hw32mult_type
) = UNSIGN_64
;
640 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
645 HWMULT (sd
, hw32mult_op1
) = val
;
646 HWMULT (sd
, hw32mult_type
) = SIGN_64
;
651 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
656 HWMULT (sd
, hw32mult_op2
) = val
;
661 HWMULT (sd
, hw32mult_op2
) = (HWMULT (sd
, hw32mult_op2
) & 0xFFFF) | (val
<< 16);
662 switch (HWMULT (sd
, hw32mult_type
))
665 HWMULT (sd
, hw32mult_result
)
666 = (unsigned64
) HWMULT (sd
, hw32mult_op1
)
667 * (unsigned64
) HWMULT (sd
, hw32mult_op2
);
670 HWMULT (sd
, hw32mult_result
)
671 = sign_ext (HWMULT (sd
, hw32mult_op1
), 32)
672 * sign_ext (HWMULT (sd
, hw32mult_op2
), 32);
678 fprintf (stderr
, "unimplemented HW MULT write to %x!\n", addr
);
687 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 1);
692 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 2);
700 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 4);
703 assert (! opc
->size
);
708 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
732 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
734 int new_val
= REG_GET (op
->reg
) + incval
;
735 /* SP is always word-aligned. */
736 if (op
->reg
== MSR_SP
&& (new_val
& 1))
738 REG_PUT (op
->reg
, new_val
);
745 mem_put_val (SIM_DESC sd
, int addr
, int val
, int bits
)
747 MSP430_Opcode_Decoded opc
;
750 opc
.op
[0].type
= MSP430_Operand_Indirect
;
751 opc
.op
[0].addend
= addr
;
752 opc
.op
[0].reg
= MSR_None
;
753 put_op (sd
, &opc
, 0, val
);
757 mem_get_val (SIM_DESC sd
, int addr
, 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 return get_op (sd
, &opc
, 0);
768 #define CIO_OPEN (0xF0)
769 #define CIO_CLOSE (0xF1)
770 #define CIO_READ (0xF2)
771 #define CIO_WRITE (0xF3)
772 #define CIO_LSEEK (0xF4)
773 #define CIO_UNLINK (0xF5)
774 #define CIO_GETENV (0xF6)
775 #define CIO_RENAME (0xF7)
776 #define CIO_GETTIME (0xF8)
777 #define CIO_GETCLK (0xF9)
778 #define CIO_SYNC (0xFF)
780 #define CIO_I(n) (parms[(n)] + parms[(n)+1] * 256)
781 #define CIO_L(n) (parms[(n)] + parms[(n)+1] * 256 \
782 + parms[(n)+2] * 65536 + parms[(n)+3] * 16777216)
785 msp430_cio (SIM_DESC sd
)
787 /* A block of data at __CIOBUF__ describes the I/O operation to
790 unsigned char raw_parms
[13];
791 unsigned char parms
[8];
794 unsigned char buffer
[512];
796 long fd
, addr
, len
, rv
;
798 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
799 MSP430_CPU (sd
)->state
.cio_buffer
, 5);
803 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
804 MSP430_CPU (sd
)->state
.cio_buffer
+ 3, 8);
806 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
807 MSP430_CPU (sd
)->state
.cio_buffer
+ 11, length
);
815 rv
= write (fd
, buffer
, len
);
816 parms
[0] = rv
& 0xff;
822 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
823 MSP430_CPU (sd
)->state
.cio_buffer
+ 4, 8);
825 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
826 MSP430_CPU (sd
)->state
.cio_buffer
+ 12, ret_buflen
);
829 #define SRC get_op (sd, opcode, 1)
830 #define DSRC get_op (sd, opcode, 0)
831 #define DEST(V) put_op (sd, opcode, 0, (V))
833 #define DO_ALU(OP,SOP,MORE) \
837 int result = s1 OP s2 MORE; \
838 TRACE_ALU (MSP430_CPU (sd), "ALU: %#x %s %#x %s = %#x", s1, SOP, \
839 s2, #MORE, result); \
843 #define SIGN (1 << (opcode->size - 1))
844 #define POS(x) (((x) & SIGN) ? 0 : 1)
845 #define NEG(x) (((x) & SIGN) ? 1 : 0)
847 #define SX(v) sign_ext (v, opcode->size)
848 #define ZX(v) zero_ext (v, opcode->size)
853 static char buf
[2][6];
859 bp
[0] = f
& MSP430_FLAG_V
? 'V' : '-';
860 bp
[1] = f
& MSP430_FLAG_N
? 'N' : '-';
861 bp
[2] = f
& MSP430_FLAG_Z
? 'Z' : '-';
862 bp
[3] = f
& MSP430_FLAG_C
? 'C' : '-';
867 /* Random number that won't show up in our usual logic. */
868 #define MAGIC_OVERFLOW 0x55000F
871 do_flags (SIM_DESC sd
,
872 MSP430_Opcode_Decoded
*opcode
,
873 int vnz_val
, /* Signed result. */
879 int signbit
= 1 << (opcode
->size
- 1);
881 f
&= ~opcode
->flags_0
;
882 f
&= ~opcode
->flags_set
;
883 f
|= opcode
->flags_1
;
885 if (vnz_val
& signbit
)
886 new_f
|= MSP430_FLAG_N
;
887 if (! (vnz_val
& ((signbit
<< 1) - 1)))
888 new_f
|= MSP430_FLAG_Z
;
889 if (overflow
== MAGIC_OVERFLOW
)
891 if (vnz_val
!= SX (vnz_val
))
892 new_f
|= MSP430_FLAG_V
;
896 new_f
|= MSP430_FLAG_V
;
898 new_f
|= MSP430_FLAG_C
;
900 new_f
= f
| (new_f
& opcode
->flags_set
);
902 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s -> %s", flags2string (SR
),
903 flags2string (new_f
));
905 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s", flags2string (new_f
));
909 #define FLAGS(vnz,c) do_flags (sd, opcode, vnz, c, MAGIC_OVERFLOW)
910 #define FLAGSV(vnz,c,v) do_flags (sd, opcode, vnz, c, v)
912 /* These two assume unsigned 16-bit (four digit) words.
913 Mask off unwanted bits for byte operations. */
916 bcd_to_binary (int v
)
918 int r
= ( ((v
>> 0) & 0xf) * 1
919 + ((v
>> 4) & 0xf) * 10
920 + ((v
>> 8) & 0xf) * 100
921 + ((v
>> 12) & 0xf) * 1000);
926 binary_to_bcd (int v
)
928 int r
= ( ((v
/ 1) % 10) << 0
929 | ((v
/ 10) % 10) << 4
930 | ((v
/ 100) % 10) << 8
931 | ((v
/ 1000) % 10) << 12);
936 cond_string (int cond
)
961 /* Checks a CALL to address CALL_ADDR. If this is a special
962 syscall address then the call is simulated and non-zero is
963 returned. Otherwise 0 is returned. */
966 maybe_perform_syscall (SIM_DESC sd
, int call_addr
)
968 if (call_addr
== 0x00160)
972 for (i
= 0; i
< 16; i
++)
975 fprintf (stderr
, "\t");
976 fprintf (stderr
, "R%-2d %05x ", i
, MSP430_CPU (sd
)->state
.regs
[i
]);
979 int sp
= SP
+ (3 - (i
/ 4)) * 2;
980 unsigned char buf
[2];
982 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, sp
, 2);
984 fprintf (stderr
, "\tSP%+d: %04x", sp
- SP
,
985 buf
[0] + buf
[1] * 256);
991 fprintf (stderr
, flags
& 0x100 ? " V" : " -");
992 fprintf (stderr
, flags
& 0x004 ? "N" : "-");
993 fprintf (stderr
, flags
& 0x002 ? "Z" : "-");
994 fprintf (stderr
, flags
& 0x001 ? "C" : "-");
997 fprintf (stderr
, "\n");
1003 if ((call_addr
& ~0x3f) == 0x00180)
1006 int arg1
, arg2
, arg3
, arg4
;
1007 int syscall_num
= call_addr
& 0x3f;
1009 /* syscall_num == 2 is used for the variadic function "open".
1010 The arguments are set up differently for variadic functions.
1011 See slaa534.pdf distributed by TI. */
1012 if (syscall_num
== 2)
1014 arg1
= MSP430_CPU (sd
)->state
.regs
[12];
1015 arg2
= mem_get_val (sd
, SP
, 16);
1016 arg3
= mem_get_val (sd
, SP
+ 2, 16);
1017 arg4
= mem_get_val (sd
, SP
+ 4, 16);
1021 arg1
= MSP430_CPU (sd
)->state
.regs
[12];
1022 arg2
= MSP430_CPU (sd
)->state
.regs
[13];
1023 arg3
= MSP430_CPU (sd
)->state
.regs
[14];
1024 arg4
= MSP430_CPU (sd
)->state
.regs
[15];
1027 MSP430_CPU (sd
)->state
.regs
[12] = sim_syscall (MSP430_CPU (sd
),
1028 syscall_num
, arg1
, arg2
,
1037 msp430_step_once (SIM_DESC sd
)
1039 Get_Byte_Local_Data ld
;
1040 unsigned char buf
[100];
1043 unsigned int opcode_pc
;
1044 MSP430_Opcode_Decoded opcode_buf
;
1045 MSP430_Opcode_Decoded
*opcode
= &opcode_buf
;
1047 int u1
= 0, u2
, uresult
;
1053 int op_bytes
= 0, op_bits
;
1058 if (opcode_pc
< 0x10)
1060 fprintf (stderr
, "Fault: PC(%#x) is less than 0x10\n", opcode_pc
);
1061 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1062 MSP430_CPU (sd
)->state
.regs
[0],
1067 if (PC
== MSP430_CPU (sd
)->state
.cio_breakpoint
1068 && STATE_OPEN_KIND (sd
) != SIM_OPEN_DEBUG
)
1073 opsize
= msp430_decode_opcode (MSP430_CPU (sd
)->state
.regs
[0],
1074 opcode
, msp430_getbyte
, &ld
);
1078 fprintf (stderr
, "Fault: undecodable opcode at %#x\n", opcode_pc
);
1079 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1080 MSP430_CPU (sd
)->state
.regs
[0],
1085 if (opcode
->repeat_reg
)
1086 n_repeats
= (MSP430_CPU (sd
)->state
.regs
[opcode
->repeats
] & 0x000f) + 1;
1088 n_repeats
= opcode
->repeats
+ 1;
1090 op_bits
= opcode
->size
;
1105 if (TRACE_ANY_P (MSP430_CPU (sd
)))
1106 trace_prefix (sd
, MSP430_CPU (sd
), NULL_CIA
, opcode_pc
,
1107 TRACE_LINENUM_P (MSP430_CPU (sd
)), NULL
, 0, " ");
1109 TRACE_DISASM (MSP430_CPU (sd
), opcode_pc
);
1117 /* Double-operand instructions. */
1119 if (opcode
->n_bytes
== 2
1120 && opcode
->op
[0].type
== MSP430_Operand_Register
1121 && opcode
->op
[0].reg
== MSR_CG
1122 && opcode
->op
[1].type
== MSP430_Operand_Immediate
1123 && opcode
->op
[1].addend
== 0
1124 /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK. */
1125 && opcode
->size
== 8)
1127 /* This is the designated software breakpoint instruction. */
1129 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1130 MSP430_CPU (sd
)->state
.regs
[0],
1131 sim_stopped
, SIM_SIGTRAP
);
1136 /* Otherwise, do the move. */
1137 for (rept
= 0; rept
< n_repeats
; rept
++)
1145 for (rept
= 0; rept
< n_repeats
; rept
++)
1147 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1152 uresult
= u1
+ u2
+ carry_to_use
;
1153 result
= s1
+ s2
+ carry_to_use
;
1154 TRACE_ALU (MSP430_CPU (sd
), "ADDC: %#x + %#x + %d = %#x",
1155 u1
, u2
, carry_to_use
, uresult
);
1157 FLAGS (result
, uresult
!= ZX (uresult
));
1162 for (rept
= 0; rept
< n_repeats
; rept
++)
1170 TRACE_ALU (MSP430_CPU (sd
), "ADD: %#x + %#x = %#x",
1173 FLAGS (result
, uresult
!= ZX (uresult
));
1178 for (rept
= 0; rept
< n_repeats
; rept
++)
1180 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1185 uresult
= ZX (~u2
) + u1
+ carry_to_use
;
1186 result
= s1
- s2
+ (carry_to_use
- 1);
1187 TRACE_ALU (MSP430_CPU (sd
), "SUBC: %#x - %#x + %d = %#x",
1188 u1
, u2
, carry_to_use
, uresult
);
1190 FLAGS (result
, uresult
!= ZX (uresult
));
1195 for (rept
= 0; rept
< n_repeats
; rept
++)
1201 uresult
= ZX (~u2
) + u1
+ 1;
1202 result
= SX (uresult
);
1203 TRACE_ALU (MSP430_CPU (sd
), "SUB: %#x - %#x = %#x",
1206 FLAGS (result
, uresult
!= ZX (uresult
));
1211 for (rept
= 0; rept
< n_repeats
; rept
++)
1217 uresult
= ZX (~u2
) + u1
+ 1;
1219 TRACE_ALU (MSP430_CPU (sd
), "CMP: %#x - %#x = %x",
1221 FLAGS (result
, uresult
!= ZX (uresult
));
1226 for (rept
= 0; rept
< n_repeats
; rept
++)
1228 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1231 uresult
= bcd_to_binary (u1
) + bcd_to_binary (u2
) + carry_to_use
;
1232 result
= binary_to_bcd (uresult
);
1233 TRACE_ALU (MSP430_CPU (sd
), "DADD: %#x + %#x + %d = %#x",
1234 u1
, u2
, carry_to_use
, result
);
1236 FLAGS (result
, uresult
> ((opcode
->size
== 8) ? 99 : 9999));
1241 for (rept
= 0; rept
< n_repeats
; rept
++)
1246 TRACE_ALU (MSP430_CPU (sd
), "AND: %#x & %#x = %#x",
1249 FLAGS (uresult
, uresult
!= 0);
1254 for (rept
= 0; rept
< n_repeats
; rept
++)
1259 TRACE_ALU (MSP430_CPU (sd
), "BIT: %#x & %#x -> %#x",
1261 FLAGS (uresult
, uresult
!= 0);
1266 for (rept
= 0; rept
< n_repeats
; rept
++)
1270 uresult
= u1
& ~ u2
;
1271 TRACE_ALU (MSP430_CPU (sd
), "BIC: %#x & ~ %#x = %#x",
1278 for (rept
= 0; rept
< n_repeats
; rept
++)
1283 TRACE_ALU (MSP430_CPU (sd
), "BIS: %#x | %#x = %#x",
1290 for (rept
= 0; rept
< n_repeats
; rept
++)
1292 s1
= 1 << (opcode
->size
- 1);
1296 TRACE_ALU (MSP430_CPU (sd
), "XOR: %#x & %#x = %#x",
1299 FLAGSV (uresult
, uresult
!= 0, (u1
& s1
) && (u2
& s1
));
1303 /* Single-operand instructions. Note: the decoder puts the same
1304 operand in SRC as in DEST, for our convenience. */
1307 for (rept
= 0; rept
< n_repeats
; rept
++)
1310 carry_to_use
= u1
& 1;
1312 /* If the ZC bit of the opcode is set, it means we are synthesizing
1313 RRUX, so the carry bit must be ignored. */
1314 if (opcode
->zc
== 0 && (SR
& MSP430_FLAG_C
))
1315 uresult
|= (1 << (opcode
->size
- 1));
1316 TRACE_ALU (MSP430_CPU (sd
), "RRC: %#x >>= %#x",
1319 FLAGS (uresult
, carry_to_use
);
1324 for (rept
= 0; rept
< n_repeats
; rept
++)
1327 uresult
= ((u1
>> 8) & 0x00ff) | ((u1
<< 8) & 0xff00);
1328 TRACE_ALU (MSP430_CPU (sd
), "SWPB: %#x -> %#x",
1335 for (rept
= 0; rept
< n_repeats
; rept
++)
1339 s1
= 1 << (opcode
->size
- 1);
1340 uresult
= (u1
>> 1) | (u1
& s1
);
1341 TRACE_ALU (MSP430_CPU (sd
), "RRA: %#x >>= %#x",
1349 for (rept
= 0; rept
< n_repeats
; rept
++)
1353 uresult
= (u1
>> 1);
1354 TRACE_ALU (MSP430_CPU (sd
), "RRU: %#x >>= %#x",
1362 for (rept
= 0; rept
< n_repeats
; rept
++)
1366 uresult
= u1
| 0xfff00;
1368 uresult
= u1
& 0x000ff;
1369 TRACE_ALU (MSP430_CPU (sd
), "SXT: %#x -> %#x",
1377 for (rept
= 0; rept
< n_repeats
; rept
++)
1381 new_sp
= REG_GET (MSR_SP
) - op_bytes
;
1382 /* SP is always word-aligned. */
1385 REG_PUT (MSR_SP
, new_sp
);
1387 mem_put_val (sd
, SP
, u1
, op_bits
);
1388 if (opcode
->op
[1].type
== MSP430_Operand_Register
)
1389 opcode
->op
[1].reg
--;
1394 for (rept
= 0; rept
< n_repeats
; rept
++)
1398 u1
= mem_get_val (sd
, SP
, op_bits
);
1400 if (opcode
->op
[0].type
== MSP430_Operand_Register
)
1401 opcode
->op
[0].reg
++;
1402 new_sp
= REG_GET (MSR_SP
) + op_bytes
;
1403 /* SP is always word-aligned. */
1406 REG_PUT (MSR_SP
, new_sp
);
1413 if (maybe_perform_syscall (sd
, u1
))
1416 REG_PUT (MSR_SP
, REG_GET (MSR_SP
) - op_bytes
);
1417 mem_put_val (sd
, SP
, PC
, op_bits
);
1418 TRACE_ALU (MSP430_CPU (sd
), "CALL: func %#x ret %#x, sp %#x",
1420 REG_PUT (MSR_PC
, u1
);
1424 u1
= mem_get_val (sd
, SP
, 16);
1427 PC
= mem_get_val (sd
, SP
, 16);
1429 /* Emulate the RETI action of the 20-bit CPUX architecure.
1430 This is safe for 16-bit CPU architectures as well, since the top
1431 8-bits of SR will have been written to the stack here, and will
1432 have been read as 0. */
1433 PC
|= (u1
& 0xF000) << 4;
1434 TRACE_ALU (MSP430_CPU (sd
), "RETI: pc %#x sr %#x",
1442 switch (opcode
->cond
)
1445 u1
= (SR
& MSP430_FLAG_Z
) ? 0 : 1;
1448 u1
= (SR
& MSP430_FLAG_Z
) ? 1 : 0;
1451 u1
= (SR
& MSP430_FLAG_C
) ? 0 : 1;
1454 u1
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1457 u1
= (SR
& MSP430_FLAG_N
) ? 1 : 0;
1460 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 1 : 0;
1463 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 0 : 1;
1472 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x -> %#x sr %#x, taken",
1473 cond_string (opcode
->cond
), PC
, i
, SR
);
1475 if (PC
== opcode_pc
)
1479 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x to %#x sr %#x, not taken",
1480 cond_string (opcode
->cond
), PC
, i
, SR
);
1484 fprintf (stderr
, "error: unexpected opcode id %d\n", opcode
->id
);
1490 sim_engine_run (SIM_DESC sd
,
1497 msp430_step_once (sd
);
1498 if (sim_events_tick (sd
))
1499 sim_events_process (sd
);