]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/msp430/msp430-sim.c
sim: msp430: migrate to standard uintXX_t types
[thirdparty/binutils-gdb.git] / sim / msp430 / msp430-sim.c
1 /* Simulator for TI MSP430 and MSP430X
2
3 Copyright (C) 2013-2022 Free Software Foundation, Inc.
4 Contributed by Red Hat.
5 Based on sim/bfin/bfin-sim.c which was contributed by Analog Devices, Inc.
6
7 This file is part of simulators.
8
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.
13
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.
18
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/>. */
21
22 /* This must come before any other includes. */
23 #include "defs.h"
24
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-signal.h"
34 #include "sim-syscall.h"
35
36 static sim_cia
37 msp430_pc_fetch (SIM_CPU *cpu)
38 {
39 return cpu->state.regs[0];
40 }
41
42 static void
43 msp430_pc_store (SIM_CPU *cpu, sim_cia newpc)
44 {
45 cpu->state.regs[0] = newpc;
46 }
47
48 static int
49 msp430_reg_fetch (SIM_CPU *cpu, int regno, unsigned char *buf, int len)
50 {
51 if (0 <= regno && regno < 16)
52 {
53 if (len == 2)
54 {
55 int val = cpu->state.regs[regno];
56 buf[0] = val & 0xff;
57 buf[1] = (val >> 8) & 0xff;
58 return 0;
59 }
60 else if (len == 4)
61 {
62 int val = cpu->state.regs[regno];
63 buf[0] = val & 0xff;
64 buf[1] = (val >> 8) & 0xff;
65 buf[2] = (val >> 16) & 0x0f; /* Registers are only 20 bits wide. */
66 buf[3] = 0;
67 return 0;
68 }
69 else
70 return -1;
71 }
72 else
73 return -1;
74 }
75
76 static int
77 msp430_reg_store (SIM_CPU *cpu, int regno, unsigned char *buf, int len)
78 {
79 if (0 <= regno && regno < 16)
80 {
81 if (len == 2)
82 {
83 cpu->state.regs[regno] = (buf[1] << 8) | buf[0];
84 return len;
85 }
86
87 if (len == 4)
88 {
89 cpu->state.regs[regno] = ((buf[2] << 16) & 0xf0000)
90 | (buf[1] << 8) | buf[0];
91 return len;
92 }
93 }
94
95 return -1;
96 }
97
98 static inline void
99 msp430_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu)
100 {
101 memset (&cpu->state, 0, sizeof (cpu->state));
102 }
103
104 SIM_DESC
105 sim_open (SIM_OPEN_KIND kind,
106 struct host_callback_struct *callback,
107 struct bfd *abfd,
108 char * const *argv)
109 {
110 SIM_DESC sd = sim_state_alloc (kind, callback);
111 char c;
112
113 /* Initialise the simulator. */
114
115 /* Set default options before parsing user options. */
116 current_target_byte_order = BFD_ENDIAN_LITTLE;
117
118 if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
119 {
120 sim_state_free (sd);
121 return 0;
122 }
123
124 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
125 {
126 sim_state_free (sd);
127 return 0;
128 }
129
130 if (sim_parse_args (sd, argv) != SIM_RC_OK)
131 {
132 sim_state_free (sd);
133 return 0;
134 }
135
136 CPU_PC_FETCH (MSP430_CPU (sd)) = msp430_pc_fetch;
137 CPU_PC_STORE (MSP430_CPU (sd)) = msp430_pc_store;
138 CPU_REG_FETCH (MSP430_CPU (sd)) = msp430_reg_fetch;
139 CPU_REG_STORE (MSP430_CPU (sd)) = msp430_reg_store;
140
141 /* Allocate memory if none specified by user.
142 Note - these values match the memory regions in the libgloss/msp430/msp430[xl]-sim.ld scripts. */
143 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x2, 1) == 0)
144 sim_do_commandf (sd, "memory-region 0,0x20"); /* Needed by the GDB testsuite. */
145 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x500, 1) == 0)
146 sim_do_commandf (sd, "memory-region 0x500,0xfac0"); /* RAM and/or ROM */
147 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0xfffe, 1) == 0)
148 sim_do_commandf (sd, "memory-region 0xffc0,0x40"); /* VECTORS. */
149 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x10000, 1) == 0)
150 sim_do_commandf (sd, "memory-region 0x10000,0x80000"); /* HIGH FLASH RAM. */
151 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x90000, 1) == 0)
152 sim_do_commandf (sd, "memory-region 0x90000,0x70000"); /* HIGH ROM. */
153
154 /* Check for/establish the a reference program image. */
155 if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
156 {
157 sim_state_free (sd);
158 return 0;
159 }
160
161 /* Establish any remaining configuration options. */
162 if (sim_config (sd) != SIM_RC_OK)
163 {
164 sim_state_free (sd);
165 return 0;
166 }
167
168 if (sim_post_argv_init (sd) != SIM_RC_OK)
169 {
170 sim_state_free (sd);
171 return 0;
172 }
173
174 /* CPU specific initialization. */
175 assert (MAX_NR_PROCESSORS == 1);
176 msp430_initialize_cpu (sd, MSP430_CPU (sd));
177
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_");
182
183 return sd;
184 }
185
186 SIM_RC
187 sim_create_inferior (SIM_DESC sd,
188 struct bfd *abfd,
189 char * const *argv,
190 char * const *env)
191 {
192 unsigned char resetv[2];
193 int c;
194 int new_pc;
195
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];
199
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);
203
204 sim_pc_set (MSP430_CPU (sd), new_pc);
205 msp430_pc_store (MSP430_CPU (sd), new_pc);
206
207 return SIM_RC_OK;
208 }
209
210 typedef struct
211 {
212 SIM_DESC sd;
213 int gb_addr;
214 } Get_Byte_Local_Data;
215
216 static int
217 msp430_getbyte (void *vld)
218 {
219 Get_Byte_Local_Data *ld = (Get_Byte_Local_Data *)vld;
220 char buf[1];
221 SIM_DESC sd = ld->sd;
222
223 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, ld->gb_addr, 1);
224 ld->gb_addr ++;
225 return buf[0];
226 }
227
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)
232
233 static const char *
234 register_names[] =
235 {
236 "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8",
237 "R9", "R10", "R11", "R12", "R13", "R14", "R15"
238 };
239
240 static void
241 trace_reg_put (SIM_DESC sd, int n, unsigned int v)
242 {
243 TRACE_REGISTER (MSP430_CPU (sd), "PUT: %#x -> %s", v, register_names[n]);
244 REG (n) = v;
245 }
246
247 static unsigned int
248 trace_reg_get (SIM_DESC sd, int n)
249 {
250 TRACE_REGISTER (MSP430_CPU (sd), "GET: %s -> %#x", register_names[n], REG (n));
251 return REG (n);
252 }
253
254 #define REG_PUT(N,V) trace_reg_put (sd, N, V)
255 #define REG_GET(N) trace_reg_get (sd, N)
256
257 /* Hardware multiply (and accumulate) support. */
258
259 static unsigned int
260 zero_ext (unsigned int v, unsigned int bits)
261 {
262 v &= ((1 << bits) - 1);
263 return v;
264 }
265
266 static signed long long
267 sign_ext (signed long long v, unsigned int bits)
268 {
269 signed long long sb = 1LL << (bits-1); /* Sign bit. */
270 signed long long mb = (1LL << (bits-1)) - 1LL; /* Mantissa bits. */
271
272 if (v & sb)
273 v = v | ~mb;
274 else
275 v = v & mb;
276 return v;
277 }
278
279 static int
280 get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
281 {
282 MSP430_Opcode_Operand *op = opc->op + n;
283 int rv = 0;
284 int addr;
285 unsigned char buf[4];
286 int incval = 0;
287
288 switch (op->type)
289 {
290 case MSP430_Operand_Immediate:
291 rv = op->addend;
292 break;
293 case MSP430_Operand_Register:
294 rv = REG_GET (op->reg);
295 break;
296 case MSP430_Operand_Indirect:
297 case MSP430_Operand_Indirect_Postinc:
298 addr = op->addend;
299 if (op->reg != MSR_None)
300 {
301 int reg = REG_GET (op->reg);
302 int sign = opc->ofs_430x ? 20 : 16;
303
304 /* Index values are signed. */
305 if (addr & (1 << (sign - 1)))
306 addr |= -(1 << sign);
307
308 addr += reg;
309
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)
314 {
315 if (addr >= 0x10000)
316 fprintf (stderr, " XXX WRAPPING ADDRESS %x on read\n", addr);
317
318 addr &= 0xffff;
319 }
320 }
321 addr &= 0xfffff;
322 switch (opc->size)
323 {
324 case 8:
325 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 1);
326 rv = buf[0];
327 break;
328 case 16:
329 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 2);
330 rv = buf[0] | (buf[1] << 8);
331 break;
332 case 20:
333 case 32:
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);
336 break;
337 default:
338 assert (! opc->size);
339 break;
340 }
341 #if 0
342 /* Hack - MSP430X5438 serial port status register. */
343 if (addr == 0x5dd)
344 rv = 2;
345 #endif
346 if ((addr >= 0x130 && addr <= 0x15B)
347 || (addr >= 0x4C0 && addr <= 0x4EB))
348 {
349 switch (addr)
350 {
351 case 0x4CA:
352 case 0x13A:
353 switch (HWMULT (sd, hwmult_type))
354 {
355 case UNSIGN_MAC_32:
356 case UNSIGN_32:
357 rv = zero_ext (HWMULT (sd, hwmult_result), 16);
358 break;
359 case SIGN_MAC_32:
360 case SIGN_32:
361 rv = sign_ext (HWMULT (sd, hwmult_signed_result), 16);
362 break;
363 }
364 break;
365
366 case 0x4CC:
367 case 0x13C:
368 switch (HWMULT (sd, hwmult_type))
369 {
370 case UNSIGN_MAC_32:
371 case UNSIGN_32:
372 rv = zero_ext (HWMULT (sd, hwmult_result) >> 16, 16);
373 break;
374
375 case SIGN_MAC_32:
376 case SIGN_32:
377 rv = sign_ext (HWMULT (sd, hwmult_signed_result) >> 16, 16);
378 break;
379 }
380 break;
381
382 case 0x4CE:
383 case 0x13E:
384 switch (HWMULT (sd, hwmult_type))
385 {
386 case UNSIGN_32:
387 rv = 0;
388 break;
389 case SIGN_32:
390 rv = HWMULT (sd, hwmult_signed_result) < 0 ? -1 : 0;
391 break;
392 case UNSIGN_MAC_32:
393 rv = 0; /* FIXME: Should be carry of last accumulate. */
394 break;
395 case SIGN_MAC_32:
396 rv = HWMULT (sd, hwmult_signed_accumulator) < 0 ? -1 : 0;
397 break;
398 }
399 break;
400
401 case 0x4E4:
402 case 0x154:
403 rv = zero_ext (HWMULT (sd, hw32mult_result), 16);
404 break;
405
406 case 0x4E6:
407 case 0x156:
408 rv = zero_ext (HWMULT (sd, hw32mult_result) >> 16, 16);
409 break;
410
411 case 0x4E8:
412 case 0x158:
413 rv = zero_ext (HWMULT (sd, hw32mult_result) >> 32, 16);
414 break;
415
416 case 0x4EA:
417 case 0x15A:
418 switch (HWMULT (sd, hw32mult_type))
419 {
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;
422 }
423 break;
424
425 default:
426 fprintf (stderr, "unimplemented HW MULT read from %x!\n", addr);
427 break;
428 }
429 }
430
431 TRACE_MEMORY (MSP430_CPU (sd), "GET: [%#x].%d -> %#x", addr, opc->size,
432 rv);
433 break;
434
435 default:
436 fprintf (stderr, "invalid operand %d type %d\n", n, op->type);
437 abort ();
438 }
439
440 switch (opc->size)
441 {
442 case 8:
443 rv &= 0xff;
444 incval = 1;
445 break;
446 case 16:
447 rv &= 0xffff;
448 incval = 2;
449 break;
450 case 20:
451 rv &= 0xfffff;
452 incval = 4;
453 break;
454 case 32:
455 rv &= 0xffffffff;
456 incval = 4;
457 break;
458 }
459
460 if (op->type == MSP430_Operand_Indirect_Postinc)
461 REG_PUT (op->reg, REG_GET (op->reg) + incval);
462
463 return rv;
464 }
465
466 static int
467 put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val)
468 {
469 MSP430_Opcode_Operand *op = opc->op + n;
470 int rv = 0;
471 int addr;
472 unsigned char buf[4];
473 int incval = 0;
474
475 switch (opc->size)
476 {
477 case 8:
478 val &= 0xff;
479 break;
480 case 16:
481 val &= 0xffff;
482 break;
483 case 20:
484 val &= 0xfffff;
485 break;
486 case 32:
487 val &= 0xffffffff;
488 break;
489 }
490
491 switch (op->type)
492 {
493 case MSP430_Operand_Register:
494 REG (op->reg) = val;
495 REG_PUT (op->reg, val);
496 break;
497 case MSP430_Operand_Indirect:
498 case MSP430_Operand_Indirect_Postinc:
499 addr = op->addend;
500 if (op->reg != MSR_None)
501 {
502 int reg = REG_GET (op->reg);
503 int sign = opc->ofs_430x ? 20 : 16;
504
505 /* Index values are signed. */
506 if (addr & (1 << (sign - 1)))
507 addr |= -(1 << sign);
508
509 addr += reg;
510
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)
515 {
516 if (addr >= 0x10000)
517 fprintf (stderr, " XXX WRAPPING ADDRESS %x on write\n", addr);
518
519 addr &= 0xffff;
520 }
521 }
522 addr &= 0xfffff;
523
524 TRACE_MEMORY (MSP430_CPU (sd), "PUT: [%#x].%d <- %#x", addr, opc->size,
525 val);
526 #if 0
527 /* Hack - MSP430X5438 serial port transmit register. */
528 if (addr == 0x5ce)
529 putchar (val);
530 #endif
531 if ((addr >= 0x130 && addr <= 0x15B)
532 || (addr >= 0x4C0 && addr <= 0x4EB))
533 {
534 signed int a,b;
535
536 /* Hardware Multiply emulation. */
537 assert (opc->size == 16);
538
539 switch (addr)
540 {
541 case 0x4C0:
542 case 0x130:
543 HWMULT (sd, hwmult_op1) = val;
544 HWMULT (sd, hwmult_type) = UNSIGN_32;
545 break;
546
547 case 0x4C2:
548 case 0x132:
549 HWMULT (sd, hwmult_op1) = val;
550 HWMULT (sd, hwmult_type) = SIGN_32;
551 break;
552
553 case 0x4C4:
554 case 0x134:
555 HWMULT (sd, hwmult_op1) = val;
556 HWMULT (sd, hwmult_type) = UNSIGN_MAC_32;
557 break;
558
559 case 0x4C6:
560 case 0x136:
561 HWMULT (sd, hwmult_op1) = val;
562 HWMULT (sd, hwmult_type) = SIGN_MAC_32;
563 break;
564
565 case 0x4C8:
566 case 0x138:
567 HWMULT (sd, hwmult_op2) = val;
568 switch (HWMULT (sd, hwmult_type))
569 {
570 case UNSIGN_32:
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
575 sign-extension. */
576 HWMULT (sd, hwmult_result) = (uint32_t) a * (uint32_t) b;
577 HWMULT (sd, hwmult_signed_result) = a * b;
578 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_signed_accumulator) = 0;
579 break;
580
581 case SIGN_32:
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) = (uint32_t) a * (uint32_t) b;
586 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_signed_accumulator) = 0;
587 break;
588
589 case UNSIGN_MAC_32:
590 a = HWMULT (sd, hwmult_op1);
591 b = HWMULT (sd, hwmult_op2);
592 HWMULT (sd, hwmult_accumulator)
593 += (uint32_t) a * (uint32_t) 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);
597 break;
598
599 case SIGN_MAC_32:
600 a = sign_ext (HWMULT (sd, hwmult_op1), 16);
601 b = sign_ext (HWMULT (sd, hwmult_op2), 16);
602 HWMULT (sd, hwmult_accumulator)
603 += (uint32_t) a * (uint32_t) 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);
607 break;
608 }
609 break;
610
611 case 0x4CA:
612 case 0x13A:
613 /* Copy into LOW result... */
614 switch (HWMULT (sd, hwmult_type))
615 {
616 case UNSIGN_MAC_32:
617 case UNSIGN_32:
618 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_result) = zero_ext (val, 16);
619 HWMULT (sd, hwmult_signed_accumulator) = sign_ext (val, 16);
620 break;
621 case SIGN_MAC_32:
622 case SIGN_32:
623 HWMULT (sd, hwmult_signed_accumulator) = HWMULT (sd, hwmult_result) = sign_ext (val, 16);
624 HWMULT (sd, hwmult_accumulator) = zero_ext (val, 16);
625 break;
626 }
627 break;
628
629 case 0x4D0:
630 case 0x140:
631 HWMULT (sd, hw32mult_op1) = val;
632 HWMULT (sd, hw32mult_type) = UNSIGN_64;
633 break;
634
635 case 0x4D2:
636 case 0x142:
637 HWMULT (sd, hw32mult_op1) = (HWMULT (sd, hw32mult_op1) & 0xFFFF) | (val << 16);
638 break;
639
640 case 0x4D4:
641 case 0x144:
642 HWMULT (sd, hw32mult_op1) = val;
643 HWMULT (sd, hw32mult_type) = SIGN_64;
644 break;
645
646 case 0x4D6:
647 case 0x146:
648 HWMULT (sd, hw32mult_op1) = (HWMULT (sd, hw32mult_op1) & 0xFFFF) | (val << 16);
649 break;
650
651 case 0x4E0:
652 case 0x150:
653 HWMULT (sd, hw32mult_op2) = val;
654 break;
655
656 case 0x4E2:
657 case 0x152:
658 HWMULT (sd, hw32mult_op2) = (HWMULT (sd, hw32mult_op2) & 0xFFFF) | (val << 16);
659 switch (HWMULT (sd, hw32mult_type))
660 {
661 case UNSIGN_64:
662 HWMULT (sd, hw32mult_result)
663 = (uint64_t) HWMULT (sd, hw32mult_op1)
664 * (uint64_t) HWMULT (sd, hw32mult_op2);
665 break;
666 case SIGN_64:
667 HWMULT (sd, hw32mult_result)
668 = sign_ext (HWMULT (sd, hw32mult_op1), 32)
669 * sign_ext (HWMULT (sd, hw32mult_op2), 32);
670 break;
671 }
672 break;
673
674 default:
675 fprintf (stderr, "unimplemented HW MULT write to %x!\n", addr);
676 break;
677 }
678 }
679
680 switch (opc->size)
681 {
682 case 8:
683 buf[0] = val;
684 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 1);
685 break;
686 case 16:
687 buf[0] = val;
688 buf[1] = val >> 8;
689 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 2);
690 break;
691 case 20:
692 case 32:
693 buf[0] = val;
694 buf[1] = val >> 8;
695 buf[2] = val >> 16;
696 buf[3] = val >> 24;
697 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 4);
698 break;
699 default:
700 assert (! opc->size);
701 break;
702 }
703 break;
704 default:
705 fprintf (stderr, "invalid operand %d type %d\n", n, op->type);
706 abort ();
707 }
708
709 switch (opc->size)
710 {
711 case 8:
712 rv &= 0xff;
713 incval = 1;
714 break;
715 case 16:
716 rv &= 0xffff;
717 incval = 2;
718 break;
719 case 20:
720 rv &= 0xfffff;
721 incval = 4;
722 break;
723 case 32:
724 rv &= 0xffffffff;
725 incval = 4;
726 break;
727 }
728
729 if (op->type == MSP430_Operand_Indirect_Postinc)
730 {
731 int new_val = REG_GET (op->reg) + incval;
732 /* SP is always word-aligned. */
733 if (op->reg == MSR_SP && (new_val & 1))
734 new_val ++;
735 REG_PUT (op->reg, new_val);
736 }
737
738 return rv;
739 }
740
741 static void
742 mem_put_val (SIM_DESC sd, int addr, int val, int bits)
743 {
744 MSP430_Opcode_Decoded opc;
745
746 opc.size = bits;
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);
751 }
752
753 static int
754 mem_get_val (SIM_DESC sd, int addr, int bits)
755 {
756 MSP430_Opcode_Decoded opc;
757
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 return get_op (sd, &opc, 0);
763 }
764
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)
776
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)
780
781 static void
782 msp430_cio (SIM_DESC sd)
783 {
784 /* A block of data at __CIOBUF__ describes the I/O operation to
785 perform. */
786
787 unsigned char raw_parms[13];
788 unsigned char parms[8];
789 long length;
790 int command;
791 unsigned char buffer[512];
792 long ret_buflen = 0;
793 long fd, addr, len, rv;
794
795 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, parms,
796 MSP430_CPU (sd)->state.cio_buffer, 5);
797 length = CIO_I (0);
798 command = parms[2];
799
800 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, parms,
801 MSP430_CPU (sd)->state.cio_buffer + 3, 8);
802
803 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, buffer,
804 MSP430_CPU (sd)->state.cio_buffer + 11, length);
805
806 switch (command)
807 {
808 case CIO_WRITE:
809 fd = CIO_I (0);
810 len = CIO_I (2);
811
812 rv = write (fd, buffer, len);
813 parms[0] = rv & 0xff;
814 parms[1] = rv >> 8;
815
816 break;
817 }
818
819 sim_core_write_buffer (sd, MSP430_CPU (sd), 0, parms,
820 MSP430_CPU (sd)->state.cio_buffer + 4, 8);
821 if (ret_buflen)
822 sim_core_write_buffer (sd, MSP430_CPU (sd), 0, buffer,
823 MSP430_CPU (sd)->state.cio_buffer + 12, ret_buflen);
824 }
825
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))
829
830 #define DO_ALU(OP,SOP,MORE) \
831 { \
832 int s1 = DSRC; \
833 int s2 = SRC; \
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); \
837 DEST (result); \
838 }
839
840 #define SIGN (1 << (opcode->size - 1))
841 #define POS(x) (((x) & SIGN) ? 0 : 1)
842 #define NEG(x) (((x) & SIGN) ? 1 : 0)
843
844 #define SX(v) sign_ext (v, opcode->size)
845 #define ZX(v) zero_ext (v, opcode->size)
846
847 static char *
848 flags2string (int f)
849 {
850 static char buf[2][6];
851 static int bi = 0;
852 char *bp = buf[bi];
853
854 bi = (bi + 1) % 2;
855
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' : '-';
860 bp[4] = 0;
861 return bp;
862 }
863
864 /* Random number that won't show up in our usual logic. */
865 #define MAGIC_OVERFLOW 0x55000F
866
867 static void
868 do_flags (SIM_DESC sd,
869 MSP430_Opcode_Decoded *opcode,
870 int vnz_val, /* Signed result. */
871 int carry,
872 int overflow)
873 {
874 int f = SR;
875 int new_f = 0;
876 int signbit = 1 << (opcode->size - 1);
877
878 f &= ~opcode->flags_0;
879 f &= ~opcode->flags_set;
880 f |= opcode->flags_1;
881
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)
887 {
888 if (vnz_val != SX (vnz_val))
889 new_f |= MSP430_FLAG_V;
890 }
891 else
892 if (overflow)
893 new_f |= MSP430_FLAG_V;
894 if (carry)
895 new_f |= MSP430_FLAG_C;
896
897 new_f = f | (new_f & opcode->flags_set);
898 if (SR != new_f)
899 TRACE_ALU (MSP430_CPU (sd), "FLAGS: %s -> %s", flags2string (SR),
900 flags2string (new_f));
901 else
902 TRACE_ALU (MSP430_CPU (sd), "FLAGS: %s", flags2string (new_f));
903 SR = new_f;
904 }
905
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)
908
909 /* These two assume unsigned 16-bit (four digit) words.
910 Mask off unwanted bits for byte operations. */
911
912 static int
913 bcd_to_binary (int v)
914 {
915 int r = ( ((v >> 0) & 0xf) * 1
916 + ((v >> 4) & 0xf) * 10
917 + ((v >> 8) & 0xf) * 100
918 + ((v >> 12) & 0xf) * 1000);
919 return r;
920 }
921
922 static int
923 binary_to_bcd (int v)
924 {
925 int r = ( ((v / 1) % 10) << 0
926 | ((v / 10) % 10) << 4
927 | ((v / 100) % 10) << 8
928 | ((v / 1000) % 10) << 12);
929 return r;
930 }
931
932 static const char *
933 cond_string (int cond)
934 {
935 switch (cond)
936 {
937 case MSC_nz:
938 return "NZ";
939 case MSC_z:
940 return "Z";
941 case MSC_nc:
942 return "NC";
943 case MSC_c:
944 return "C";
945 case MSC_n:
946 return "N";
947 case MSC_ge:
948 return "GE";
949 case MSC_l:
950 return "L";
951 case MSC_true:
952 return "MP";
953 default:
954 return "??";
955 }
956 }
957
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. */
961
962 static int
963 maybe_perform_syscall (SIM_DESC sd, int call_addr)
964 {
965 if (call_addr == 0x00160)
966 {
967 int i;
968
969 for (i = 0; i < 16; i++)
970 {
971 if (i % 4 == 0)
972 fprintf (stderr, "\t");
973 fprintf (stderr, "R%-2d %05x ", i, MSP430_CPU (sd)->state.regs[i]);
974 if (i % 4 == 3)
975 {
976 int sp = SP + (3 - (i / 4)) * 2;
977 unsigned char buf[2];
978
979 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, sp, 2);
980
981 fprintf (stderr, "\tSP%+d: %04x", sp - SP,
982 buf[0] + buf[1] * 256);
983
984 if (i / 4 == 0)
985 {
986 int flags = SR;
987
988 fprintf (stderr, flags & 0x100 ? " V" : " -");
989 fprintf (stderr, flags & 0x004 ? "N" : "-");
990 fprintf (stderr, flags & 0x002 ? "Z" : "-");
991 fprintf (stderr, flags & 0x001 ? "C" : "-");
992 }
993
994 fprintf (stderr, "\n");
995 }
996 }
997 return 1;
998 }
999
1000 if ((call_addr & ~0x3f) == 0x00180)
1001 {
1002 /* Syscall! */
1003 int arg1, arg2, arg3, arg4;
1004 int syscall_num = call_addr & 0x3f;
1005
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)
1010 {
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);
1015 }
1016 else
1017 {
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];
1022 }
1023
1024 MSP430_CPU (sd)->state.regs[12] = sim_syscall (MSP430_CPU (sd),
1025 syscall_num, arg1, arg2,
1026 arg3, arg4);
1027 return 1;
1028 }
1029
1030 return 0;
1031 }
1032
1033 static void
1034 msp430_step_once (SIM_DESC sd)
1035 {
1036 Get_Byte_Local_Data ld;
1037 unsigned char buf[100];
1038 int i;
1039 int opsize;
1040 unsigned int opcode_pc;
1041 MSP430_Opcode_Decoded opcode_buf;
1042 MSP430_Opcode_Decoded *opcode = &opcode_buf;
1043 int s1, s2, result;
1044 int u1 = 0, u2, uresult;
1045 int c = 0, reg;
1046 int sp;
1047 int carry_to_use;
1048 int n_repeats;
1049 int rept;
1050 int op_bytes = 0, op_bits;
1051
1052 PC &= 0xfffff;
1053 opcode_pc = PC;
1054
1055 if (opcode_pc < 0x10)
1056 {
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],
1060 sim_exited, -1);
1061 return;
1062 }
1063
1064 if (PC == MSP430_CPU (sd)->state.cio_breakpoint
1065 && STATE_OPEN_KIND (sd) != SIM_OPEN_DEBUG)
1066 msp430_cio (sd);
1067
1068 ld.sd = sd;
1069 ld.gb_addr = PC;
1070 opsize = msp430_decode_opcode (MSP430_CPU (sd)->state.regs[0],
1071 opcode, msp430_getbyte, &ld);
1072 PC += opsize;
1073 if (opsize <= 0)
1074 {
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],
1078 sim_exited, -1);
1079 return;
1080 }
1081
1082 if (opcode->repeat_reg)
1083 n_repeats = (MSP430_CPU (sd)->state.regs[opcode->repeats] & 0x000f) + 1;
1084 else
1085 n_repeats = opcode->repeats + 1;
1086
1087 op_bits = opcode->size;
1088 switch (op_bits)
1089 {
1090 case 8:
1091 op_bytes = 1;
1092 break;
1093 case 16:
1094 op_bytes = 2;
1095 break;
1096 case 20:
1097 case 32:
1098 op_bytes = 4;
1099 break;
1100 }
1101
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, " ");
1105
1106 TRACE_DISASM (MSP430_CPU (sd), opcode_pc);
1107
1108 carry_to_use = 0;
1109 switch (opcode->id)
1110 {
1111 case MSO_unknown:
1112 break;
1113
1114 /* Double-operand instructions. */
1115 case MSO_mov:
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)
1123 {
1124 /* This is the designated software breakpoint instruction. */
1125 PC -= opsize;
1126 sim_engine_halt (sd, MSP430_CPU (sd), NULL,
1127 MSP430_CPU (sd)->state.regs[0],
1128 sim_stopped, SIM_SIGTRAP);
1129
1130 }
1131 else
1132 {
1133 /* Otherwise, do the move. */
1134 for (rept = 0; rept < n_repeats; rept ++)
1135 {
1136 DEST (SRC);
1137 }
1138 }
1139 break;
1140
1141 case MSO_addc:
1142 for (rept = 0; rept < n_repeats; rept ++)
1143 {
1144 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
1145 u1 = DSRC;
1146 u2 = SRC;
1147 s1 = SX (u1);
1148 s2 = SX (u2);
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);
1153 DEST (result);
1154 FLAGS (result, uresult != ZX (uresult));
1155 }
1156 break;
1157
1158 case MSO_add:
1159 for (rept = 0; rept < n_repeats; rept ++)
1160 {
1161 u1 = DSRC;
1162 u2 = SRC;
1163 s1 = SX (u1);
1164 s2 = SX (u2);
1165 uresult = u1 + u2;
1166 result = s1 + s2;
1167 TRACE_ALU (MSP430_CPU (sd), "ADD: %#x + %#x = %#x",
1168 u1, u2, uresult);
1169 DEST (result);
1170 FLAGS (result, uresult != ZX (uresult));
1171 }
1172 break;
1173
1174 case MSO_subc:
1175 for (rept = 0; rept < n_repeats; rept ++)
1176 {
1177 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
1178 u1 = DSRC;
1179 u2 = SRC;
1180 s1 = SX (u1);
1181 s2 = SX (u2);
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);
1186 DEST (result);
1187 FLAGS (result, uresult != ZX (uresult));
1188 }
1189 break;
1190
1191 case MSO_sub:
1192 for (rept = 0; rept < n_repeats; rept ++)
1193 {
1194 u1 = DSRC;
1195 u2 = SRC;
1196 s1 = SX (u1);
1197 s2 = SX (u2);
1198 uresult = ZX (~u2) + u1 + 1;
1199 result = SX (uresult);
1200 TRACE_ALU (MSP430_CPU (sd), "SUB: %#x - %#x = %#x",
1201 u1, u2, uresult);
1202 DEST (result);
1203 FLAGS (result, uresult != ZX (uresult));
1204 }
1205 break;
1206
1207 case MSO_cmp:
1208 for (rept = 0; rept < n_repeats; rept ++)
1209 {
1210 u1 = DSRC;
1211 u2 = SRC;
1212 s1 = SX (u1);
1213 s2 = SX (u2);
1214 uresult = ZX (~u2) + u1 + 1;
1215 result = s1 - s2;
1216 TRACE_ALU (MSP430_CPU (sd), "CMP: %#x - %#x = %x",
1217 u1, u2, uresult);
1218 FLAGS (result, uresult != ZX (uresult));
1219 }
1220 break;
1221
1222 case MSO_dadd:
1223 for (rept = 0; rept < n_repeats; rept ++)
1224 {
1225 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
1226 u1 = DSRC;
1227 u2 = SRC;
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);
1232 DEST (result);
1233 FLAGS (result, uresult > ((opcode->size == 8) ? 99 : 9999));
1234 }
1235 break;
1236
1237 case MSO_and:
1238 for (rept = 0; rept < n_repeats; rept ++)
1239 {
1240 u1 = DSRC;
1241 u2 = SRC;
1242 uresult = u1 & u2;
1243 TRACE_ALU (MSP430_CPU (sd), "AND: %#x & %#x = %#x",
1244 u1, u2, uresult);
1245 DEST (uresult);
1246 FLAGS (uresult, uresult != 0);
1247 }
1248 break;
1249
1250 case MSO_bit:
1251 for (rept = 0; rept < n_repeats; rept ++)
1252 {
1253 u1 = DSRC;
1254 u2 = SRC;
1255 uresult = u1 & u2;
1256 TRACE_ALU (MSP430_CPU (sd), "BIT: %#x & %#x -> %#x",
1257 u1, u2, uresult);
1258 FLAGS (uresult, uresult != 0);
1259 }
1260 break;
1261
1262 case MSO_bic:
1263 for (rept = 0; rept < n_repeats; rept ++)
1264 {
1265 u1 = DSRC;
1266 u2 = SRC;
1267 uresult = u1 & ~ u2;
1268 TRACE_ALU (MSP430_CPU (sd), "BIC: %#x & ~ %#x = %#x",
1269 u1, u2, uresult);
1270 DEST (uresult);
1271 }
1272 break;
1273
1274 case MSO_bis:
1275 for (rept = 0; rept < n_repeats; rept ++)
1276 {
1277 u1 = DSRC;
1278 u2 = SRC;
1279 uresult = u1 | u2;
1280 TRACE_ALU (MSP430_CPU (sd), "BIS: %#x | %#x = %#x",
1281 u1, u2, uresult);
1282 DEST (uresult);
1283 }
1284 break;
1285
1286 case MSO_xor:
1287 for (rept = 0; rept < n_repeats; rept ++)
1288 {
1289 s1 = 1 << (opcode->size - 1);
1290 u1 = DSRC;
1291 u2 = SRC;
1292 uresult = u1 ^ u2;
1293 TRACE_ALU (MSP430_CPU (sd), "XOR: %#x & %#x = %#x",
1294 u1, u2, uresult);
1295 DEST (uresult);
1296 FLAGSV (uresult, uresult != 0, (u1 & s1) && (u2 & s1));
1297 }
1298 break;
1299
1300 /* Single-operand instructions. Note: the decoder puts the same
1301 operand in SRC as in DEST, for our convenience. */
1302
1303 case MSO_rrc:
1304 for (rept = 0; rept < n_repeats; rept ++)
1305 {
1306 u1 = SRC;
1307 carry_to_use = u1 & 1;
1308 uresult = 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",
1314 u1, uresult);
1315 DEST (uresult);
1316 FLAGS (uresult, carry_to_use);
1317 }
1318 break;
1319
1320 case MSO_swpb:
1321 for (rept = 0; rept < n_repeats; rept ++)
1322 {
1323 u1 = SRC;
1324 uresult = ((u1 >> 8) & 0x00ff) | ((u1 << 8) & 0xff00);
1325 TRACE_ALU (MSP430_CPU (sd), "SWPB: %#x -> %#x",
1326 u1, uresult);
1327 DEST (uresult);
1328 }
1329 break;
1330
1331 case MSO_rra:
1332 for (rept = 0; rept < n_repeats; rept ++)
1333 {
1334 u1 = SRC;
1335 c = u1 & 1;
1336 s1 = 1 << (opcode->size - 1);
1337 uresult = (u1 >> 1) | (u1 & s1);
1338 TRACE_ALU (MSP430_CPU (sd), "RRA: %#x >>= %#x",
1339 u1, uresult);
1340 DEST (uresult);
1341 FLAGS (uresult, c);
1342 }
1343 break;
1344
1345 case MSO_rru:
1346 for (rept = 0; rept < n_repeats; rept ++)
1347 {
1348 u1 = SRC;
1349 c = u1 & 1;
1350 uresult = (u1 >> 1);
1351 TRACE_ALU (MSP430_CPU (sd), "RRU: %#x >>= %#x",
1352 u1, uresult);
1353 DEST (uresult);
1354 FLAGS (uresult, c);
1355 }
1356 break;
1357
1358 case MSO_sxt:
1359 for (rept = 0; rept < n_repeats; rept ++)
1360 {
1361 u1 = SRC;
1362 if (u1 & 0x80)
1363 uresult = u1 | 0xfff00;
1364 else
1365 uresult = u1 & 0x000ff;
1366 TRACE_ALU (MSP430_CPU (sd), "SXT: %#x -> %#x",
1367 u1, uresult);
1368 DEST (uresult);
1369 FLAGS (uresult, c);
1370 }
1371 break;
1372
1373 case MSO_push:
1374 for (rept = 0; rept < n_repeats; rept ++)
1375 {
1376 int new_sp;
1377
1378 new_sp = REG_GET (MSR_SP) - op_bytes;
1379 /* SP is always word-aligned. */
1380 if (new_sp & 1)
1381 new_sp --;
1382 REG_PUT (MSR_SP, new_sp);
1383 u1 = SRC;
1384 mem_put_val (sd, SP, u1, op_bits);
1385 if (opcode->op[1].type == MSP430_Operand_Register)
1386 opcode->op[1].reg --;
1387 }
1388 break;
1389
1390 case MSO_pop:
1391 for (rept = 0; rept < n_repeats; rept ++)
1392 {
1393 int new_sp;
1394
1395 u1 = mem_get_val (sd, SP, op_bits);
1396 DEST (u1);
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. */
1401 if (new_sp & 1)
1402 new_sp ++;
1403 REG_PUT (MSR_SP, new_sp);
1404 }
1405 break;
1406
1407 case MSO_call:
1408 u1 = SRC;
1409
1410 if (maybe_perform_syscall (sd, u1))
1411 break;
1412
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",
1416 u1, PC, SP);
1417 REG_PUT (MSR_PC, u1);
1418 break;
1419
1420 case MSO_reti:
1421 u1 = mem_get_val (sd, SP, 16);
1422 SR = u1 & 0xFF;
1423 SP += 2;
1424 PC = mem_get_val (sd, SP, 16);
1425 SP += 2;
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",
1432 PC, SR);
1433 break;
1434
1435 /* Jumps. */
1436
1437 case MSO_jmp:
1438 i = SRC;
1439 switch (opcode->cond)
1440 {
1441 case MSC_nz:
1442 u1 = (SR & MSP430_FLAG_Z) ? 0 : 1;
1443 break;
1444 case MSC_z:
1445 u1 = (SR & MSP430_FLAG_Z) ? 1 : 0;
1446 break;
1447 case MSC_nc:
1448 u1 = (SR & MSP430_FLAG_C) ? 0 : 1;
1449 break;
1450 case MSC_c:
1451 u1 = (SR & MSP430_FLAG_C) ? 1 : 0;
1452 break;
1453 case MSC_n:
1454 u1 = (SR & MSP430_FLAG_N) ? 1 : 0;
1455 break;
1456 case MSC_ge:
1457 u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 1 : 0;
1458 break;
1459 case MSC_l:
1460 u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 0 : 1;
1461 break;
1462 case MSC_true:
1463 u1 = 1;
1464 break;
1465 }
1466
1467 if (u1)
1468 {
1469 TRACE_BRANCH (MSP430_CPU (sd), "J%s: pc %#x -> %#x sr %#x, taken",
1470 cond_string (opcode->cond), PC, i, SR);
1471 PC = i;
1472 if (PC == opcode_pc)
1473 exit (0);
1474 }
1475 else
1476 TRACE_BRANCH (MSP430_CPU (sd), "J%s: pc %#x to %#x sr %#x, not taken",
1477 cond_string (opcode->cond), PC, i, SR);
1478 break;
1479
1480 default:
1481 fprintf (stderr, "error: unexpected opcode id %d\n", opcode->id);
1482 exit (1);
1483 }
1484 }
1485
1486 void
1487 sim_engine_run (SIM_DESC sd,
1488 int next_cpu_nr,
1489 int nr_cpus,
1490 int siggnal)
1491 {
1492 while (1)
1493 {
1494 msp430_step_once (sd);
1495 if (sim_events_tick (sd))
1496 sim_events_process (sd);
1497 }
1498 }