Fix: Output section type does not been applied to section forced output by `. = ...
[binutils-gdb.git] / sim / msp430 / msp430-sim.c
bloba4ff6a4ad3f2f0c68744c16b2a196011531a3a7d
1 /* Simulator for TI MSP430 and MSP430X
3 Copyright (C) 2013-2023 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. */
23 #include "defs.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <inttypes.h>
29 #include <unistd.h>
30 #include <assert.h>
31 #include "opcode/msp430-decode.h"
32 #include "sim-main.h"
33 #include "sim-options.h"
34 #include "sim-signal.h"
35 #include "sim-syscall.h"
36 #include "msp430-sim.h"
38 static sim_cia
39 msp430_pc_fetch (SIM_CPU *cpu)
41 struct msp430_cpu_state *msp430_cpu = MSP430_SIM_CPU (cpu);
43 return msp430_cpu->regs[0];
46 static void
47 msp430_pc_store (SIM_CPU *cpu, sim_cia newpc)
49 struct msp430_cpu_state *msp430_cpu = MSP430_SIM_CPU (cpu);
51 msp430_cpu->regs[0] = newpc;
54 static int
55 msp430_reg_fetch (SIM_CPU *cpu, int regno, void *buf, int len)
57 struct msp430_cpu_state *msp430_cpu = MSP430_SIM_CPU (cpu);
58 unsigned char *memory = buf;
60 if (0 <= regno && regno < 16)
62 if (len == 2)
64 int val = msp430_cpu->regs[regno];
65 memory[0] = val & 0xff;
66 memory[1] = (val >> 8) & 0xff;
67 return 0;
69 else if (len == 4)
71 int val = msp430_cpu->regs[regno];
72 memory[0] = val & 0xff;
73 memory[1] = (val >> 8) & 0xff;
74 memory[2] = (val >> 16) & 0x0f; /* Registers are only 20 bits wide. */
75 memory[3] = 0;
76 return 0;
78 else
79 return -1;
81 else
82 return -1;
85 static int
86 msp430_reg_store (SIM_CPU *cpu, int regno, const void *buf, int len)
88 struct msp430_cpu_state *msp430_cpu = MSP430_SIM_CPU (cpu);
89 const unsigned char *memory = buf;
91 if (0 <= regno && regno < 16)
93 if (len == 2)
95 msp430_cpu->regs[regno] = (memory[1] << 8) | memory[0];
96 return len;
99 if (len == 4)
101 msp430_cpu->regs[regno] = ((memory[2] << 16) & 0xf0000)
102 | (memory[1] << 8) | memory[0];
103 return len;
107 return -1;
110 SIM_DESC
111 sim_open (SIM_OPEN_KIND kind,
112 struct host_callback_struct *callback,
113 struct bfd *abfd,
114 char * const *argv)
116 SIM_DESC sd = sim_state_alloc (kind, callback);
117 struct msp430_cpu_state *msp430_cpu;
118 char c;
119 int i;
121 /* Initialise the simulator. */
123 /* Set default options before parsing user options. */
124 current_target_byte_order = BFD_ENDIAN_LITTLE;
126 if (sim_cpu_alloc_all_extra (sd, 0, sizeof (struct msp430_cpu_state))
127 != SIM_RC_OK)
129 sim_state_free (sd);
130 return 0;
133 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
135 sim_state_free (sd);
136 return 0;
139 if (sim_parse_args (sd, argv) != SIM_RC_OK)
141 sim_state_free (sd);
142 return 0;
145 /* Allocate memory if none specified by user.
146 Note - these values match the memory regions in the libgloss/msp430/msp430[xl]-sim.ld scripts. */
147 if (sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, &c, 0x2, 1) == 0)
148 sim_do_commandf (sd, "memory-region 0,0x20"); /* Needed by the GDB testsuite. */
149 if (sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, &c, 0x500, 1) == 0)
150 sim_do_commandf (sd, "memory-region 0x500,0xfac0"); /* RAM and/or ROM */
151 if (sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, &c, 0xfffe, 1) == 0)
152 sim_do_commandf (sd, "memory-region 0xffc0,0x40"); /* VECTORS. */
153 if (sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, &c, 0x10000, 1) == 0)
154 sim_do_commandf (sd, "memory-region 0x10000,0x80000"); /* HIGH FLASH RAM. */
155 if (sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, &c, 0x90000, 1) == 0)
156 sim_do_commandf (sd, "memory-region 0x90000,0x70000"); /* HIGH ROM. */
158 /* Check for/establish the a reference program image. */
159 if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
161 sim_state_free (sd);
162 return 0;
165 /* Establish any remaining configuration options. */
166 if (sim_config (sd) != SIM_RC_OK)
168 sim_state_free (sd);
169 return 0;
172 if (sim_post_argv_init (sd) != SIM_RC_OK)
174 sim_state_free (sd);
175 return 0;
178 /* CPU specific initialization. */
179 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
181 SIM_CPU *cpu = STATE_CPU (sd, i);
183 CPU_PC_FETCH (cpu) = msp430_pc_fetch;
184 CPU_PC_STORE (cpu) = msp430_pc_store;
185 CPU_REG_FETCH (cpu) = msp430_reg_fetch;
186 CPU_REG_STORE (cpu) = msp430_reg_store;
188 msp430_cpu = MSP430_SIM_CPU (cpu);
189 msp430_cpu->cio_breakpoint = trace_sym_value (sd, "C$$IO$$");
190 msp430_cpu->cio_buffer = trace_sym_value (sd, "__CIOBUF__");
191 if (msp430_cpu->cio_buffer == -1)
192 msp430_cpu->cio_buffer = trace_sym_value (sd, "_CIOBUF_");
195 return sd;
198 SIM_RC
199 sim_create_inferior (SIM_DESC sd,
200 struct bfd *abfd,
201 char * const *argv,
202 char * const *env)
204 unsigned char resetv[2];
205 int c;
206 int new_pc;
208 /* Set the PC to the default reset vector if available. */
209 c = sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, resetv, 0xfffe, 2);
210 new_pc = resetv[0] + 256 * resetv[1];
212 /* If the reset vector isn't initialized, then use the ELF entry. */
213 if (abfd != NULL && !new_pc)
214 new_pc = bfd_get_start_address (abfd);
216 sim_pc_set (STATE_CPU (sd, 0), new_pc);
217 msp430_pc_store (STATE_CPU (sd, 0), new_pc);
219 return SIM_RC_OK;
222 typedef struct
224 SIM_DESC sd;
225 int gb_addr;
226 } Get_Byte_Local_Data;
228 static int
229 msp430_getbyte (void *vld)
231 Get_Byte_Local_Data *ld = (Get_Byte_Local_Data *)vld;
232 char buf[1];
233 SIM_DESC sd = ld->sd;
235 sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, buf, ld->gb_addr, 1);
236 ld->gb_addr ++;
237 return buf[0];
240 #define REG(N) MSP430_SIM_CPU (STATE_CPU (sd, 0))->regs[N]
241 #define PC REG(MSR_PC)
242 #define SP REG(MSR_SP)
243 #define SR REG(MSR_SR)
245 static const char *
246 register_names[] =
248 "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8",
249 "R9", "R10", "R11", "R12", "R13", "R14", "R15"
252 static void
253 trace_reg_put (SIM_DESC sd, int n, unsigned int v)
255 TRACE_REGISTER (STATE_CPU (sd, 0), "PUT: %#x -> %s", v, register_names[n]);
256 REG (n) = v;
259 static unsigned int
260 trace_reg_get (SIM_DESC sd, int n)
262 TRACE_REGISTER (STATE_CPU (sd, 0), "GET: %s -> %#x", register_names[n], REG (n));
263 return REG (n);
266 #define REG_PUT(N,V) trace_reg_put (sd, N, V)
267 #define REG_GET(N) trace_reg_get (sd, N)
269 /* Hardware multiply (and accumulate) support. */
271 static unsigned int
272 zero_ext (unsigned int v, unsigned int bits)
274 v &= ((1 << bits) - 1);
275 return v;
278 static signed long long
279 sign_ext (signed long long v, unsigned int bits)
281 signed long long sb = 1LL << (bits-1); /* Sign bit. */
282 signed long long mb = (1LL << (bits-1)) - 1LL; /* Mantissa bits. */
284 if (v & sb)
285 v = v | ~mb;
286 else
287 v = v & mb;
288 return v;
291 static int
292 get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
294 MSP430_Opcode_Operand *op = opc->op + n;
295 int rv = 0;
296 int addr;
297 unsigned char buf[4];
298 int incval = 0;
300 switch (op->type)
302 case MSP430_Operand_Immediate:
303 rv = op->addend;
304 break;
305 case MSP430_Operand_Register:
306 rv = REG_GET (op->reg);
307 break;
308 case MSP430_Operand_Indirect:
309 case MSP430_Operand_Indirect_Postinc:
310 addr = op->addend;
311 if (op->reg != MSR_None)
313 int reg = REG_GET (op->reg);
314 int sign = opc->ofs_430x ? 20 : 16;
316 /* Index values are signed. */
317 if (addr & (1 << (sign - 1)))
318 addr |= -(1 << sign);
320 addr += reg;
322 /* For MSP430 instructions the sum is limited to 16 bits if the
323 address in the index register is less than 64k even if we are
324 running on an MSP430X CPU. This is for MSP430 compatibility. */
325 if (reg < 0x10000 && ! opc->ofs_430x)
327 if (addr >= 0x10000)
328 fprintf (stderr, " XXX WRAPPING ADDRESS %x on read\n", addr);
330 addr &= 0xffff;
333 addr &= 0xfffff;
334 switch (opc->size)
336 case 8:
337 sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, buf, addr, 1);
338 rv = buf[0];
339 break;
340 case 16:
341 sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, buf, addr, 2);
342 rv = buf[0] | (buf[1] << 8);
343 break;
344 case 20:
345 case 32:
346 sim_core_read_buffer (sd, STATE_CPU (sd, 0), read_map, buf, addr, 4);
347 rv = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
348 break;
349 default:
350 assert (! opc->size);
351 break;
353 #if 0
354 /* Hack - MSP430X5438 serial port status register. */
355 if (addr == 0x5dd)
356 rv = 2;
357 #endif
358 if ((addr >= 0x130 && addr <= 0x15B)
359 || (addr >= 0x4C0 && addr <= 0x4EB))
361 switch (addr)
363 case 0x4CA:
364 case 0x13A:
365 switch (HWMULT (sd, hwmult_type))
367 case UNSIGN_MAC_32:
368 case UNSIGN_32:
369 rv = zero_ext (HWMULT (sd, hwmult_result), 16);
370 break;
371 case SIGN_MAC_32:
372 case SIGN_32:
373 rv = sign_ext (HWMULT (sd, hwmult_signed_result), 16);
374 break;
376 break;
378 case 0x4CC:
379 case 0x13C:
380 switch (HWMULT (sd, hwmult_type))
382 case UNSIGN_MAC_32:
383 case UNSIGN_32:
384 rv = zero_ext (HWMULT (sd, hwmult_result) >> 16, 16);
385 break;
387 case SIGN_MAC_32:
388 case SIGN_32:
389 rv = sign_ext (HWMULT (sd, hwmult_signed_result) >> 16, 16);
390 break;
392 break;
394 case 0x4CE:
395 case 0x13E:
396 switch (HWMULT (sd, hwmult_type))
398 case UNSIGN_32:
399 rv = 0;
400 break;
401 case SIGN_32:
402 rv = HWMULT (sd, hwmult_signed_result) < 0 ? -1 : 0;
403 break;
404 case UNSIGN_MAC_32:
405 rv = 0; /* FIXME: Should be carry of last accumulate. */
406 break;
407 case SIGN_MAC_32:
408 rv = HWMULT (sd, hwmult_signed_accumulator) < 0 ? -1 : 0;
409 break;
411 break;
413 case 0x4E4:
414 case 0x154:
415 rv = zero_ext (HWMULT (sd, hw32mult_result), 16);
416 break;
418 case 0x4E6:
419 case 0x156:
420 rv = zero_ext (HWMULT (sd, hw32mult_result) >> 16, 16);
421 break;
423 case 0x4E8:
424 case 0x158:
425 rv = zero_ext (HWMULT (sd, hw32mult_result) >> 32, 16);
426 break;
428 case 0x4EA:
429 case 0x15A:
430 switch (HWMULT (sd, hw32mult_type))
432 case UNSIGN_64: rv = zero_ext (HWMULT (sd, hw32mult_result) >> 48, 16); break;
433 case SIGN_64: rv = sign_ext (HWMULT (sd, hw32mult_result) >> 48, 16); break;
435 break;
437 default:
438 fprintf (stderr, "unimplemented HW MULT read from %x!\n", addr);
439 break;
443 TRACE_MEMORY (STATE_CPU (sd, 0), "GET: [%#x].%d -> %#x", addr, opc->size,
444 rv);
445 break;
447 default:
448 fprintf (stderr, "invalid operand %d type %d\n", n, op->type);
449 abort ();
452 switch (opc->size)
454 case 8:
455 rv &= 0xff;
456 incval = 1;
457 break;
458 case 16:
459 rv &= 0xffff;
460 incval = 2;
461 break;
462 case 20:
463 rv &= 0xfffff;
464 incval = 4;
465 break;
466 case 32:
467 rv &= 0xffffffff;
468 incval = 4;
469 break;
472 if (op->type == MSP430_Operand_Indirect_Postinc)
473 REG_PUT (op->reg, REG_GET (op->reg) + incval);
475 return rv;
478 static int
479 put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val)
481 MSP430_Opcode_Operand *op = opc->op + n;
482 int rv = 0;
483 int addr;
484 unsigned char buf[4];
485 int incval = 0;
487 switch (opc->size)
489 case 8:
490 val &= 0xff;
491 break;
492 case 16:
493 val &= 0xffff;
494 break;
495 case 20:
496 val &= 0xfffff;
497 break;
498 case 32:
499 val &= 0xffffffff;
500 break;
503 switch (op->type)
505 case MSP430_Operand_Register:
506 REG (op->reg) = val;
507 REG_PUT (op->reg, val);
508 break;
509 case MSP430_Operand_Indirect:
510 case MSP430_Operand_Indirect_Postinc:
511 addr = op->addend;
512 if (op->reg != MSR_None)
514 int reg = REG_GET (op->reg);
515 int sign = opc->ofs_430x ? 20 : 16;
517 /* Index values are signed. */
518 if (addr & (1 << (sign - 1)))
519 addr |= -(1 << sign);
521 addr += reg;
523 /* For MSP430 instructions the sum is limited to 16 bits if the
524 address in the index register is less than 64k even if we are
525 running on an MSP430X CPU. This is for MSP430 compatibility. */
526 if (reg < 0x10000 && ! opc->ofs_430x)
528 if (addr >= 0x10000)
529 fprintf (stderr, " XXX WRAPPING ADDRESS %x on write\n", addr);
531 addr &= 0xffff;
534 addr &= 0xfffff;
536 TRACE_MEMORY (STATE_CPU (sd, 0), "PUT: [%#x].%d <- %#x", addr, opc->size,
537 val);
538 #if 0
539 /* Hack - MSP430X5438 serial port transmit register. */
540 if (addr == 0x5ce)
541 putchar (val);
542 #endif
543 if ((addr >= 0x130 && addr <= 0x15B)
544 || (addr >= 0x4C0 && addr <= 0x4EB))
546 signed int a,b;
548 /* Hardware Multiply emulation. */
549 assert (opc->size == 16);
551 switch (addr)
553 case 0x4C0:
554 case 0x130:
555 HWMULT (sd, hwmult_op1) = val;
556 HWMULT (sd, hwmult_type) = UNSIGN_32;
557 break;
559 case 0x4C2:
560 case 0x132:
561 HWMULT (sd, hwmult_op1) = val;
562 HWMULT (sd, hwmult_type) = SIGN_32;
563 break;
565 case 0x4C4:
566 case 0x134:
567 HWMULT (sd, hwmult_op1) = val;
568 HWMULT (sd, hwmult_type) = UNSIGN_MAC_32;
569 break;
571 case 0x4C6:
572 case 0x136:
573 HWMULT (sd, hwmult_op1) = val;
574 HWMULT (sd, hwmult_type) = SIGN_MAC_32;
575 break;
577 case 0x4C8:
578 case 0x138:
579 HWMULT (sd, hwmult_op2) = val;
580 switch (HWMULT (sd, hwmult_type))
582 case UNSIGN_32:
583 a = HWMULT (sd, hwmult_op1);
584 b = HWMULT (sd, hwmult_op2);
585 /* For unsigned 32-bit multiplication of 16-bit operands, an
586 explicit cast is required to prevent any implicit
587 sign-extension. */
588 HWMULT (sd, hwmult_result) = (uint32_t) a * (uint32_t) b;
589 HWMULT (sd, hwmult_signed_result) = a * b;
590 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_signed_accumulator) = 0;
591 break;
593 case SIGN_32:
594 a = sign_ext (HWMULT (sd, hwmult_op1), 16);
595 b = sign_ext (HWMULT (sd, hwmult_op2), 16);
596 HWMULT (sd, hwmult_signed_result) = a * b;
597 HWMULT (sd, hwmult_result) = (uint32_t) a * (uint32_t) b;
598 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_signed_accumulator) = 0;
599 break;
601 case UNSIGN_MAC_32:
602 a = HWMULT (sd, hwmult_op1);
603 b = HWMULT (sd, hwmult_op2);
604 HWMULT (sd, hwmult_accumulator)
605 += (uint32_t) a * (uint32_t) b;
606 HWMULT (sd, hwmult_signed_accumulator) += a * b;
607 HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_accumulator);
608 HWMULT (sd, hwmult_signed_result) = HWMULT (sd, hwmult_signed_accumulator);
609 break;
611 case SIGN_MAC_32:
612 a = sign_ext (HWMULT (sd, hwmult_op1), 16);
613 b = sign_ext (HWMULT (sd, hwmult_op2), 16);
614 HWMULT (sd, hwmult_accumulator)
615 += (uint32_t) a * (uint32_t) b;
616 HWMULT (sd, hwmult_signed_accumulator) += a * b;
617 HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_accumulator);
618 HWMULT (sd, hwmult_signed_result) = HWMULT (sd, hwmult_signed_accumulator);
619 break;
621 break;
623 case 0x4CA:
624 case 0x13A:
625 /* Copy into LOW result... */
626 switch (HWMULT (sd, hwmult_type))
628 case UNSIGN_MAC_32:
629 case UNSIGN_32:
630 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_result) = zero_ext (val, 16);
631 HWMULT (sd, hwmult_signed_accumulator) = sign_ext (val, 16);
632 break;
633 case SIGN_MAC_32:
634 case SIGN_32:
635 HWMULT (sd, hwmult_signed_accumulator) = HWMULT (sd, hwmult_result) = sign_ext (val, 16);
636 HWMULT (sd, hwmult_accumulator) = zero_ext (val, 16);
637 break;
639 break;
641 case 0x4D0:
642 case 0x140:
643 HWMULT (sd, hw32mult_op1) = val;
644 HWMULT (sd, hw32mult_type) = UNSIGN_64;
645 break;
647 case 0x4D2:
648 case 0x142:
649 HWMULT (sd, hw32mult_op1) = (HWMULT (sd, hw32mult_op1) & 0xFFFF) | (val << 16);
650 break;
652 case 0x4D4:
653 case 0x144:
654 HWMULT (sd, hw32mult_op1) = val;
655 HWMULT (sd, hw32mult_type) = SIGN_64;
656 break;
658 case 0x4D6:
659 case 0x146:
660 HWMULT (sd, hw32mult_op1) = (HWMULT (sd, hw32mult_op1) & 0xFFFF) | (val << 16);
661 break;
663 case 0x4E0:
664 case 0x150:
665 HWMULT (sd, hw32mult_op2) = val;
666 break;
668 case 0x4E2:
669 case 0x152:
670 HWMULT (sd, hw32mult_op2) = (HWMULT (sd, hw32mult_op2) & 0xFFFF) | (val << 16);
671 switch (HWMULT (sd, hw32mult_type))
673 case UNSIGN_64:
674 HWMULT (sd, hw32mult_result)
675 = (uint64_t) HWMULT (sd, hw32mult_op1)
676 * (uint64_t) HWMULT (sd, hw32mult_op2);
677 break;
678 case SIGN_64:
679 HWMULT (sd, hw32mult_result)
680 = sign_ext (HWMULT (sd, hw32mult_op1), 32)
681 * sign_ext (HWMULT (sd, hw32mult_op2), 32);
682 break;
684 break;
686 default:
687 fprintf (stderr, "unimplemented HW MULT write to %x!\n", addr);
688 break;
692 switch (opc->size)
694 case 8:
695 buf[0] = val;
696 sim_core_write_buffer (sd, STATE_CPU (sd, 0), write_map, buf, addr, 1);
697 break;
698 case 16:
699 buf[0] = val;
700 buf[1] = val >> 8;
701 sim_core_write_buffer (sd, STATE_CPU (sd, 0), write_map, buf, addr, 2);
702 break;
703 case 20:
704 case 32:
705 buf[0] = val;
706 buf[1] = val >> 8;
707 buf[2] = val >> 16;
708 buf[3] = val >> 24;
709 sim_core_write_buffer (sd, STATE_CPU (sd, 0), write_map, buf, addr, 4);
710 break;
711 default:
712 assert (! opc->size);
713 break;
715 break;
716 default:
717 fprintf (stderr, "invalid operand %d type %d\n", n, op->type);
718 abort ();
721 switch (opc->size)
723 case 8:
724 rv &= 0xff;
725 incval = 1;
726 break;
727 case 16:
728 rv &= 0xffff;
729 incval = 2;
730 break;
731 case 20:
732 rv &= 0xfffff;
733 incval = 4;
734 break;
735 case 32:
736 rv &= 0xffffffff;
737 incval = 4;
738 break;
741 if (op->type == MSP430_Operand_Indirect_Postinc)
743 int new_val = REG_GET (op->reg) + incval;
744 /* SP is always word-aligned. */
745 if (op->reg == MSR_SP && (new_val & 1))
746 new_val ++;
747 REG_PUT (op->reg, new_val);
750 return rv;
753 static void
754 mem_put_val (SIM_DESC sd, int addr, int val, int bits)
756 MSP430_Opcode_Decoded opc;
758 opc.size = bits;
759 opc.op[0].type = MSP430_Operand_Indirect;
760 opc.op[0].addend = addr;
761 opc.op[0].reg = MSR_None;
762 put_op (sd, &opc, 0, val);
765 static int
766 mem_get_val (SIM_DESC sd, int addr, int bits)
768 MSP430_Opcode_Decoded opc;
770 opc.size = bits;
771 opc.op[0].type = MSP430_Operand_Indirect;
772 opc.op[0].addend = addr;
773 opc.op[0].reg = MSR_None;
774 return get_op (sd, &opc, 0);
777 #define CIO_OPEN (0xF0)
778 #define CIO_CLOSE (0xF1)
779 #define CIO_READ (0xF2)
780 #define CIO_WRITE (0xF3)
781 #define CIO_LSEEK (0xF4)
782 #define CIO_UNLINK (0xF5)
783 #define CIO_GETENV (0xF6)
784 #define CIO_RENAME (0xF7)
785 #define CIO_GETTIME (0xF8)
786 #define CIO_GETCLK (0xF9)
787 #define CIO_SYNC (0xFF)
789 #define CIO_I(n) (parms[(n)] + parms[(n)+1] * 256)
790 #define CIO_L(n) (parms[(n)] + parms[(n)+1] * 256 \
791 + parms[(n)+2] * 65536 + parms[(n)+3] * 16777216)
793 static void
794 msp430_cio (SIM_DESC sd)
796 /* A block of data at __CIOBUF__ describes the I/O operation to
797 perform. */
798 sim_cpu *cpu = STATE_CPU (sd, 0);
799 struct msp430_cpu_state *msp430_cpu = MSP430_SIM_CPU (cpu);
800 unsigned char raw_parms[13];
801 unsigned char parms[8];
802 long length;
803 int command;
804 unsigned char buffer[512];
805 long ret_buflen = 0;
806 long fd, addr, len, rv;
808 sim_core_read_buffer (sd, cpu, 0, parms, msp430_cpu->cio_buffer, 5);
809 length = CIO_I (0);
810 command = parms[2];
812 sim_core_read_buffer (sd, cpu, 0, parms, msp430_cpu->cio_buffer + 3, 8);
813 sim_core_read_buffer (sd, cpu, 0, buffer, msp430_cpu->cio_buffer + 11, length);
815 switch (command)
817 case CIO_WRITE:
818 fd = CIO_I (0);
819 len = CIO_I (2);
821 rv = write (fd, buffer, len);
822 parms[0] = rv & 0xff;
823 parms[1] = rv >> 8;
825 break;
828 sim_core_write_buffer (sd, cpu, 0, parms, msp430_cpu->cio_buffer + 4, 8);
829 if (ret_buflen)
830 sim_core_write_buffer (sd, cpu, 0, buffer, msp430_cpu->cio_buffer + 12,
831 ret_buflen);
834 #define SRC get_op (sd, opcode, 1)
835 #define DSRC get_op (sd, opcode, 0)
836 #define DEST(V) put_op (sd, opcode, 0, (V))
838 #define DO_ALU(OP,SOP,MORE) \
840 int s1 = DSRC; \
841 int s2 = SRC; \
842 int result = s1 OP s2 MORE; \
843 TRACE_ALU (STATE_CPU (sd, 0), "ALU: %#x %s %#x %s = %#x", s1, SOP, \
844 s2, #MORE, result); \
845 DEST (result); \
848 #define SIGN (1 << (opcode->size - 1))
849 #define POS(x) (((x) & SIGN) ? 0 : 1)
850 #define NEG(x) (((x) & SIGN) ? 1 : 0)
852 #define SX(v) sign_ext (v, opcode->size)
853 #define ZX(v) zero_ext (v, opcode->size)
855 static char *
856 flags2string (int f)
858 static char buf[2][6];
859 static int bi = 0;
860 char *bp = buf[bi];
862 bi = (bi + 1) % 2;
864 bp[0] = f & MSP430_FLAG_V ? 'V' : '-';
865 bp[1] = f & MSP430_FLAG_N ? 'N' : '-';
866 bp[2] = f & MSP430_FLAG_Z ? 'Z' : '-';
867 bp[3] = f & MSP430_FLAG_C ? 'C' : '-';
868 bp[4] = 0;
869 return bp;
872 /* Random number that won't show up in our usual logic. */
873 #define MAGIC_OVERFLOW 0x55000F
875 static void
876 do_flags (SIM_DESC sd,
877 MSP430_Opcode_Decoded *opcode,
878 int vnz_val, /* Signed result. */
879 int carry,
880 int overflow)
882 int f = SR;
883 int new_f = 0;
884 int signbit = 1 << (opcode->size - 1);
886 f &= ~opcode->flags_0;
887 f &= ~opcode->flags_set;
888 f |= opcode->flags_1;
890 if (vnz_val & signbit)
891 new_f |= MSP430_FLAG_N;
892 if (! (vnz_val & ((signbit << 1) - 1)))
893 new_f |= MSP430_FLAG_Z;
894 if (overflow == MAGIC_OVERFLOW)
896 if (vnz_val != SX (vnz_val))
897 new_f |= MSP430_FLAG_V;
899 else
900 if (overflow)
901 new_f |= MSP430_FLAG_V;
902 if (carry)
903 new_f |= MSP430_FLAG_C;
905 new_f = f | (new_f & opcode->flags_set);
906 if (SR != new_f)
907 TRACE_ALU (STATE_CPU (sd, 0), "FLAGS: %s -> %s", flags2string (SR),
908 flags2string (new_f));
909 else
910 TRACE_ALU (STATE_CPU (sd, 0), "FLAGS: %s", flags2string (new_f));
911 SR = new_f;
914 #define FLAGS(vnz,c) do_flags (sd, opcode, vnz, c, MAGIC_OVERFLOW)
915 #define FLAGSV(vnz,c,v) do_flags (sd, opcode, vnz, c, v)
917 /* These two assume unsigned 16-bit (four digit) words.
918 Mask off unwanted bits for byte operations. */
920 static int
921 bcd_to_binary (int v)
923 int r = ( ((v >> 0) & 0xf) * 1
924 + ((v >> 4) & 0xf) * 10
925 + ((v >> 8) & 0xf) * 100
926 + ((v >> 12) & 0xf) * 1000);
927 return r;
930 static int
931 binary_to_bcd (int v)
933 int r = ( ((v / 1) % 10) << 0
934 | ((v / 10) % 10) << 4
935 | ((v / 100) % 10) << 8
936 | ((v / 1000) % 10) << 12);
937 return r;
940 static const char *
941 cond_string (int cond)
943 switch (cond)
945 case MSC_nz:
946 return "NZ";
947 case MSC_z:
948 return "Z";
949 case MSC_nc:
950 return "NC";
951 case MSC_c:
952 return "C";
953 case MSC_n:
954 return "N";
955 case MSC_ge:
956 return "GE";
957 case MSC_l:
958 return "L";
959 case MSC_true:
960 return "MP";
961 default:
962 return "??";
966 /* Checks a CALL to address CALL_ADDR. If this is a special
967 syscall address then the call is simulated and non-zero is
968 returned. Otherwise 0 is returned. */
970 static int
971 maybe_perform_syscall (SIM_DESC sd, int call_addr)
973 sim_cpu *cpu = STATE_CPU (sd, 0);
974 struct msp430_cpu_state *msp430_cpu = MSP430_SIM_CPU (cpu);
976 if (call_addr == 0x00160)
978 int i;
980 for (i = 0; i < 16; i++)
982 if (i % 4 == 0)
983 fprintf (stderr, "\t");
984 fprintf (stderr, "R%-2d %05x ", i, msp430_cpu->regs[i]);
985 if (i % 4 == 3)
987 int sp = SP + (3 - (i / 4)) * 2;
988 unsigned char buf[2];
990 sim_core_read_buffer (sd, cpu, read_map, buf, sp, 2);
992 fprintf (stderr, "\tSP%+d: %04x", sp - SP,
993 buf[0] + buf[1] * 256);
995 if (i / 4 == 0)
997 int flags = SR;
999 fprintf (stderr, flags & 0x100 ? " V" : " -");
1000 fprintf (stderr, flags & 0x004 ? "N" : "-");
1001 fprintf (stderr, flags & 0x002 ? "Z" : "-");
1002 fprintf (stderr, flags & 0x001 ? "C" : "-");
1005 fprintf (stderr, "\n");
1008 return 1;
1011 if ((call_addr & ~0x3f) == 0x00180)
1013 /* Syscall! */
1014 int arg1, arg2, arg3, arg4;
1015 int syscall_num = call_addr & 0x3f;
1017 /* syscall_num == 2 is used for the variadic function "open".
1018 The arguments are set up differently for variadic functions.
1019 See slaa534.pdf distributed by TI. */
1020 if (syscall_num == 2)
1022 arg1 = msp430_cpu->regs[12];
1023 arg2 = mem_get_val (sd, SP, 16);
1024 arg3 = mem_get_val (sd, SP + 2, 16);
1025 arg4 = mem_get_val (sd, SP + 4, 16);
1027 else
1029 arg1 = msp430_cpu->regs[12];
1030 arg2 = msp430_cpu->regs[13];
1031 arg3 = msp430_cpu->regs[14];
1032 arg4 = msp430_cpu->regs[15];
1035 msp430_cpu->regs[12] = sim_syscall (cpu, syscall_num, arg1, arg2, arg3,
1036 arg4);
1037 return 1;
1040 return 0;
1043 static void
1044 msp430_step_once (SIM_DESC sd)
1046 sim_cpu *cpu = STATE_CPU (sd, 0);
1047 struct msp430_cpu_state *msp430_cpu = MSP430_SIM_CPU (cpu);
1048 Get_Byte_Local_Data ld;
1049 unsigned char buf[100];
1050 int i;
1051 int opsize;
1052 unsigned int opcode_pc;
1053 MSP430_Opcode_Decoded opcode_buf;
1054 MSP430_Opcode_Decoded *opcode = &opcode_buf;
1055 int s1, s2, result;
1056 int u1 = 0, u2, uresult;
1057 int c = 0, reg;
1058 int sp;
1059 int carry_to_use;
1060 int n_repeats;
1061 int rept;
1062 int op_bytes = 0, op_bits;
1064 PC &= 0xfffff;
1065 opcode_pc = PC;
1067 if (opcode_pc < 0x10)
1069 fprintf (stderr, "Fault: PC(%#x) is less than 0x10\n", opcode_pc);
1070 sim_engine_halt (sd, cpu, NULL, msp430_cpu->regs[0], sim_exited, -1);
1071 return;
1074 if (PC == msp430_cpu->cio_breakpoint && STATE_OPEN_KIND (sd) != SIM_OPEN_DEBUG)
1075 msp430_cio (sd);
1077 ld.sd = sd;
1078 ld.gb_addr = PC;
1079 opsize = msp430_decode_opcode (msp430_cpu->regs[0], opcode, msp430_getbyte,
1080 &ld);
1081 PC += opsize;
1082 if (opsize <= 0)
1084 fprintf (stderr, "Fault: undecodable opcode at %#x\n", opcode_pc);
1085 sim_engine_halt (sd, cpu, NULL, msp430_cpu->regs[0], sim_exited, -1);
1086 return;
1089 if (opcode->repeat_reg)
1090 n_repeats = (msp430_cpu->regs[opcode->repeats] & 0x000f) + 1;
1091 else
1092 n_repeats = opcode->repeats + 1;
1094 op_bits = opcode->size;
1095 switch (op_bits)
1097 case 8:
1098 op_bytes = 1;
1099 break;
1100 case 16:
1101 op_bytes = 2;
1102 break;
1103 case 20:
1104 case 32:
1105 op_bytes = 4;
1106 break;
1109 if (TRACE_ANY_P (cpu))
1110 trace_prefix (sd, cpu, NULL_CIA, opcode_pc, TRACE_LINENUM_P (cpu), NULL,
1111 0, " ");
1113 TRACE_DISASM (cpu, opcode_pc);
1115 carry_to_use = 0;
1116 switch (opcode->id)
1118 case MSO_unknown:
1119 break;
1121 /* Double-operand instructions. */
1122 case MSO_mov:
1123 if (opcode->n_bytes == 2
1124 && opcode->op[0].type == MSP430_Operand_Register
1125 && opcode->op[0].reg == MSR_CG
1126 && opcode->op[1].type == MSP430_Operand_Immediate
1127 && opcode->op[1].addend == 0
1128 /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK. */
1129 && opcode->size == 8)
1131 /* This is the designated software breakpoint instruction. */
1132 PC -= opsize;
1133 sim_engine_halt (sd, cpu, NULL, msp430_cpu->regs[0], sim_stopped,
1134 SIM_SIGTRAP);
1136 else
1138 /* Otherwise, do the move. */
1139 for (rept = 0; rept < n_repeats; rept ++)
1141 DEST (SRC);
1144 break;
1146 case MSO_addc:
1147 for (rept = 0; rept < n_repeats; rept ++)
1149 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
1150 u1 = DSRC;
1151 u2 = SRC;
1152 s1 = SX (u1);
1153 s2 = SX (u2);
1154 uresult = u1 + u2 + carry_to_use;
1155 result = s1 + s2 + carry_to_use;
1156 TRACE_ALU (cpu, "ADDC: %#x + %#x + %d = %#x",
1157 u1, u2, carry_to_use, uresult);
1158 DEST (result);
1159 FLAGS (result, uresult != ZX (uresult));
1161 break;
1163 case MSO_add:
1164 for (rept = 0; rept < n_repeats; rept ++)
1166 u1 = DSRC;
1167 u2 = SRC;
1168 s1 = SX (u1);
1169 s2 = SX (u2);
1170 uresult = u1 + u2;
1171 result = s1 + s2;
1172 TRACE_ALU (cpu, "ADD: %#x + %#x = %#x", u1, u2, uresult);
1173 DEST (result);
1174 FLAGS (result, uresult != ZX (uresult));
1176 break;
1178 case MSO_subc:
1179 for (rept = 0; rept < n_repeats; rept ++)
1181 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
1182 u1 = DSRC;
1183 u2 = SRC;
1184 s1 = SX (u1);
1185 s2 = SX (u2);
1186 uresult = ZX (~u2) + u1 + carry_to_use;
1187 result = s1 - s2 + (carry_to_use - 1);
1188 TRACE_ALU (cpu, "SUBC: %#x - %#x + %d = %#x",
1189 u1, u2, carry_to_use, uresult);
1190 DEST (result);
1191 FLAGS (result, uresult != ZX (uresult));
1193 break;
1195 case MSO_sub:
1196 for (rept = 0; rept < n_repeats; rept ++)
1198 u1 = DSRC;
1199 u2 = SRC;
1200 s1 = SX (u1);
1201 s2 = SX (u2);
1202 uresult = ZX (~u2) + u1 + 1;
1203 result = SX (uresult);
1204 TRACE_ALU (cpu, "SUB: %#x - %#x = %#x",
1205 u1, u2, uresult);
1206 DEST (result);
1207 FLAGS (result, uresult != ZX (uresult));
1209 break;
1211 case MSO_cmp:
1212 for (rept = 0; rept < n_repeats; rept ++)
1214 u1 = DSRC;
1215 u2 = SRC;
1216 s1 = SX (u1);
1217 s2 = SX (u2);
1218 uresult = ZX (~u2) + u1 + 1;
1219 result = s1 - s2;
1220 TRACE_ALU (cpu, "CMP: %#x - %#x = %x",
1221 u1, u2, uresult);
1222 FLAGS (result, uresult != ZX (uresult));
1224 break;
1226 case MSO_dadd:
1227 for (rept = 0; rept < n_repeats; rept ++)
1229 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
1230 u1 = DSRC;
1231 u2 = SRC;
1232 uresult = bcd_to_binary (u1) + bcd_to_binary (u2) + carry_to_use;
1233 result = binary_to_bcd (uresult);
1234 TRACE_ALU (cpu, "DADD: %#x + %#x + %d = %#x",
1235 u1, u2, carry_to_use, result);
1236 DEST (result);
1237 FLAGS (result, uresult > ((opcode->size == 8) ? 99 : 9999));
1239 break;
1241 case MSO_and:
1242 for (rept = 0; rept < n_repeats; rept ++)
1244 u1 = DSRC;
1245 u2 = SRC;
1246 uresult = u1 & u2;
1247 TRACE_ALU (cpu, "AND: %#x & %#x = %#x",
1248 u1, u2, uresult);
1249 DEST (uresult);
1250 FLAGS (uresult, uresult != 0);
1252 break;
1254 case MSO_bit:
1255 for (rept = 0; rept < n_repeats; rept ++)
1257 u1 = DSRC;
1258 u2 = SRC;
1259 uresult = u1 & u2;
1260 TRACE_ALU (cpu, "BIT: %#x & %#x -> %#x",
1261 u1, u2, uresult);
1262 FLAGS (uresult, uresult != 0);
1264 break;
1266 case MSO_bic:
1267 for (rept = 0; rept < n_repeats; rept ++)
1269 u1 = DSRC;
1270 u2 = SRC;
1271 uresult = u1 & ~ u2;
1272 TRACE_ALU (cpu, "BIC: %#x & ~ %#x = %#x",
1273 u1, u2, uresult);
1274 DEST (uresult);
1276 break;
1278 case MSO_bis:
1279 for (rept = 0; rept < n_repeats; rept ++)
1281 u1 = DSRC;
1282 u2 = SRC;
1283 uresult = u1 | u2;
1284 TRACE_ALU (cpu, "BIS: %#x | %#x = %#x",
1285 u1, u2, uresult);
1286 DEST (uresult);
1288 break;
1290 case MSO_xor:
1291 for (rept = 0; rept < n_repeats; rept ++)
1293 s1 = 1 << (opcode->size - 1);
1294 u1 = DSRC;
1295 u2 = SRC;
1296 uresult = u1 ^ u2;
1297 TRACE_ALU (cpu, "XOR: %#x & %#x = %#x",
1298 u1, u2, uresult);
1299 DEST (uresult);
1300 FLAGSV (uresult, uresult != 0, (u1 & s1) && (u2 & s1));
1302 break;
1304 /* Single-operand instructions. Note: the decoder puts the same
1305 operand in SRC as in DEST, for our convenience. */
1307 case MSO_rrc:
1308 for (rept = 0; rept < n_repeats; rept ++)
1310 u1 = SRC;
1311 carry_to_use = u1 & 1;
1312 uresult = u1 >> 1;
1313 /* If the ZC bit of the opcode is set, it means we are synthesizing
1314 RRUX, so the carry bit must be ignored. */
1315 if (opcode->zc == 0 && (SR & MSP430_FLAG_C))
1316 uresult |= (1 << (opcode->size - 1));
1317 TRACE_ALU (cpu, "RRC: %#x >>= %#x",
1318 u1, uresult);
1319 DEST (uresult);
1320 FLAGS (uresult, carry_to_use);
1322 break;
1324 case MSO_swpb:
1325 for (rept = 0; rept < n_repeats; rept ++)
1327 u1 = SRC;
1328 uresult = ((u1 >> 8) & 0x00ff) | ((u1 << 8) & 0xff00);
1329 TRACE_ALU (cpu, "SWPB: %#x -> %#x",
1330 u1, uresult);
1331 DEST (uresult);
1333 break;
1335 case MSO_rra:
1336 for (rept = 0; rept < n_repeats; rept ++)
1338 u1 = SRC;
1339 c = u1 & 1;
1340 s1 = 1 << (opcode->size - 1);
1341 uresult = (u1 >> 1) | (u1 & s1);
1342 TRACE_ALU (cpu, "RRA: %#x >>= %#x",
1343 u1, uresult);
1344 DEST (uresult);
1345 FLAGS (uresult, c);
1347 break;
1349 case MSO_rru:
1350 for (rept = 0; rept < n_repeats; rept ++)
1352 u1 = SRC;
1353 c = u1 & 1;
1354 uresult = (u1 >> 1);
1355 TRACE_ALU (cpu, "RRU: %#x >>= %#x",
1356 u1, uresult);
1357 DEST (uresult);
1358 FLAGS (uresult, c);
1360 break;
1362 case MSO_sxt:
1363 for (rept = 0; rept < n_repeats; rept ++)
1365 u1 = SRC;
1366 if (u1 & 0x80)
1367 uresult = u1 | 0xfff00;
1368 else
1369 uresult = u1 & 0x000ff;
1370 TRACE_ALU (cpu, "SXT: %#x -> %#x", u1, uresult);
1371 DEST (uresult);
1372 FLAGS (uresult, c);
1374 break;
1376 case MSO_push:
1377 for (rept = 0; rept < n_repeats; rept ++)
1379 int new_sp;
1381 new_sp = REG_GET (MSR_SP) - op_bytes;
1382 /* SP is always word-aligned. */
1383 if (new_sp & 1)
1384 new_sp --;
1385 REG_PUT (MSR_SP, new_sp);
1386 u1 = SRC;
1387 mem_put_val (sd, SP, u1, op_bits);
1388 if (opcode->op[1].type == MSP430_Operand_Register)
1389 opcode->op[1].reg --;
1391 break;
1393 case MSO_pop:
1394 for (rept = 0; rept < n_repeats; rept ++)
1396 int new_sp;
1398 u1 = mem_get_val (sd, SP, op_bits);
1399 DEST (u1);
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. */
1404 if (new_sp & 1)
1405 new_sp ++;
1406 REG_PUT (MSR_SP, new_sp);
1408 break;
1410 case MSO_call:
1411 u1 = SRC;
1413 if (maybe_perform_syscall (sd, u1))
1414 break;
1416 REG_PUT (MSR_SP, REG_GET (MSR_SP) - op_bytes);
1417 mem_put_val (sd, SP, PC, op_bits);
1418 TRACE_ALU (cpu, "CALL: func %#x ret %#x, sp %#x",
1419 u1, PC, SP);
1420 REG_PUT (MSR_PC, u1);
1421 break;
1423 case MSO_reti:
1424 u1 = mem_get_val (sd, SP, 16);
1425 SR = u1 & 0xFF;
1426 SP += 2;
1427 PC = mem_get_val (sd, SP, 16);
1428 SP += 2;
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 (cpu, "RETI: pc %#x sr %#x", PC, SR);
1435 break;
1437 /* Jumps. */
1439 case MSO_jmp:
1440 i = SRC;
1441 switch (opcode->cond)
1443 case MSC_nz:
1444 u1 = (SR & MSP430_FLAG_Z) ? 0 : 1;
1445 break;
1446 case MSC_z:
1447 u1 = (SR & MSP430_FLAG_Z) ? 1 : 0;
1448 break;
1449 case MSC_nc:
1450 u1 = (SR & MSP430_FLAG_C) ? 0 : 1;
1451 break;
1452 case MSC_c:
1453 u1 = (SR & MSP430_FLAG_C) ? 1 : 0;
1454 break;
1455 case MSC_n:
1456 u1 = (SR & MSP430_FLAG_N) ? 1 : 0;
1457 break;
1458 case MSC_ge:
1459 u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 1 : 0;
1460 break;
1461 case MSC_l:
1462 u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 0 : 1;
1463 break;
1464 case MSC_true:
1465 u1 = 1;
1466 break;
1469 if (u1)
1471 TRACE_BRANCH (cpu, "J%s: pc %#x -> %#x sr %#x, taken",
1472 cond_string (opcode->cond), PC, i, SR);
1473 PC = i;
1474 if (PC == opcode_pc)
1475 exit (0);
1477 else
1478 TRACE_BRANCH (cpu, "J%s: pc %#x to %#x sr %#x, not taken",
1479 cond_string (opcode->cond), PC, i, SR);
1480 break;
1482 default:
1483 fprintf (stderr, "error: unexpected opcode id %d\n", opcode->id);
1484 exit (1);
1488 void
1489 sim_engine_run (SIM_DESC sd,
1490 int next_cpu_nr,
1491 int nr_cpus,
1492 int siggnal)
1494 while (1)
1496 msp430_step_once (sd);
1497 if (sim_events_tick (sd))
1498 sim_events_process (sd);