1 /* Simulator for TI MSP430 and MSP430X
3 Copyright (C) 2013-2016 Free Software Foundation, Inc.
4 Contributed by Red Hat.
5 Based on sim/bfin/bfin-sim.c which was contributed by Analog Devices, Inc.
7 This file is part of simulators.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
30 #include "opcode/msp430-decode.h"
32 #include "sim-syscall.h"
33 #include "targ-vals.h"
36 msp430_pc_fetch (SIM_CPU
*cpu
)
38 return cpu
->state
.regs
[0];
42 msp430_pc_store (SIM_CPU
*cpu
, sim_cia newpc
)
44 cpu
->state
.regs
[0] = newpc
;
48 lookup_symbol (SIM_DESC sd
, const char *name
)
50 struct bfd
*abfd
= STATE_PROG_BFD (sd
);
51 asymbol
**symbol_table
= STATE_SYMBOL_TABLE (sd
);
52 long number_of_symbols
= STATE_NUM_SYMBOLS (sd
);
58 if (symbol_table
== NULL
)
62 storage_needed
= bfd_get_symtab_upper_bound (abfd
);
63 if (storage_needed
<= 0)
66 STATE_SYMBOL_TABLE (sd
) = symbol_table
= xmalloc (storage_needed
);
67 STATE_NUM_SYMBOLS (sd
) = number_of_symbols
=
68 bfd_canonicalize_symtab (abfd
, symbol_table
);
71 for (i
= 0; i
< number_of_symbols
; i
++)
72 if (strcmp (symbol_table
[i
]->name
, name
) == 0)
74 long val
= symbol_table
[i
]->section
->vma
+ symbol_table
[i
]->value
;
81 msp430_reg_fetch (SIM_CPU
*cpu
, int regno
, unsigned char *buf
, int len
)
83 if (0 <= regno
&& regno
< 16)
87 int val
= cpu
->state
.regs
[regno
];
89 buf
[1] = (val
>> 8) & 0xff;
94 int val
= cpu
->state
.regs
[regno
];
96 buf
[1] = (val
>> 8) & 0xff;
97 buf
[2] = (val
>> 16) & 0x0f; /* Registers are only 20 bits wide. */
109 msp430_reg_store (SIM_CPU
*cpu
, int regno
, unsigned char *buf
, int len
)
111 if (0 <= regno
&& regno
< 16)
115 cpu
->state
.regs
[regno
] = (buf
[1] << 8) | buf
[0];
121 cpu
->state
.regs
[regno
] = ((buf
[2] << 16) & 0xf0000)
122 | (buf
[1] << 8) | buf
[0];
131 msp430_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
133 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
137 sim_open (SIM_OPEN_KIND kind
,
138 struct host_callback_struct
*callback
,
142 SIM_DESC sd
= sim_state_alloc (kind
, callback
);
145 /* Initialise the simulator. */
147 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
153 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
159 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
165 CPU_PC_FETCH (MSP430_CPU (sd
)) = msp430_pc_fetch
;
166 CPU_PC_STORE (MSP430_CPU (sd
)) = msp430_pc_store
;
167 CPU_REG_FETCH (MSP430_CPU (sd
)) = msp430_reg_fetch
;
168 CPU_REG_STORE (MSP430_CPU (sd
)) = msp430_reg_store
;
170 /* Allocate memory if none specified by user.
171 Note - these values match the memory regions in the libgloss/msp430/msp430[xl]-sim.ld scripts. */
172 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x2, 1) == 0)
173 sim_do_commandf (sd
, "memory-region 0,0x20"); /* Needed by the GDB testsuite. */
174 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x500, 1) == 0)
175 sim_do_commandf (sd
, "memory-region 0x500,0xfa00"); /* RAM and/or ROM */
176 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0xfffe, 1) == 0)
177 sim_do_commandf (sd
, "memory-region 0xffc0,0x40"); /* VECTORS. */
178 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x10000, 1) == 0)
179 sim_do_commandf (sd
, "memory-region 0x10000,0x80000"); /* HIGH FLASH RAM. */
180 if (sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, &c
, 0x90000, 1) == 0)
181 sim_do_commandf (sd
, "memory-region 0x90000,0x70000"); /* HIGH ROM. */
183 /* Check for/establish the a reference program image. */
184 if (sim_analyze_program (sd
,
185 (STATE_PROG_ARGV (sd
) != NULL
186 ? *STATE_PROG_ARGV (sd
)
187 : NULL
), abfd
) != SIM_RC_OK
)
193 /* Establish any remaining configuration options. */
194 if (sim_config (sd
) != SIM_RC_OK
)
200 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
206 /* CPU specific initialization. */
207 assert (MAX_NR_PROCESSORS
== 1);
208 msp430_initialize_cpu (sd
, MSP430_CPU (sd
));
210 MSP430_CPU (sd
)->state
.cio_breakpoint
= lookup_symbol (sd
, "C$$IO$$");
211 MSP430_CPU (sd
)->state
.cio_buffer
= lookup_symbol (sd
, "__CIOBUF__");
212 if (MSP430_CPU (sd
)->state
.cio_buffer
== -1)
213 MSP430_CPU (sd
)->state
.cio_buffer
= lookup_symbol (sd
, "_CIOBUF_");
219 msp430_sim_close (SIM_DESC sd
, int quitting
)
221 free (STATE_SYMBOL_TABLE (sd
));
225 sim_create_inferior (SIM_DESC sd
,
230 unsigned char resetv
[2];
234 /* Set the PC to the default reset vector if available. */
235 c
= sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, resetv
, 0xfffe, 2);
236 new_pc
= resetv
[0] + 256 * resetv
[1];
238 /* If the reset vector isn't initialized, then use the ELF entry. */
239 if (abfd
!= NULL
&& !new_pc
)
240 new_pc
= bfd_get_start_address (abfd
);
242 sim_pc_set (MSP430_CPU (sd
), new_pc
);
243 msp430_pc_store (MSP430_CPU (sd
), new_pc
);
252 } Get_Byte_Local_Data
;
255 msp430_getbyte (void *vld
)
257 Get_Byte_Local_Data
*ld
= (Get_Byte_Local_Data
*)vld
;
259 SIM_DESC sd
= ld
->sd
;
261 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, ld
->gb_addr
, 1);
266 #define REG(N) MSP430_CPU (sd)->state.regs[(N)]
267 #define PC REG(MSR_PC)
268 #define SP REG(MSR_SP)
269 #define SR REG(MSR_SR)
274 "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8",
275 "R9", "R10", "R11", "R12", "R13", "R14", "R15"
279 trace_reg_put (SIM_DESC sd
, int n
, unsigned int v
)
281 TRACE_REGISTER (MSP430_CPU (sd
), "PUT: %#x -> %s", v
, register_names
[n
]);
286 trace_reg_get (SIM_DESC sd
, int n
)
288 TRACE_REGISTER (MSP430_CPU (sd
), "GET: %s -> %#x", register_names
[n
], REG (n
));
292 #define REG_PUT(N,V) trace_reg_put (sd, N, V)
293 #define REG_GET(N) trace_reg_get (sd, N)
295 /* Hardware multiply (and accumulate) support. */
298 zero_ext (unsigned int v
, unsigned int bits
)
300 v
&= ((1 << bits
) - 1);
304 static signed long long
305 sign_ext (signed long long v
, unsigned int bits
)
307 signed long long sb
= 1LL << (bits
-1); /* Sign bit. */
308 signed long long mb
= (1LL << (bits
-1)) - 1LL; /* Mantissa bits. */
318 get_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
)
320 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
323 unsigned char buf
[4];
328 case MSP430_Operand_Immediate
:
331 case MSP430_Operand_Register
:
332 rv
= REG_GET (op
->reg
);
334 case MSP430_Operand_Indirect
:
335 case MSP430_Operand_Indirect_Postinc
:
337 if (op
->reg
!= MSR_None
)
339 int reg
= REG_GET (op
->reg
);
340 int sign
= opc
->ofs_430x
? 20 : 16;
342 /* Index values are signed. */
343 if (addr
& (1 << (sign
- 1)))
344 addr
|= -(1 << sign
);
348 /* For MSP430 instructions the sum is limited to 16 bits if the
349 address in the index register is less than 64k even if we are
350 running on an MSP430X CPU. This is for MSP430 compatibility. */
351 if (reg
< 0x10000 && ! opc
->ofs_430x
)
354 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on read\n", addr
);
363 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 1);
367 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 2);
368 rv
= buf
[0] | (buf
[1] << 8);
372 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, addr
, 4);
373 rv
= buf
[0] | (buf
[1] << 8) | (buf
[2] << 16) | (buf
[3] << 24);
376 assert (! opc
->size
);
380 /* Hack - MSP430X5438 serial port status register. */
384 if ((addr
>= 0x130 && addr
<= 0x15B)
385 || (addr
>= 0x4C0 && addr
<= 0x4EB))
391 switch (HWMULT (sd
, hwmult_type
))
395 rv
= zero_ext (HWMULT (sd
, hwmult_result
), 16);
399 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
), 16);
406 switch (HWMULT (sd
, hwmult_type
))
410 rv
= zero_ext (HWMULT (sd
, hwmult_result
) >> 16, 16);
415 rv
= sign_ext (HWMULT (sd
, hwmult_signed_result
) >> 16, 16);
422 switch (HWMULT (sd
, hwmult_type
))
428 rv
= HWMULT (sd
, hwmult_signed_result
) < 0 ? -1 : 0;
431 rv
= 0; /* FIXME: Should be carry of last accumulate. */
434 rv
= HWMULT (sd
, hwmult_signed_accumulator
) < 0 ? -1 : 0;
441 rv
= zero_ext (HWMULT (sd
, hw32mult_result
), 16);
446 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 16, 16);
451 rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 32, 16);
456 switch (HWMULT (sd
, hw32mult_type
))
458 case UNSIGN_64
: rv
= zero_ext (HWMULT (sd
, hw32mult_result
) >> 48, 16); break;
459 case SIGN_64
: rv
= sign_ext (HWMULT (sd
, hw32mult_result
) >> 48, 16); break;
464 fprintf (stderr
, "unimplemented HW MULT read from %x!\n", addr
);
469 TRACE_MEMORY (MSP430_CPU (sd
), "GET: [%#x].%d -> %#x", addr
, opc
->size
,
474 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
498 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
499 REG_PUT (op
->reg
, REG_GET (op
->reg
) + incval
);
505 put_op (SIM_DESC sd
, MSP430_Opcode_Decoded
*opc
, int n
, int val
)
507 MSP430_Opcode_Operand
*op
= opc
->op
+ n
;
510 unsigned char buf
[4];
531 case MSP430_Operand_Register
:
533 REG_PUT (op
->reg
, val
);
535 case MSP430_Operand_Indirect
:
536 case MSP430_Operand_Indirect_Postinc
:
538 if (op
->reg
!= MSR_None
)
540 int reg
= REG_GET (op
->reg
);
541 int sign
= opc
->ofs_430x
? 20 : 16;
543 /* Index values are signed. */
544 if (addr
& (1 << (sign
- 1)))
545 addr
|= -(1 << sign
);
549 /* For MSP430 instructions the sum is limited to 16 bits if the
550 address in the index register is less than 64k even if we are
551 running on an MSP430X CPU. This is for MSP430 compatibility. */
552 if (reg
< 0x10000 && ! opc
->ofs_430x
)
555 fprintf (stderr
, " XXX WRAPPING ADDRESS %x on write\n", addr
);
562 TRACE_MEMORY (MSP430_CPU (sd
), "PUT: [%#x].%d <- %#x", addr
, opc
->size
,
565 /* Hack - MSP430X5438 serial port transmit register. */
569 if ((addr
>= 0x130 && addr
<= 0x15B)
570 || (addr
>= 0x4C0 && addr
<= 0x4EB))
574 /* Hardware Multiply emulation. */
575 assert (opc
->size
== 16);
581 HWMULT (sd
, hwmult_op1
) = val
;
582 HWMULT (sd
, hwmult_type
) = UNSIGN_32
;
587 HWMULT (sd
, hwmult_op1
) = val
;
588 HWMULT (sd
, hwmult_type
) = SIGN_32
;
593 HWMULT (sd
, hwmult_op1
) = val
;
594 HWMULT (sd
, hwmult_type
) = UNSIGN_MAC_32
;
599 HWMULT (sd
, hwmult_op1
) = val
;
600 HWMULT (sd
, hwmult_type
) = SIGN_MAC_32
;
605 HWMULT (sd
, hwmult_op2
) = val
;
606 switch (HWMULT (sd
, hwmult_type
))
609 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
610 HWMULT (sd
, hwmult_signed_result
) = (signed) HWMULT (sd
, hwmult_result
);
611 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
615 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
616 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
617 HWMULT (sd
, hwmult_signed_result
) = a
* b
;
618 HWMULT (sd
, hwmult_result
) = (unsigned) HWMULT (sd
, hwmult_signed_result
);
619 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_signed_accumulator
) = 0;
623 HWMULT (sd
, hwmult_accumulator
) += HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
624 HWMULT (sd
, hwmult_signed_accumulator
) += HWMULT (sd
, hwmult_op1
) * HWMULT (sd
, hwmult_op2
);
625 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
626 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
630 a
= sign_ext (HWMULT (sd
, hwmult_op1
), 16);
631 b
= sign_ext (HWMULT (sd
, hwmult_op2
), 16);
632 HWMULT (sd
, hwmult_accumulator
) += a
* b
;
633 HWMULT (sd
, hwmult_signed_accumulator
) += a
* b
;
634 HWMULT (sd
, hwmult_result
) = HWMULT (sd
, hwmult_accumulator
);
635 HWMULT (sd
, hwmult_signed_result
) = HWMULT (sd
, hwmult_signed_accumulator
);
642 /* Copy into LOW result... */
643 switch (HWMULT (sd
, hwmult_type
))
647 HWMULT (sd
, hwmult_accumulator
) = HWMULT (sd
, hwmult_result
) = zero_ext (val
, 16);
648 HWMULT (sd
, hwmult_signed_accumulator
) = sign_ext (val
, 16);
652 HWMULT (sd
, hwmult_signed_accumulator
) = HWMULT (sd
, hwmult_result
) = sign_ext (val
, 16);
653 HWMULT (sd
, hwmult_accumulator
) = zero_ext (val
, 16);
660 HWMULT (sd
, hw32mult_op1
) = val
;
661 HWMULT (sd
, hw32mult_type
) = UNSIGN_64
;
666 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
671 HWMULT (sd
, hw32mult_op1
) = val
;
672 HWMULT (sd
, hw32mult_type
) = SIGN_64
;
677 HWMULT (sd
, hw32mult_op1
) = (HWMULT (sd
, hw32mult_op1
) & 0xFFFF) | (val
<< 16);
682 HWMULT (sd
, hw32mult_op2
) = val
;
687 HWMULT (sd
, hw32mult_op2
) = (HWMULT (sd
, hw32mult_op2
) & 0xFFFF) | (val
<< 16);
688 switch (HWMULT (sd
, hw32mult_type
))
691 HWMULT (sd
, hw32mult_result
) = HWMULT (sd
, hw32mult_op1
) * HWMULT (sd
, hw32mult_op2
);
694 HWMULT (sd
, hw32mult_result
) = sign_ext (HWMULT (sd
, hw32mult_op1
), 32)
695 * sign_ext (HWMULT (sd
, hw32mult_op2
), 32);
701 fprintf (stderr
, "unimplemented HW MULT write to %x!\n", addr
);
710 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 1);
715 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 2);
723 sim_core_write_buffer (sd
, MSP430_CPU (sd
), write_map
, buf
, addr
, 4);
726 assert (! opc
->size
);
731 fprintf (stderr
, "invalid operand %d type %d\n", n
, op
->type
);
755 if (op
->type
== MSP430_Operand_Indirect_Postinc
)
757 int new_val
= REG_GET (op
->reg
) + incval
;
758 /* SP is always word-aligned. */
759 if (op
->reg
== MSR_SP
&& (new_val
& 1))
761 REG_PUT (op
->reg
, new_val
);
768 mem_put_val (SIM_DESC sd
, int addr
, int val
, int bits
)
770 MSP430_Opcode_Decoded opc
;
773 opc
.op
[0].type
= MSP430_Operand_Indirect
;
774 opc
.op
[0].addend
= addr
;
775 opc
.op
[0].reg
= MSR_None
;
776 put_op (sd
, &opc
, 0, val
);
780 mem_get_val (SIM_DESC sd
, int addr
, int bits
)
782 MSP430_Opcode_Decoded opc
;
785 opc
.op
[0].type
= MSP430_Operand_Indirect
;
786 opc
.op
[0].addend
= addr
;
787 opc
.op
[0].reg
= MSR_None
;
788 return get_op (sd
, &opc
, 0);
791 #define CIO_OPEN (0xF0)
792 #define CIO_CLOSE (0xF1)
793 #define CIO_READ (0xF2)
794 #define CIO_WRITE (0xF3)
795 #define CIO_LSEEK (0xF4)
796 #define CIO_UNLINK (0xF5)
797 #define CIO_GETENV (0xF6)
798 #define CIO_RENAME (0xF7)
799 #define CIO_GETTIME (0xF8)
800 #define CIO_GETCLK (0xF9)
801 #define CIO_SYNC (0xFF)
803 #define CIO_I(n) (parms[(n)] + parms[(n)+1] * 256)
804 #define CIO_L(n) (parms[(n)] + parms[(n)+1] * 256 \
805 + parms[(n)+2] * 65536 + parms[(n)+3] * 16777216)
808 msp430_cio (SIM_DESC sd
)
810 /* A block of data at __CIOBUF__ describes the I/O operation to
813 unsigned char raw_parms
[13];
814 unsigned char parms
[8];
817 unsigned char buffer
[512];
819 long fd
, addr
, len
, rv
;
821 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
822 MSP430_CPU (sd
)->state
.cio_buffer
, 5);
826 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
827 MSP430_CPU (sd
)->state
.cio_buffer
+ 3, 8);
829 sim_core_read_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
830 MSP430_CPU (sd
)->state
.cio_buffer
+ 11, length
);
838 rv
= write (fd
, buffer
, len
);
839 parms
[0] = rv
& 0xff;
845 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, parms
,
846 MSP430_CPU (sd
)->state
.cio_buffer
+ 4, 8);
848 sim_core_write_buffer (sd
, MSP430_CPU (sd
), 0, buffer
,
849 MSP430_CPU (sd
)->state
.cio_buffer
+ 12, ret_buflen
);
852 #define SRC get_op (sd, opcode, 1)
853 #define DSRC get_op (sd, opcode, 0)
854 #define DEST(V) put_op (sd, opcode, 0, (V))
856 #define DO_ALU(OP,SOP,MORE) \
860 int result = s1 OP s2 MORE; \
861 TRACE_ALU (MSP430_CPU (sd), "ALU: %#x %s %#x %s = %#x", s1, SOP, \
862 s2, #MORE, result); \
866 #define SIGN (1 << (opcode->size - 1))
867 #define POS(x) (((x) & SIGN) ? 0 : 1)
868 #define NEG(x) (((x) & SIGN) ? 1 : 0)
870 #define SX(v) sign_ext (v, opcode->size)
871 #define ZX(v) zero_ext (v, opcode->size)
876 static char buf
[2][6];
882 bp
[0] = f
& MSP430_FLAG_V
? 'V' : '-';
883 bp
[1] = f
& MSP430_FLAG_N
? 'N' : '-';
884 bp
[2] = f
& MSP430_FLAG_Z
? 'Z' : '-';
885 bp
[3] = f
& MSP430_FLAG_C
? 'C' : '-';
890 /* Random number that won't show up in our usual logic. */
891 #define MAGIC_OVERFLOW 0x55000F
894 do_flags (SIM_DESC sd
,
895 MSP430_Opcode_Decoded
*opcode
,
896 int vnz_val
, /* Signed result. */
902 int signbit
= 1 << (opcode
->size
- 1);
904 f
&= ~opcode
->flags_0
;
905 f
&= ~opcode
->flags_set
;
906 f
|= opcode
->flags_1
;
908 if (vnz_val
& signbit
)
909 new_f
|= MSP430_FLAG_N
;
910 if (! (vnz_val
& ((signbit
<< 1) - 1)))
911 new_f
|= MSP430_FLAG_Z
;
912 if (overflow
== MAGIC_OVERFLOW
)
914 if (vnz_val
!= SX (vnz_val
))
915 new_f
|= MSP430_FLAG_V
;
919 new_f
|= MSP430_FLAG_V
;
921 new_f
|= MSP430_FLAG_C
;
923 new_f
= f
| (new_f
& opcode
->flags_set
);
925 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s -> %s", flags2string (SR
),
926 flags2string (new_f
));
928 TRACE_ALU (MSP430_CPU (sd
), "FLAGS: %s", flags2string (new_f
));
932 #define FLAGS(vnz,c) do_flags (sd, opcode, vnz, c, MAGIC_OVERFLOW)
933 #define FLAGSV(vnz,c,v) do_flags (sd, opcode, vnz, c, v)
935 /* These two assume unsigned 16-bit (four digit) words.
936 Mask off unwanted bits for byte operations. */
939 bcd_to_binary (int v
)
941 int r
= ( ((v
>> 0) & 0xf) * 1
942 + ((v
>> 4) & 0xf) * 10
943 + ((v
>> 8) & 0xf) * 100
944 + ((v
>> 12) & 0xf) * 1000);
949 binary_to_bcd (int v
)
951 int r
= ( ((v
/ 1) % 10) << 0
952 | ((v
/ 10) % 10) << 4
953 | ((v
/ 100) % 10) << 8
954 | ((v
/ 1000) % 10) << 12);
959 cond_string (int cond
)
984 /* Checks a CALL to address CALL_ADDR. If this is a special
985 syscall address then the call is simulated and non-zero is
986 returned. Otherwise 0 is returned. */
989 maybe_perform_syscall (SIM_DESC sd
, int call_addr
)
991 if (call_addr
== 0x00160)
995 for (i
= 0; i
< 16; i
++)
998 fprintf (stderr
, "\t");
999 fprintf (stderr
, "R%-2d %05x ", i
, MSP430_CPU (sd
)->state
.regs
[i
]);
1002 int sp
= SP
+ (3 - (i
/ 4)) * 2;
1003 unsigned char buf
[2];
1005 sim_core_read_buffer (sd
, MSP430_CPU (sd
), read_map
, buf
, sp
, 2);
1007 fprintf (stderr
, "\tSP%+d: %04x", sp
- SP
,
1008 buf
[0] + buf
[1] * 256);
1014 fprintf (stderr
, flags
& 0x100 ? " V" : " -");
1015 fprintf (stderr
, flags
& 0x004 ? "N" : "-");
1016 fprintf (stderr
, flags
& 0x002 ? "Z" : "-");
1017 fprintf (stderr
, flags
& 0x001 ? "C" : "-");
1020 fprintf (stderr
, "\n");
1026 if ((call_addr
& ~0x3f) == 0x00180)
1029 int syscall_num
= call_addr
& 0x3f;
1030 int arg1
= MSP430_CPU (sd
)->state
.regs
[12];
1031 int arg2
= MSP430_CPU (sd
)->state
.regs
[13];
1032 int arg3
= MSP430_CPU (sd
)->state
.regs
[14];
1033 int arg4
= MSP430_CPU (sd
)->state
.regs
[15];
1035 MSP430_CPU (sd
)->state
.regs
[12] = sim_syscall (MSP430_CPU (sd
),
1036 syscall_num
, arg1
, arg2
,
1045 msp430_step_once (SIM_DESC sd
)
1047 Get_Byte_Local_Data ld
;
1048 unsigned char buf
[100];
1051 unsigned int opcode_pc
;
1052 MSP430_Opcode_Decoded opcode_buf
;
1053 MSP430_Opcode_Decoded
*opcode
= &opcode_buf
;
1055 int u1
, u2
, uresult
;
1061 int op_bytes
, op_bits
;
1066 if (opcode_pc
< 0x10)
1068 fprintf (stderr
, "Fault: PC(%#x) is less than 0x10\n", opcode_pc
);
1069 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1070 MSP430_CPU (sd
)->state
.regs
[0],
1075 if (PC
== MSP430_CPU (sd
)->state
.cio_breakpoint
1076 && STATE_OPEN_KIND (sd
) != SIM_OPEN_DEBUG
)
1081 opsize
= msp430_decode_opcode (MSP430_CPU (sd
)->state
.regs
[0],
1082 opcode
, msp430_getbyte
, &ld
);
1086 fprintf (stderr
, "Fault: undecodable opcode at %#x\n", opcode_pc
);
1087 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1088 MSP430_CPU (sd
)->state
.regs
[0],
1093 if (opcode
->repeat_reg
)
1094 n_repeats
= (MSP430_CPU (sd
)->state
.regs
[opcode
->repeats
] & 0x000f) + 1;
1096 n_repeats
= opcode
->repeats
+ 1;
1098 op_bits
= opcode
->size
;
1113 if (TRACE_ANY_P (MSP430_CPU (sd
)))
1114 trace_prefix (sd
, MSP430_CPU (sd
), NULL_CIA
, opcode_pc
,
1115 TRACE_LINENUM_P (MSP430_CPU (sd
)), NULL
, 0, "");
1117 TRACE_DISASM (MSP430_CPU (sd
), opcode_pc
);
1125 /* Double-operand instructions. */
1127 if (opcode
->n_bytes
== 2
1128 && opcode
->op
[0].type
== MSP430_Operand_Register
1129 && opcode
->op
[0].reg
== MSR_CG
1130 && opcode
->op
[1].type
== MSP430_Operand_Immediate
1131 && opcode
->op
[1].addend
== 0
1132 /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK. */
1133 && opcode
->size
== 8)
1135 /* This is the designated software breakpoint instruction. */
1137 sim_engine_halt (sd
, MSP430_CPU (sd
), NULL
,
1138 MSP430_CPU (sd
)->state
.regs
[0],
1139 sim_stopped
, SIM_SIGTRAP
);
1144 /* Otherwise, do the move. */
1145 for (rept
= 0; rept
< n_repeats
; rept
++)
1153 for (rept
= 0; rept
< n_repeats
; rept
++)
1155 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1160 uresult
= u1
+ u2
+ carry_to_use
;
1161 result
= s1
+ s2
+ carry_to_use
;
1162 TRACE_ALU (MSP430_CPU (sd
), "ADDC: %#x + %#x + %d = %#x",
1163 u1
, u2
, carry_to_use
, uresult
);
1165 FLAGS (result
, uresult
!= ZX (uresult
));
1170 for (rept
= 0; rept
< n_repeats
; rept
++)
1178 TRACE_ALU (MSP430_CPU (sd
), "ADD: %#x + %#x = %#x",
1181 FLAGS (result
, uresult
!= ZX (uresult
));
1186 for (rept
= 0; rept
< n_repeats
; rept
++)
1188 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1193 uresult
= ZX (~u2
) + u1
+ carry_to_use
;
1194 result
= s1
- s2
+ (carry_to_use
- 1);
1195 TRACE_ALU (MSP430_CPU (sd
), "SUBC: %#x - %#x + %d = %#x",
1196 u1
, u2
, carry_to_use
, uresult
);
1198 FLAGS (result
, uresult
!= ZX (uresult
));
1203 for (rept
= 0; rept
< n_repeats
; rept
++)
1209 uresult
= ZX (~u2
) + u1
+ 1;
1210 result
= SX (uresult
);
1211 TRACE_ALU (MSP430_CPU (sd
), "SUB: %#x - %#x = %#x",
1214 FLAGS (result
, uresult
!= ZX (uresult
));
1219 for (rept
= 0; rept
< n_repeats
; rept
++)
1225 uresult
= ZX (~u2
) + u1
+ 1;
1227 TRACE_ALU (MSP430_CPU (sd
), "CMP: %#x - %#x = %x",
1229 FLAGS (result
, uresult
!= ZX (uresult
));
1234 for (rept
= 0; rept
< n_repeats
; rept
++)
1236 carry_to_use
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1239 uresult
= bcd_to_binary (u1
) + bcd_to_binary (u2
) + carry_to_use
;
1240 result
= binary_to_bcd (uresult
);
1241 TRACE_ALU (MSP430_CPU (sd
), "DADD: %#x + %#x + %d = %#x",
1242 u1
, u2
, carry_to_use
, result
);
1244 FLAGS (result
, uresult
> ((opcode
->size
== 8) ? 99 : 9999));
1249 for (rept
= 0; rept
< n_repeats
; rept
++)
1254 TRACE_ALU (MSP430_CPU (sd
), "AND: %#x & %#x = %#x",
1257 FLAGS (uresult
, uresult
!= 0);
1262 for (rept
= 0; rept
< n_repeats
; rept
++)
1267 TRACE_ALU (MSP430_CPU (sd
), "BIT: %#x & %#x -> %#x",
1269 FLAGS (uresult
, uresult
!= 0);
1274 for (rept
= 0; rept
< n_repeats
; rept
++)
1278 uresult
= u1
& ~ u2
;
1279 TRACE_ALU (MSP430_CPU (sd
), "BIC: %#x & ~ %#x = %#x",
1286 for (rept
= 0; rept
< n_repeats
; rept
++)
1291 TRACE_ALU (MSP430_CPU (sd
), "BIS: %#x | %#x = %#x",
1298 for (rept
= 0; rept
< n_repeats
; rept
++)
1300 s1
= 1 << (opcode
->size
- 1);
1304 TRACE_ALU (MSP430_CPU (sd
), "XOR: %#x & %#x = %#x",
1307 FLAGSV (uresult
, uresult
!= 0, (u1
& s1
) && (u2
& s1
));
1311 /* Single-operand instructions. Note: the decoder puts the same
1312 operand in SRC as in DEST, for our convenience. */
1315 for (rept
= 0; rept
< n_repeats
; rept
++)
1318 carry_to_use
= u1
& 1;
1320 if (SR
& MSP430_FLAG_C
)
1321 uresult
|= (1 << (opcode
->size
- 1));
1322 TRACE_ALU (MSP430_CPU (sd
), "RRC: %#x >>= %#x",
1325 FLAGS (uresult
, carry_to_use
);
1330 for (rept
= 0; rept
< n_repeats
; rept
++)
1333 uresult
= ((u1
>> 8) & 0x00ff) | ((u1
<< 8) & 0xff00);
1334 TRACE_ALU (MSP430_CPU (sd
), "SWPB: %#x -> %#x",
1341 for (rept
= 0; rept
< n_repeats
; rept
++)
1345 s1
= 1 << (opcode
->size
- 1);
1346 uresult
= (u1
>> 1) | (u1
& s1
);
1347 TRACE_ALU (MSP430_CPU (sd
), "RRA: %#x >>= %#x",
1355 for (rept
= 0; rept
< n_repeats
; rept
++)
1359 uresult
= (u1
>> 1);
1360 TRACE_ALU (MSP430_CPU (sd
), "RRU: %#x >>= %#x",
1368 for (rept
= 0; rept
< n_repeats
; rept
++)
1372 uresult
= u1
| 0xfff00;
1374 uresult
= u1
& 0x000ff;
1375 TRACE_ALU (MSP430_CPU (sd
), "SXT: %#x -> %#x",
1383 for (rept
= 0; rept
< n_repeats
; rept
++)
1387 new_sp
= REG_GET (MSR_SP
) - op_bytes
;
1388 /* SP is always word-aligned. */
1391 REG_PUT (MSR_SP
, new_sp
);
1393 mem_put_val (sd
, SP
, u1
, op_bits
);
1394 if (opcode
->op
[1].type
== MSP430_Operand_Register
)
1395 opcode
->op
[1].reg
--;
1400 for (rept
= 0; rept
< n_repeats
; rept
++)
1404 u1
= mem_get_val (sd
, SP
, op_bits
);
1406 if (opcode
->op
[0].type
== MSP430_Operand_Register
)
1407 opcode
->op
[0].reg
++;
1408 new_sp
= REG_GET (MSR_SP
) + op_bytes
;
1409 /* SP is always word-aligned. */
1412 REG_PUT (MSR_SP
, new_sp
);
1419 if (maybe_perform_syscall (sd
, u1
))
1422 REG_PUT (MSR_SP
, REG_GET (MSR_SP
) - op_bytes
);
1423 mem_put_val (sd
, SP
, PC
, op_bits
);
1424 TRACE_ALU (MSP430_CPU (sd
), "CALL: func %#x ret %#x, sp %#x",
1426 REG_PUT (MSR_PC
, u1
);
1430 u1
= mem_get_val (sd
, SP
, 16);
1433 PC
= mem_get_val (sd
, SP
, 16);
1435 /* Emulate the RETI action of the 20-bit CPUX architecure.
1436 This is safe for 16-bit CPU architectures as well, since the top
1437 8-bits of SR will have been written to the stack here, and will
1438 have been read as 0. */
1439 PC
|= (u1
& 0xF000) << 4;
1440 TRACE_ALU (MSP430_CPU (sd
), "RETI: pc %#x sr %#x",
1448 switch (opcode
->cond
)
1451 u1
= (SR
& MSP430_FLAG_Z
) ? 0 : 1;
1454 u1
= (SR
& MSP430_FLAG_Z
) ? 1 : 0;
1457 u1
= (SR
& MSP430_FLAG_C
) ? 0 : 1;
1460 u1
= (SR
& MSP430_FLAG_C
) ? 1 : 0;
1463 u1
= (SR
& MSP430_FLAG_N
) ? 1 : 0;
1466 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 1 : 0;
1469 u1
= (!!(SR
& MSP430_FLAG_N
) == !!(SR
& MSP430_FLAG_V
)) ? 0 : 1;
1478 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x -> %#x sr %#x, taken",
1479 cond_string (opcode
->cond
), PC
, i
, SR
);
1481 if (PC
== opcode_pc
)
1485 TRACE_BRANCH (MSP430_CPU (sd
), "J%s: pc %#x to %#x sr %#x, not taken",
1486 cond_string (opcode
->cond
), PC
, i
, SR
);
1490 fprintf (stderr
, "error: unexpected opcode id %d\n", opcode
->id
);
1496 sim_engine_run (SIM_DESC sd
,
1503 msp430_step_once (sd
);
1504 if (sim_events_tick (sd
))
1505 sim_events_process (sd
);