1 /* Simulator for TI MSP430 and MSP430X
3 Copyright (C) 2013-2020 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,0xfac0"); /* 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 a
= HWMULT (sd
, hwmult_op1
);
570 b
= HWMULT (sd
, hwmult_op2
);
571 /* For unsigned 32-bit multiplication of 16-bit operands, an
572 explicit cast is required to prevent any implicit
574 HWMULT (sd
, hwmult_result
) = (unsigned32
) a
* (unsigned32
) b
;
575 HWMULT (sd
, hwmult_signed_result
) = a
* b
;
576 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
580 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
581 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
582 HWMULT (sd
, hwmult_signed_result
) = a
* b
;
583 HWMULT (sd
, hwmult_result
) = (unsigned32
) a
* (unsigned32
) b
;
584 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
588 a
= HWMULT (sd
, hwmult_op1
);
589 b
= HWMULT (sd
, hwmult_op2
);
590 HWMULT (sd
, hwmult_accumulator
)
591 += (unsigned32
) a
* (unsigned32
) b
;
592 HWMULT (sd
, hwmult_signed_accumulator
) += a
* b
;
593 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
594 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
598 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
599 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
600 HWMULT (sd
, hwmult_accumulator
)
601 += (unsigned32
) a
* (unsigned32
) b
;
602 HWMULT (sd
, hwmult_signed_accumulator
) += a
* b
;
603 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
604 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
611 /* Copy into LOW result... */
612 switch (HWMULT (sd
, hwmult_type
))
616 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_result
) = zero_ext (val
, 16);
617 HWMULT (sd
, hwmult_signed_accumulator
) = sign_ext (val
, 16);
621 HWMULT (sd
, hwmult_signed_accumulator
) = HWMULT (sd
, hwmult_result
) = sign_ext (val
, 16);
622 HWMULT (sd
, hwmult_accumulator
) = zero_ext (val
, 16);
629 HWMULT (sd
, hw32mult_op1
) = val
;
630 HWMULT (sd
, hw32mult_type
) = UNSIGN_64
;
635 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
640 HWMULT (sd
, hw32mult_op1
) = val
;
641 HWMULT (sd
, hw32mult_type
) = SIGN_64
;
646 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
651 HWMULT (sd
, hw32mult_op2
) = val
;
656 HWMULT (sd
, hw32mult_op2
) = (HWMULT (sd
, hw32mult_op2
) & 0xFFFF) | (val
<< 16);
657 switch (HWMULT (sd
, hw32mult_type
))
660 HWMULT (sd
, hw32mult_result
)
661 = (unsigned64
) HWMULT (sd
, hw32mult_op1
)
662 * (unsigned64
) HWMULT (sd
, hw32mult_op2
);
665 HWMULT (sd
, hw32mult_result
)
666 = sign_ext (HWMULT (sd
, hw32mult_op1
), 32)
667 * sign_ext (HWMULT (sd
, hw32mult_op2
), 32);
673 fprintf (stderr
, "unimplemented HW MULT write to %x!\n", addr
);
682 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 1);
687 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 2);
695 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 4);
698 assert (! opc
->size
);
703 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
727 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
729 int new_val
= REG_GET (op
->reg
) + incval
;
730 /* SP is always word-aligned. */
731 if (op
->reg
== MSR_SP
&& (new_val
& 1))
733 REG_PUT (op
->reg
, new_val
);
740 mem_put_val (SIM_DESC sd
, int addr
, int val
, 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 put_op (sd
, &opc
, 0, val
);
752 mem_get_val (SIM_DESC sd
, int addr
, int bits
)
754 MSP430_Opcode_Decoded opc
;
757 opc
.op
[0].type
= MSP430_Operand_Indirect
;
758 opc
.op
[0].addend
= addr
;
759 opc
.op
[0].reg
= MSR_None
;
760 return get_op (sd
, &opc
, 0);
763 #define CIO_OPEN (0xF0)
764 #define CIO_CLOSE (0xF1)
765 #define CIO_READ (0xF2)
766 #define CIO_WRITE (0xF3)
767 #define CIO_LSEEK (0xF4)
768 #define CIO_UNLINK (0xF5)
769 #define CIO_GETENV (0xF6)
770 #define CIO_RENAME (0xF7)
771 #define CIO_GETTIME (0xF8)
772 #define CIO_GETCLK (0xF9)
773 #define CIO_SYNC (0xFF)
775 #define CIO_I(n) (parms[(n)] + parms[(n)+1] * 256)
776 #define CIO_L(n) (parms[(n)] + parms[(n)+1] * 256 \
777 + parms[(n)+2] * 65536 + parms[(n)+3] * 16777216)
780 msp430_cio (SIM_DESC sd
)
782 /* A block of data at __CIOBUF__ describes the I/O operation to
785 unsigned char raw_parms
[13];
786 unsigned char parms
[8];
789 unsigned char buffer
[512];
791 long fd
, addr
, len
, rv
;
793 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
794 MSP430_CPU (sd
)->state
.cio_buffer
, 5);
798 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
799 MSP430_CPU (sd
)->state
.cio_buffer
+ 3, 8);
801 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
802 MSP430_CPU (sd
)->state
.cio_buffer
+ 11, length
);
810 rv
= write (fd
, buffer
, len
);
811 parms
[0] = rv
& 0xff;
817 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
818 MSP430_CPU (sd
)->state
.cio_buffer
+ 4, 8);
820 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
821 MSP430_CPU (sd
)->state
.cio_buffer
+ 12, ret_buflen
);
824 #define SRC get_op (sd, opcode, 1)
825 #define DSRC get_op (sd, opcode, 0)
826 #define DEST(V) put_op (sd, opcode, 0, (V))
828 #define DO_ALU(OP,SOP,MORE) \
832 int result = s1 OP s2 MORE; \
833 TRACE_ALU (MSP430_CPU (sd), "ALU: %#x %s %#x %s = %#x", s1, SOP, \
834 s2, #MORE, result); \
838 #define SIGN (1 << (opcode->size - 1))
839 #define POS(x) (((x) & SIGN) ? 0 : 1)
840 #define NEG(x) (((x) & SIGN) ? 1 : 0)
842 #define SX(v) sign_ext (v, opcode->size)
843 #define ZX(v) zero_ext (v, opcode->size)
848 static char buf
[2][6];
854 bp
[0] = f
& MSP430_FLAG_V
? 'V' : '-';
855 bp
[1] = f
& MSP430_FLAG_N
? 'N' : '-';
856 bp
[2] = f
& MSP430_FLAG_Z
? 'Z' : '-';
857 bp
[3] = f
& MSP430_FLAG_C
? 'C' : '-';
862 /* Random number that won't show up in our usual logic. */
863 #define MAGIC_OVERFLOW 0x55000F
866 do_flags (SIM_DESC sd
,
867 MSP430_Opcode_Decoded
*opcode
,
868 int vnz_val
, /* Signed result. */
874 int signbit
= 1 << (opcode
->size
- 1);
876 f
&= ~opcode
->flags_0
;
877 f
&= ~opcode
->flags_set
;
878 f
|= opcode
->flags_1
;
880 if (vnz_val
& signbit
)
881 new_f
|= MSP430_FLAG_N
;
882 if (! (vnz_val
& ((signbit
<< 1) - 1)))
883 new_f
|= MSP430_FLAG_Z
;
884 if (overflow
== MAGIC_OVERFLOW
)
886 if (vnz_val
!= SX (vnz_val
))
887 new_f
|= MSP430_FLAG_V
;
891 new_f
|= MSP430_FLAG_V
;
893 new_f
|= MSP430_FLAG_C
;
895 new_f
= f
| (new_f
& opcode
->flags_set
);
897 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s -> %s", flags2string (SR
),
898 flags2string (new_f
));
900 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s", flags2string (new_f
));
904 #define FLAGS(vnz,c) do_flags (sd, opcode, vnz, c, MAGIC_OVERFLOW)
905 #define FLAGSV(vnz,c,v) do_flags (sd, opcode, vnz, c, v)
907 /* These two assume unsigned 16-bit (four digit) words.
908 Mask off unwanted bits for byte operations. */
911 bcd_to_binary (int v
)
913 int r
= ( ((v
>> 0) & 0xf) * 1
914 + ((v
>> 4) & 0xf) * 10
915 + ((v
>> 8) & 0xf) * 100
916 + ((v
>> 12) & 0xf) * 1000);
921 binary_to_bcd (int v
)
923 int r
= ( ((v
/ 1) % 10) << 0
924 | ((v
/ 10) % 10) << 4
925 | ((v
/ 100) % 10) << 8
926 | ((v
/ 1000) % 10) << 12);
931 cond_string (int cond
)
956 /* Checks a CALL to address CALL_ADDR. If this is a special
957 syscall address then the call is simulated and non-zero is
958 returned. Otherwise 0 is returned. */
961 maybe_perform_syscall (SIM_DESC sd
, int call_addr
)
963 if (call_addr
== 0x00160)
967 for (i
= 0; i
< 16; i
++)
970 fprintf (stderr
, "\t");
971 fprintf (stderr
, "R%-2d %05x ", i
, MSP430_CPU (sd
)->state
.regs
[i
]);
974 int sp
= SP
+ (3 - (i
/ 4)) * 2;
975 unsigned char buf
[2];
977 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, sp
, 2);
979 fprintf (stderr
, "\tSP%+d: %04x", sp
- SP
,
980 buf
[0] + buf
[1] * 256);
986 fprintf (stderr
, flags
& 0x100 ? " V" : " -");
987 fprintf (stderr
, flags
& 0x004 ? "N" : "-");
988 fprintf (stderr
, flags
& 0x002 ? "Z" : "-");
989 fprintf (stderr
, flags
& 0x001 ? "C" : "-");
992 fprintf (stderr
, "\n");
998 if ((call_addr
& ~0x3f) == 0x00180)
1001 int arg1
, arg2
, arg3
, arg4
;
1002 int syscall_num
= call_addr
& 0x3f;
1004 /* syscall_num == 2 is used for the variadic function "open".
1005 The arguments are set up differently for variadic functions.
1006 See slaa534.pdf distributed by TI. */
1007 if (syscall_num
== 2)
1009 arg1
= MSP430_CPU (sd
)->state
.regs
[12];
1010 arg2
= mem_get_val (sd
, SP
, 16);
1011 arg3
= mem_get_val (sd
, SP
+ 2, 16);
1012 arg4
= mem_get_val (sd
, SP
+ 4, 16);
1016 arg1
= MSP430_CPU (sd
)->state
.regs
[12];
1017 arg2
= MSP430_CPU (sd
)->state
.regs
[13];
1018 arg3
= MSP430_CPU (sd
)->state
.regs
[14];
1019 arg4
= MSP430_CPU (sd
)->state
.regs
[15];
1022 MSP430_CPU (sd
)->state
.regs
[12] = sim_syscall (MSP430_CPU (sd
),
1023 syscall_num
, arg1
, arg2
,
1032 msp430_step_once (SIM_DESC sd
)
1034 Get_Byte_Local_Data ld
;
1035 unsigned char buf
[100];
1038 unsigned int opcode_pc
;
1039 MSP430_Opcode_Decoded opcode_buf
;
1040 MSP430_Opcode_Decoded
*opcode
= &opcode_buf
;
1042 int u1
= 0, u2
, uresult
;
1048 int op_bytes
= 0, op_bits
;
1053 if (opcode_pc
< 0x10)
1055 fprintf (stderr
, "Fault: PC(%#x) is less than 0x10\n", opcode_pc
);
1056 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1057 MSP430_CPU (sd
)->state
.regs
[0],
1062 if (PC
== MSP430_CPU (sd
)->state
.cio_breakpoint
1063 && STATE_OPEN_KIND (sd
) != SIM_OPEN_DEBUG
)
1068 opsize
= msp430_decode_opcode (MSP430_CPU (sd
)->state
.regs
[0],
1069 opcode
, msp430_getbyte
, &ld
);
1073 fprintf (stderr
, "Fault: undecodable opcode at %#x\n", opcode_pc
);
1074 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1075 MSP430_CPU (sd
)->state
.regs
[0],
1080 if (opcode
->repeat_reg
)
1081 n_repeats
= (MSP430_CPU (sd
)->state
.regs
[opcode
->repeats
] & 0x000f) + 1;
1083 n_repeats
= opcode
->repeats
+ 1;
1085 op_bits
= opcode
->size
;
1100 if (TRACE_ANY_P (MSP430_CPU (sd
)))
1101 trace_prefix (sd
, MSP430_CPU (sd
), NULL_CIA
, opcode_pc
,
1102 TRACE_LINENUM_P (MSP430_CPU (sd
)), NULL
, 0, " ");
1104 TRACE_DISASM (MSP430_CPU (sd
), opcode_pc
);
1112 /* Double-operand instructions. */
1114 if (opcode
->n_bytes
== 2
1115 && opcode
->op
[0].type
== MSP430_Operand_Register
1116 && opcode
->op
[0].reg
== MSR_CG
1117 && opcode
->op
[1].type
== MSP430_Operand_Immediate
1118 && opcode
->op
[1].addend
== 0
1119 /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK. */
1120 && opcode
->size
== 8)
1122 /* This is the designated software breakpoint instruction. */
1124 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1125 MSP430_CPU (sd
)->state
.regs
[0],
1126 sim_stopped
, SIM_SIGTRAP
);
1131 /* Otherwise, do the move. */
1132 for (rept
= 0; rept
< n_repeats
; rept
++)
1140 for (rept
= 0; rept
< n_repeats
; rept
++)
1142 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1147 uresult
= u1
+ u2
+ carry_to_use
;
1148 result
= s1
+ s2
+ carry_to_use
;
1149 TRACE_ALU (MSP430_CPU (sd
), "ADDC: %#x + %#x + %d = %#x",
1150 u1
, u2
, carry_to_use
, uresult
);
1152 FLAGS (result
, uresult
!= ZX (uresult
));
1157 for (rept
= 0; rept
< n_repeats
; rept
++)
1165 TRACE_ALU (MSP430_CPU (sd
), "ADD: %#x + %#x = %#x",
1168 FLAGS (result
, uresult
!= ZX (uresult
));
1173 for (rept
= 0; rept
< n_repeats
; rept
++)
1175 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1180 uresult
= ZX (~u2
) + u1
+ carry_to_use
;
1181 result
= s1
- s2
+ (carry_to_use
- 1);
1182 TRACE_ALU (MSP430_CPU (sd
), "SUBC: %#x - %#x + %d = %#x",
1183 u1
, u2
, carry_to_use
, uresult
);
1185 FLAGS (result
, uresult
!= ZX (uresult
));
1190 for (rept
= 0; rept
< n_repeats
; rept
++)
1196 uresult
= ZX (~u2
) + u1
+ 1;
1197 result
= SX (uresult
);
1198 TRACE_ALU (MSP430_CPU (sd
), "SUB: %#x - %#x = %#x",
1201 FLAGS (result
, uresult
!= ZX (uresult
));
1206 for (rept
= 0; rept
< n_repeats
; rept
++)
1212 uresult
= ZX (~u2
) + u1
+ 1;
1214 TRACE_ALU (MSP430_CPU (sd
), "CMP: %#x - %#x = %x",
1216 FLAGS (result
, uresult
!= ZX (uresult
));
1221 for (rept
= 0; rept
< n_repeats
; rept
++)
1223 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1226 uresult
= bcd_to_binary (u1
) + bcd_to_binary (u2
) + carry_to_use
;
1227 result
= binary_to_bcd (uresult
);
1228 TRACE_ALU (MSP430_CPU (sd
), "DADD: %#x + %#x + %d = %#x",
1229 u1
, u2
, carry_to_use
, result
);
1231 FLAGS (result
, uresult
> ((opcode
->size
== 8) ? 99 : 9999));
1236 for (rept
= 0; rept
< n_repeats
; rept
++)
1241 TRACE_ALU (MSP430_CPU (sd
), "AND: %#x & %#x = %#x",
1244 FLAGS (uresult
, uresult
!= 0);
1249 for (rept
= 0; rept
< n_repeats
; rept
++)
1254 TRACE_ALU (MSP430_CPU (sd
), "BIT: %#x & %#x -> %#x",
1256 FLAGS (uresult
, uresult
!= 0);
1261 for (rept
= 0; rept
< n_repeats
; rept
++)
1265 uresult
= u1
& ~ u2
;
1266 TRACE_ALU (MSP430_CPU (sd
), "BIC: %#x & ~ %#x = %#x",
1273 for (rept
= 0; rept
< n_repeats
; rept
++)
1278 TRACE_ALU (MSP430_CPU (sd
), "BIS: %#x | %#x = %#x",
1285 for (rept
= 0; rept
< n_repeats
; rept
++)
1287 s1
= 1 << (opcode
->size
- 1);
1291 TRACE_ALU (MSP430_CPU (sd
), "XOR: %#x & %#x = %#x",
1294 FLAGSV (uresult
, uresult
!= 0, (u1
& s1
) && (u2
& s1
));
1298 /* Single-operand instructions. Note: the decoder puts the same
1299 operand in SRC as in DEST, for our convenience. */
1302 for (rept
= 0; rept
< n_repeats
; rept
++)
1305 carry_to_use
= u1
& 1;
1307 /* If the ZC bit of the opcode is set, it means we are synthesizing
1308 RRUX, so the carry bit must be ignored. */
1309 if (opcode
->zc
== 0 && (SR
& MSP430_FLAG_C
))
1310 uresult
|= (1 << (opcode
->size
- 1));
1311 TRACE_ALU (MSP430_CPU (sd
), "RRC: %#x >>= %#x",
1314 FLAGS (uresult
, carry_to_use
);
1319 for (rept
= 0; rept
< n_repeats
; rept
++)
1322 uresult
= ((u1
>> 8) & 0x00ff) | ((u1
<< 8) & 0xff00);
1323 TRACE_ALU (MSP430_CPU (sd
), "SWPB: %#x -> %#x",
1330 for (rept
= 0; rept
< n_repeats
; rept
++)
1334 s1
= 1 << (opcode
->size
- 1);
1335 uresult
= (u1
>> 1) | (u1
& s1
);
1336 TRACE_ALU (MSP430_CPU (sd
), "RRA: %#x >>= %#x",
1344 for (rept
= 0; rept
< n_repeats
; rept
++)
1348 uresult
= (u1
>> 1);
1349 TRACE_ALU (MSP430_CPU (sd
), "RRU: %#x >>= %#x",
1357 for (rept
= 0; rept
< n_repeats
; rept
++)
1361 uresult
= u1
| 0xfff00;
1363 uresult
= u1
& 0x000ff;
1364 TRACE_ALU (MSP430_CPU (sd
), "SXT: %#x -> %#x",
1372 for (rept
= 0; rept
< n_repeats
; rept
++)
1376 new_sp
= REG_GET (MSR_SP
) - op_bytes
;
1377 /* SP is always word-aligned. */
1380 REG_PUT (MSR_SP
, new_sp
);
1382 mem_put_val (sd
, SP
, u1
, op_bits
);
1383 if (opcode
->op
[1].type
== MSP430_Operand_Register
)
1384 opcode
->op
[1].reg
--;
1389 for (rept
= 0; rept
< n_repeats
; rept
++)
1393 u1
= mem_get_val (sd
, SP
, op_bits
);
1395 if (opcode
->op
[0].type
== MSP430_Operand_Register
)
1396 opcode
->op
[0].reg
++;
1397 new_sp
= REG_GET (MSR_SP
) + op_bytes
;
1398 /* SP is always word-aligned. */
1401 REG_PUT (MSR_SP
, new_sp
);
1408 if (maybe_perform_syscall (sd
, u1
))
1411 REG_PUT (MSR_SP
, REG_GET (MSR_SP
) - op_bytes
);
1412 mem_put_val (sd
, SP
, PC
, op_bits
);
1413 TRACE_ALU (MSP430_CPU (sd
), "CALL: func %#x ret %#x, sp %#x",
1415 REG_PUT (MSR_PC
, u1
);
1419 u1
= mem_get_val (sd
, SP
, 16);
1422 PC
= mem_get_val (sd
, SP
, 16);
1424 /* Emulate the RETI action of the 20-bit CPUX architecure.
1425 This is safe for 16-bit CPU architectures as well, since the top
1426 8-bits of SR will have been written to the stack here, and will
1427 have been read as 0. */
1428 PC
|= (u1
& 0xF000) << 4;
1429 TRACE_ALU (MSP430_CPU (sd
), "RETI: pc %#x sr %#x",
1437 switch (opcode
->cond
)
1440 u1
= (SR
& MSP430_FLAG_Z
) ? 0 : 1;
1443 u1
= (SR
& MSP430_FLAG_Z
) ? 1 : 0;
1446 u1
= (SR
& MSP430_FLAG_C
) ? 0 : 1;
1449 u1
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1452 u1
= (SR
& MSP430_FLAG_N
) ? 1 : 0;
1455 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 1 : 0;
1458 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 0 : 1;
1467 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x -> %#x sr %#x, taken",
1468 cond_string (opcode
->cond
), PC
, i
, SR
);
1470 if (PC
== opcode_pc
)
1474 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x to %#x sr %#x, not taken",
1475 cond_string (opcode
->cond
), PC
, i
, SR
);
1479 fprintf (stderr
, "error: unexpected opcode id %d\n", opcode
->id
);
1485 sim_engine_run (SIM_DESC sd
,
1492 msp430_step_once (sd
);
1493 if (sim_events_tick (sd
))
1494 sim_events_process (sd
);