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 if (sim_cpu_alloc_all (sd
, 1) != SIM_RC_OK
)
121 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
127 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
133 CPU_PC_FETCH (MSP430_CPU (sd
)) = msp430_pc_fetch
;
134 CPU_PC_STORE (MSP430_CPU (sd
)) = msp430_pc_store
;
135 CPU_REG_FETCH (MSP430_CPU (sd
)) = msp430_reg_fetch
;
136 CPU_REG_STORE (MSP430_CPU (sd
)) = msp430_reg_store
;
138 /* Allocate memory if none specified by user.
139 Note - these values match the memory regions in the libgloss/msp430/msp430[xl]-sim.ld scripts. */
140 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x2, 1) == 0)
141 sim_do_commandf (sd
, "memory-region 0,0x20"); /* Needed by the GDB testsuite. */
142 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x500, 1) == 0)
143 sim_do_commandf (sd
, "memory-region 0x500,0xfac0"); /* RAM and/or ROM */
144 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0xfffe, 1) == 0)
145 sim_do_commandf (sd
, "memory-region 0xffc0,0x40"); /* VECTORS. */
146 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x10000, 1) == 0)
147 sim_do_commandf (sd
, "memory-region 0x10000,0x80000"); /* HIGH FLASH RAM. */
148 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x90000, 1) == 0)
149 sim_do_commandf (sd
, "memory-region 0x90000,0x70000"); /* HIGH ROM. */
151 /* Check for/establish the a reference program image. */
152 if (sim_analyze_program (sd
,
153 (STATE_PROG_ARGV (sd
) != NULL
154 ? *STATE_PROG_ARGV (sd
)
155 : NULL
), abfd
) != SIM_RC_OK
)
161 /* Establish any remaining configuration options. */
162 if (sim_config (sd
) != SIM_RC_OK
)
168 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
174 /* CPU specific initialization. */
175 assert (MAX_NR_PROCESSORS
== 1);
176 msp430_initialize_cpu (sd
, MSP430_CPU (sd
));
178 MSP430_CPU (sd
)->state
.cio_breakpoint
= trace_sym_value (sd
, "C$$IO$$");
179 MSP430_CPU (sd
)->state
.cio_buffer
= trace_sym_value (sd
, "__CIOBUF__");
180 if (MSP430_CPU (sd
)->state
.cio_buffer
== -1)
181 MSP430_CPU (sd
)->state
.cio_buffer
= trace_sym_value (sd
, "_CIOBUF_");
187 sim_create_inferior (SIM_DESC sd
,
192 unsigned char resetv
[2];
196 /* Set the PC to the default reset vector if available. */
197 c
= sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, resetv
, 0xfffe, 2);
198 new_pc
= resetv
[0] + 256 * resetv
[1];
200 /* If the reset vector isn't initialized, then use the ELF entry. */
201 if (abfd
!= NULL
&& !new_pc
)
202 new_pc
= bfd_get_start_address (abfd
);
204 sim_pc_set (MSP430_CPU (sd
), new_pc
);
205 msp430_pc_store (MSP430_CPU (sd
), new_pc
);
214 } Get_Byte_Local_Data
;
217 msp430_getbyte (void *vld
)
219 Get_Byte_Local_Data
*ld
= (Get_Byte_Local_Data
*)vld
;
221 SIM_DESC sd
= ld
->sd
;
223 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, ld
->gb_addr
, 1);
228 #define REG(N) MSP430_CPU (sd)->state.regs[(N)]
229 #define PC REG(MSR_PC)
230 #define SP REG(MSR_SP)
231 #define SR REG(MSR_SR)
236 "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8",
237 "R9", "R10", "R11", "R12", "R13", "R14", "R15"
241 trace_reg_put (SIM_DESC sd
, int n
, unsigned int v
)
243 TRACE_REGISTER (MSP430_CPU (sd
), "PUT: %#x -> %s", v
, register_names
[n
]);
248 trace_reg_get (SIM_DESC sd
, int n
)
250 TRACE_REGISTER (MSP430_CPU (sd
), "GET: %s -> %#x", register_names
[n
], REG (n
));
254 #define REG_PUT(N,V) trace_reg_put (sd, N, V)
255 #define REG_GET(N) trace_reg_get (sd, N)
257 /* Hardware multiply (and accumulate) support. */
260 zero_ext (unsigned int v
, unsigned int bits
)
262 v
&= ((1 << bits
) - 1);
266 static signed long long
267 sign_ext (signed long long v
, unsigned int bits
)
269 signed long long sb
= 1LL << (bits
-1); /* Sign bit. */
270 signed long long mb
= (1LL << (bits
-1)) - 1LL; /* Mantissa bits. */
280 get_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
)
282 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
285 unsigned char buf
[4];
290 case MSP430_Operand_Immediate
:
293 case MSP430_Operand_Register
:
294 rv
= REG_GET (op
->reg
);
296 case MSP430_Operand_Indirect
:
297 case MSP430_Operand_Indirect_Postinc
:
299 if (op
->reg
!= MSR_None
)
301 int reg
= REG_GET (op
->reg
);
302 int sign
= opc
->ofs_430x
? 20 : 16;
304 /* Index values are signed. */
305 if (addr
& (1 << (sign
- 1)))
306 addr
|= -(1 << sign
);
310 /* For MSP430 instructions the sum is limited to 16 bits if the
311 address in the index register is less than 64k even if we are
312 running on an MSP430X CPU. This is for MSP430 compatibility. */
313 if (reg
< 0x10000 && ! opc
->ofs_430x
)
316 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on read\n", addr
);
325 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 1);
329 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 2);
330 rv
= buf
[0] | (buf
[1] << 8);
334 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 4);
335 rv
= buf
[0] | (buf
[1] << 8) | (buf
[2] << 16) | (buf
[3] << 24);
338 assert (! opc
->size
);
342 /* Hack - MSP430X5438 serial port status register. */
346 if ((addr
>= 0x130 && addr
<= 0x15B)
347 || (addr
>= 0x4C0 && addr
<= 0x4EB))
353 switch (HWMULT (sd
, hwmult_type
))
357 rv
= zero_ext (HWMULT (sd
, hwmult_result
), 16);
361 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
), 16);
368 switch (HWMULT (sd
, hwmult_type
))
372 rv
= zero_ext (HWMULT (sd
, hwmult_result
) >> 16, 16);
377 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
) >> 16, 16);
384 switch (HWMULT (sd
, hwmult_type
))
390 rv
= HWMULT (sd
, hwmult_signed_result
) < 0 ? -1 : 0;
393 rv
= 0; /* FIXME: Should be carry of last accumulate. */
396 rv
= HWMULT (sd
, hwmult_signed_accumulator
) < 0 ? -1 : 0;
403 rv
= zero_ext (HWMULT (sd
, hw32mult_result
), 16);
408 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 16, 16);
413 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 32, 16);
418 switch (HWMULT (sd
, hw32mult_type
))
420 case UNSIGN_64
: rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 48, 16); break;
421 case SIGN_64
: rv
= sign_ext (HWMULT (sd
, hw32mult_result
) >> 48, 16); break;
426 fprintf (stderr
, "unimplemented HW MULT read from %x!\n", addr
);
431 TRACE_MEMORY (MSP430_CPU (sd
), "GET: [%#x].%d -> %#x", addr
, opc
->size
,
436 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
460 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
461 REG_PUT (op
->reg
, REG_GET (op
->reg
) + incval
);
467 put_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
, int val
)
469 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
472 unsigned char buf
[4];
493 case MSP430_Operand_Register
:
495 REG_PUT (op
->reg
, val
);
497 case MSP430_Operand_Indirect
:
498 case MSP430_Operand_Indirect_Postinc
:
500 if (op
->reg
!= MSR_None
)
502 int reg
= REG_GET (op
->reg
);
503 int sign
= opc
->ofs_430x
? 20 : 16;
505 /* Index values are signed. */
506 if (addr
& (1 << (sign
- 1)))
507 addr
|= -(1 << sign
);
511 /* For MSP430 instructions the sum is limited to 16 bits if the
512 address in the index register is less than 64k even if we are
513 running on an MSP430X CPU. This is for MSP430 compatibility. */
514 if (reg
< 0x10000 && ! opc
->ofs_430x
)
517 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on write\n", addr
);
524 TRACE_MEMORY (MSP430_CPU (sd
), "PUT: [%#x].%d <- %#x", addr
, opc
->size
,
527 /* Hack - MSP430X5438 serial port transmit register. */
531 if ((addr
>= 0x130 && addr
<= 0x15B)
532 || (addr
>= 0x4C0 && addr
<= 0x4EB))
536 /* Hardware Multiply emulation. */
537 assert (opc
->size
== 16);
543 HWMULT (sd
, hwmult_op1
) = val
;
544 HWMULT (sd
, hwmult_type
) = UNSIGN_32
;
549 HWMULT (sd
, hwmult_op1
) = val
;
550 HWMULT (sd
, hwmult_type
) = SIGN_32
;
555 HWMULT (sd
, hwmult_op1
) = val
;
556 HWMULT (sd
, hwmult_type
) = UNSIGN_MAC_32
;
561 HWMULT (sd
, hwmult_op1
) = val
;
562 HWMULT (sd
, hwmult_type
) = SIGN_MAC_32
;
567 HWMULT (sd
, hwmult_op2
) = val
;
568 switch (HWMULT (sd
, hwmult_type
))
571 a
= HWMULT (sd
, hwmult_op1
);
572 b
= HWMULT (sd
, hwmult_op2
);
573 /* For unsigned 32-bit multiplication of 16-bit operands, an
574 explicit cast is required to prevent any implicit
576 HWMULT (sd
, hwmult_result
) = (unsigned32
) a
* (unsigned32
) b
;
577 HWMULT (sd
, hwmult_signed_result
) = a
* b
;
578 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
582 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
583 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
584 HWMULT (sd
, hwmult_signed_result
) = a
* b
;
585 HWMULT (sd
, hwmult_result
) = (unsigned32
) a
* (unsigned32
) b
;
586 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
590 a
= HWMULT (sd
, hwmult_op1
);
591 b
= HWMULT (sd
, hwmult_op2
);
592 HWMULT (sd
, hwmult_accumulator
)
593 += (unsigned32
) a
* (unsigned32
) b
;
594 HWMULT (sd
, hwmult_signed_accumulator
) += a
* b
;
595 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
596 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
600 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
601 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
602 HWMULT (sd
, hwmult_accumulator
)
603 += (unsigned32
) a
* (unsigned32
) b
;
604 HWMULT (sd
, hwmult_signed_accumulator
) += a
* b
;
605 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
606 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
613 /* Copy into LOW result... */
614 switch (HWMULT (sd
, hwmult_type
))
618 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_result
) = zero_ext (val
, 16);
619 HWMULT (sd
, hwmult_signed_accumulator
) = sign_ext (val
, 16);
623 HWMULT (sd
, hwmult_signed_accumulator
) = HWMULT (sd
, hwmult_result
) = sign_ext (val
, 16);
624 HWMULT (sd
, hwmult_accumulator
) = zero_ext (val
, 16);
631 HWMULT (sd
, hw32mult_op1
) = val
;
632 HWMULT (sd
, hw32mult_type
) = UNSIGN_64
;
637 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
642 HWMULT (sd
, hw32mult_op1
) = val
;
643 HWMULT (sd
, hw32mult_type
) = SIGN_64
;
648 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
653 HWMULT (sd
, hw32mult_op2
) = val
;
658 HWMULT (sd
, hw32mult_op2
) = (HWMULT (sd
, hw32mult_op2
) & 0xFFFF) | (val
<< 16);
659 switch (HWMULT (sd
, hw32mult_type
))
662 HWMULT (sd
, hw32mult_result
)
663 = (unsigned64
) HWMULT (sd
, hw32mult_op1
)
664 * (unsigned64
) HWMULT (sd
, hw32mult_op2
);
667 HWMULT (sd
, hw32mult_result
)
668 = sign_ext (HWMULT (sd
, hw32mult_op1
), 32)
669 * sign_ext (HWMULT (sd
, hw32mult_op2
), 32);
675 fprintf (stderr
, "unimplemented HW MULT write to %x!\n", addr
);
684 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 1);
689 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 2);
697 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 4);
700 assert (! opc
->size
);
705 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
729 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
731 int new_val
= REG_GET (op
->reg
) + incval
;
732 /* SP is always word-aligned. */
733 if (op
->reg
== MSR_SP
&& (new_val
& 1))
735 REG_PUT (op
->reg
, new_val
);
742 mem_put_val (SIM_DESC sd
, int addr
, int val
, int bits
)
744 MSP430_Opcode_Decoded opc
;
747 opc
.op
[0].type
= MSP430_Operand_Indirect
;
748 opc
.op
[0].addend
= addr
;
749 opc
.op
[0].reg
= MSR_None
;
750 put_op (sd
, &opc
, 0, val
);
754 mem_get_val (SIM_DESC sd
, int addr
, int bits
)
756 MSP430_Opcode_Decoded opc
;
759 opc
.op
[0].type
= MSP430_Operand_Indirect
;
760 opc
.op
[0].addend
= addr
;
761 opc
.op
[0].reg
= MSR_None
;
762 return get_op (sd
, &opc
, 0);
765 #define CIO_OPEN (0xF0)
766 #define CIO_CLOSE (0xF1)
767 #define CIO_READ (0xF2)
768 #define CIO_WRITE (0xF3)
769 #define CIO_LSEEK (0xF4)
770 #define CIO_UNLINK (0xF5)
771 #define CIO_GETENV (0xF6)
772 #define CIO_RENAME (0xF7)
773 #define CIO_GETTIME (0xF8)
774 #define CIO_GETCLK (0xF9)
775 #define CIO_SYNC (0xFF)
777 #define CIO_I(n) (parms[(n)] + parms[(n)+1] * 256)
778 #define CIO_L(n) (parms[(n)] + parms[(n)+1] * 256 \
779 + parms[(n)+2] * 65536 + parms[(n)+3] * 16777216)
782 msp430_cio (SIM_DESC sd
)
784 /* A block of data at __CIOBUF__ describes the I/O operation to
787 unsigned char raw_parms
[13];
788 unsigned char parms
[8];
791 unsigned char buffer
[512];
793 long fd
, addr
, len
, rv
;
795 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
796 MSP430_CPU (sd
)->state
.cio_buffer
, 5);
800 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
801 MSP430_CPU (sd
)->state
.cio_buffer
+ 3, 8);
803 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
804 MSP430_CPU (sd
)->state
.cio_buffer
+ 11, length
);
812 rv
= write (fd
, buffer
, len
);
813 parms
[0] = rv
& 0xff;
819 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
820 MSP430_CPU (sd
)->state
.cio_buffer
+ 4, 8);
822 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
823 MSP430_CPU (sd
)->state
.cio_buffer
+ 12, ret_buflen
);
826 #define SRC get_op (sd, opcode, 1)
827 #define DSRC get_op (sd, opcode, 0)
828 #define DEST(V) put_op (sd, opcode, 0, (V))
830 #define DO_ALU(OP,SOP,MORE) \
834 int result = s1 OP s2 MORE; \
835 TRACE_ALU (MSP430_CPU (sd), "ALU: %#x %s %#x %s = %#x", s1, SOP, \
836 s2, #MORE, result); \
840 #define SIGN (1 << (opcode->size - 1))
841 #define POS(x) (((x) & SIGN) ? 0 : 1)
842 #define NEG(x) (((x) & SIGN) ? 1 : 0)
844 #define SX(v) sign_ext (v, opcode->size)
845 #define ZX(v) zero_ext (v, opcode->size)
850 static char buf
[2][6];
856 bp
[0] = f
& MSP430_FLAG_V
? 'V' : '-';
857 bp
[1] = f
& MSP430_FLAG_N
? 'N' : '-';
858 bp
[2] = f
& MSP430_FLAG_Z
? 'Z' : '-';
859 bp
[3] = f
& MSP430_FLAG_C
? 'C' : '-';
864 /* Random number that won't show up in our usual logic. */
865 #define MAGIC_OVERFLOW 0x55000F
868 do_flags (SIM_DESC sd
,
869 MSP430_Opcode_Decoded
*opcode
,
870 int vnz_val
, /* Signed result. */
876 int signbit
= 1 << (opcode
->size
- 1);
878 f
&= ~opcode
->flags_0
;
879 f
&= ~opcode
->flags_set
;
880 f
|= opcode
->flags_1
;
882 if (vnz_val
& signbit
)
883 new_f
|= MSP430_FLAG_N
;
884 if (! (vnz_val
& ((signbit
<< 1) - 1)))
885 new_f
|= MSP430_FLAG_Z
;
886 if (overflow
== MAGIC_OVERFLOW
)
888 if (vnz_val
!= SX (vnz_val
))
889 new_f
|= MSP430_FLAG_V
;
893 new_f
|= MSP430_FLAG_V
;
895 new_f
|= MSP430_FLAG_C
;
897 new_f
= f
| (new_f
& opcode
->flags_set
);
899 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s -> %s", flags2string (SR
),
900 flags2string (new_f
));
902 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s", flags2string (new_f
));
906 #define FLAGS(vnz,c) do_flags (sd, opcode, vnz, c, MAGIC_OVERFLOW)
907 #define FLAGSV(vnz,c,v) do_flags (sd, opcode, vnz, c, v)
909 /* These two assume unsigned 16-bit (four digit) words.
910 Mask off unwanted bits for byte operations. */
913 bcd_to_binary (int v
)
915 int r
= ( ((v
>> 0) & 0xf) * 1
916 + ((v
>> 4) & 0xf) * 10
917 + ((v
>> 8) & 0xf) * 100
918 + ((v
>> 12) & 0xf) * 1000);
923 binary_to_bcd (int v
)
925 int r
= ( ((v
/ 1) % 10) << 0
926 | ((v
/ 10) % 10) << 4
927 | ((v
/ 100) % 10) << 8
928 | ((v
/ 1000) % 10) << 12);
933 cond_string (int cond
)
958 /* Checks a CALL to address CALL_ADDR. If this is a special
959 syscall address then the call is simulated and non-zero is
960 returned. Otherwise 0 is returned. */
963 maybe_perform_syscall (SIM_DESC sd
, int call_addr
)
965 if (call_addr
== 0x00160)
969 for (i
= 0; i
< 16; i
++)
972 fprintf (stderr
, "\t");
973 fprintf (stderr
, "R%-2d %05x ", i
, MSP430_CPU (sd
)->state
.regs
[i
]);
976 int sp
= SP
+ (3 - (i
/ 4)) * 2;
977 unsigned char buf
[2];
979 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, sp
, 2);
981 fprintf (stderr
, "\tSP%+d: %04x", sp
- SP
,
982 buf
[0] + buf
[1] * 256);
988 fprintf (stderr
, flags
& 0x100 ? " V" : " -");
989 fprintf (stderr
, flags
& 0x004 ? "N" : "-");
990 fprintf (stderr
, flags
& 0x002 ? "Z" : "-");
991 fprintf (stderr
, flags
& 0x001 ? "C" : "-");
994 fprintf (stderr
, "\n");
1000 if ((call_addr
& ~0x3f) == 0x00180)
1003 int arg1
, arg2
, arg3
, arg4
;
1004 int syscall_num
= call_addr
& 0x3f;
1006 /* syscall_num == 2 is used for the variadic function "open".
1007 The arguments are set up differently for variadic functions.
1008 See slaa534.pdf distributed by TI. */
1009 if (syscall_num
== 2)
1011 arg1
= MSP430_CPU (sd
)->state
.regs
[12];
1012 arg2
= mem_get_val (sd
, SP
, 16);
1013 arg3
= mem_get_val (sd
, SP
+ 2, 16);
1014 arg4
= mem_get_val (sd
, SP
+ 4, 16);
1018 arg1
= MSP430_CPU (sd
)->state
.regs
[12];
1019 arg2
= MSP430_CPU (sd
)->state
.regs
[13];
1020 arg3
= MSP430_CPU (sd
)->state
.regs
[14];
1021 arg4
= MSP430_CPU (sd
)->state
.regs
[15];
1024 MSP430_CPU (sd
)->state
.regs
[12] = sim_syscall (MSP430_CPU (sd
),
1025 syscall_num
, arg1
, arg2
,
1034 msp430_step_once (SIM_DESC sd
)
1036 Get_Byte_Local_Data ld
;
1037 unsigned char buf
[100];
1040 unsigned int opcode_pc
;
1041 MSP430_Opcode_Decoded opcode_buf
;
1042 MSP430_Opcode_Decoded
*opcode
= &opcode_buf
;
1044 int u1
= 0, u2
, uresult
;
1050 int op_bytes
= 0, op_bits
;
1055 if (opcode_pc
< 0x10)
1057 fprintf (stderr
, "Fault: PC(%#x) is less than 0x10\n", opcode_pc
);
1058 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1059 MSP430_CPU (sd
)->state
.regs
[0],
1064 if (PC
== MSP430_CPU (sd
)->state
.cio_breakpoint
1065 && STATE_OPEN_KIND (sd
) != SIM_OPEN_DEBUG
)
1070 opsize
= msp430_decode_opcode (MSP430_CPU (sd
)->state
.regs
[0],
1071 opcode
, msp430_getbyte
, &ld
);
1075 fprintf (stderr
, "Fault: undecodable opcode at %#x\n", opcode_pc
);
1076 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1077 MSP430_CPU (sd
)->state
.regs
[0],
1082 if (opcode
->repeat_reg
)
1083 n_repeats
= (MSP430_CPU (sd
)->state
.regs
[opcode
->repeats
] & 0x000f) + 1;
1085 n_repeats
= opcode
->repeats
+ 1;
1087 op_bits
= opcode
->size
;
1102 if (TRACE_ANY_P (MSP430_CPU (sd
)))
1103 trace_prefix (sd
, MSP430_CPU (sd
), NULL_CIA
, opcode_pc
,
1104 TRACE_LINENUM_P (MSP430_CPU (sd
)), NULL
, 0, " ");
1106 TRACE_DISASM (MSP430_CPU (sd
), opcode_pc
);
1114 /* Double-operand instructions. */
1116 if (opcode
->n_bytes
== 2
1117 && opcode
->op
[0].type
== MSP430_Operand_Register
1118 && opcode
->op
[0].reg
== MSR_CG
1119 && opcode
->op
[1].type
== MSP430_Operand_Immediate
1120 && opcode
->op
[1].addend
== 0
1121 /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK. */
1122 && opcode
->size
== 8)
1124 /* This is the designated software breakpoint instruction. */
1126 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1127 MSP430_CPU (sd
)->state
.regs
[0],
1128 sim_stopped
, SIM_SIGTRAP
);
1133 /* Otherwise, do the move. */
1134 for (rept
= 0; rept
< n_repeats
; rept
++)
1142 for (rept
= 0; rept
< n_repeats
; rept
++)
1144 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1149 uresult
= u1
+ u2
+ carry_to_use
;
1150 result
= s1
+ s2
+ carry_to_use
;
1151 TRACE_ALU (MSP430_CPU (sd
), "ADDC: %#x + %#x + %d = %#x",
1152 u1
, u2
, carry_to_use
, uresult
);
1154 FLAGS (result
, uresult
!= ZX (uresult
));
1159 for (rept
= 0; rept
< n_repeats
; rept
++)
1167 TRACE_ALU (MSP430_CPU (sd
), "ADD: %#x + %#x = %#x",
1170 FLAGS (result
, uresult
!= ZX (uresult
));
1175 for (rept
= 0; rept
< n_repeats
; rept
++)
1177 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1182 uresult
= ZX (~u2
) + u1
+ carry_to_use
;
1183 result
= s1
- s2
+ (carry_to_use
- 1);
1184 TRACE_ALU (MSP430_CPU (sd
), "SUBC: %#x - %#x + %d = %#x",
1185 u1
, u2
, carry_to_use
, uresult
);
1187 FLAGS (result
, uresult
!= ZX (uresult
));
1192 for (rept
= 0; rept
< n_repeats
; rept
++)
1198 uresult
= ZX (~u2
) + u1
+ 1;
1199 result
= SX (uresult
);
1200 TRACE_ALU (MSP430_CPU (sd
), "SUB: %#x - %#x = %#x",
1203 FLAGS (result
, uresult
!= ZX (uresult
));
1208 for (rept
= 0; rept
< n_repeats
; rept
++)
1214 uresult
= ZX (~u2
) + u1
+ 1;
1216 TRACE_ALU (MSP430_CPU (sd
), "CMP: %#x - %#x = %x",
1218 FLAGS (result
, uresult
!= ZX (uresult
));
1223 for (rept
= 0; rept
< n_repeats
; rept
++)
1225 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1228 uresult
= bcd_to_binary (u1
) + bcd_to_binary (u2
) + carry_to_use
;
1229 result
= binary_to_bcd (uresult
);
1230 TRACE_ALU (MSP430_CPU (sd
), "DADD: %#x + %#x + %d = %#x",
1231 u1
, u2
, carry_to_use
, result
);
1233 FLAGS (result
, uresult
> ((opcode
->size
== 8) ? 99 : 9999));
1238 for (rept
= 0; rept
< n_repeats
; rept
++)
1243 TRACE_ALU (MSP430_CPU (sd
), "AND: %#x & %#x = %#x",
1246 FLAGS (uresult
, uresult
!= 0);
1251 for (rept
= 0; rept
< n_repeats
; rept
++)
1256 TRACE_ALU (MSP430_CPU (sd
), "BIT: %#x & %#x -> %#x",
1258 FLAGS (uresult
, uresult
!= 0);
1263 for (rept
= 0; rept
< n_repeats
; rept
++)
1267 uresult
= u1
& ~ u2
;
1268 TRACE_ALU (MSP430_CPU (sd
), "BIC: %#x & ~ %#x = %#x",
1275 for (rept
= 0; rept
< n_repeats
; rept
++)
1280 TRACE_ALU (MSP430_CPU (sd
), "BIS: %#x | %#x = %#x",
1287 for (rept
= 0; rept
< n_repeats
; rept
++)
1289 s1
= 1 << (opcode
->size
- 1);
1293 TRACE_ALU (MSP430_CPU (sd
), "XOR: %#x & %#x = %#x",
1296 FLAGSV (uresult
, uresult
!= 0, (u1
& s1
) && (u2
& s1
));
1300 /* Single-operand instructions. Note: the decoder puts the same
1301 operand in SRC as in DEST, for our convenience. */
1304 for (rept
= 0; rept
< n_repeats
; rept
++)
1307 carry_to_use
= u1
& 1;
1309 /* If the ZC bit of the opcode is set, it means we are synthesizing
1310 RRUX, so the carry bit must be ignored. */
1311 if (opcode
->zc
== 0 && (SR
& MSP430_FLAG_C
))
1312 uresult
|= (1 << (opcode
->size
- 1));
1313 TRACE_ALU (MSP430_CPU (sd
), "RRC: %#x >>= %#x",
1316 FLAGS (uresult
, carry_to_use
);
1321 for (rept
= 0; rept
< n_repeats
; rept
++)
1324 uresult
= ((u1
>> 8) & 0x00ff) | ((u1
<< 8) & 0xff00);
1325 TRACE_ALU (MSP430_CPU (sd
), "SWPB: %#x -> %#x",
1332 for (rept
= 0; rept
< n_repeats
; rept
++)
1336 s1
= 1 << (opcode
->size
- 1);
1337 uresult
= (u1
>> 1) | (u1
& s1
);
1338 TRACE_ALU (MSP430_CPU (sd
), "RRA: %#x >>= %#x",
1346 for (rept
= 0; rept
< n_repeats
; rept
++)
1350 uresult
= (u1
>> 1);
1351 TRACE_ALU (MSP430_CPU (sd
), "RRU: %#x >>= %#x",
1359 for (rept
= 0; rept
< n_repeats
; rept
++)
1363 uresult
= u1
| 0xfff00;
1365 uresult
= u1
& 0x000ff;
1366 TRACE_ALU (MSP430_CPU (sd
), "SXT: %#x -> %#x",
1374 for (rept
= 0; rept
< n_repeats
; rept
++)
1378 new_sp
= REG_GET (MSR_SP
) - op_bytes
;
1379 /* SP is always word-aligned. */
1382 REG_PUT (MSR_SP
, new_sp
);
1384 mem_put_val (sd
, SP
, u1
, op_bits
);
1385 if (opcode
->op
[1].type
== MSP430_Operand_Register
)
1386 opcode
->op
[1].reg
--;
1391 for (rept
= 0; rept
< n_repeats
; rept
++)
1395 u1
= mem_get_val (sd
, SP
, op_bits
);
1397 if (opcode
->op
[0].type
== MSP430_Operand_Register
)
1398 opcode
->op
[0].reg
++;
1399 new_sp
= REG_GET (MSR_SP
) + op_bytes
;
1400 /* SP is always word-aligned. */
1403 REG_PUT (MSR_SP
, new_sp
);
1410 if (maybe_perform_syscall (sd
, u1
))
1413 REG_PUT (MSR_SP
, REG_GET (MSR_SP
) - op_bytes
);
1414 mem_put_val (sd
, SP
, PC
, op_bits
);
1415 TRACE_ALU (MSP430_CPU (sd
), "CALL: func %#x ret %#x, sp %#x",
1417 REG_PUT (MSR_PC
, u1
);
1421 u1
= mem_get_val (sd
, SP
, 16);
1424 PC
= mem_get_val (sd
, SP
, 16);
1426 /* Emulate the RETI action of the 20-bit CPUX architecure.
1427 This is safe for 16-bit CPU architectures as well, since the top
1428 8-bits of SR will have been written to the stack here, and will
1429 have been read as 0. */
1430 PC
|= (u1
& 0xF000) << 4;
1431 TRACE_ALU (MSP430_CPU (sd
), "RETI: pc %#x sr %#x",
1439 switch (opcode
->cond
)
1442 u1
= (SR
& MSP430_FLAG_Z
) ? 0 : 1;
1445 u1
= (SR
& MSP430_FLAG_Z
) ? 1 : 0;
1448 u1
= (SR
& MSP430_FLAG_C
) ? 0 : 1;
1451 u1
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1454 u1
= (SR
& MSP430_FLAG_N
) ? 1 : 0;
1457 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 1 : 0;
1460 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 0 : 1;
1469 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x -> %#x sr %#x, taken",
1470 cond_string (opcode
->cond
), PC
, i
, SR
);
1472 if (PC
== opcode_pc
)
1476 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x to %#x sr %#x, not taken",
1477 cond_string (opcode
->cond
), PC
, i
, SR
);
1481 fprintf (stderr
, "error: unexpected opcode id %d\n", opcode
->id
);
1487 sim_engine_run (SIM_DESC sd
,
1494 msp430_step_once (sd
);
1495 if (sim_events_tick (sd
))
1496 sim_events_process (sd
);