]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/msp430/msp430-sim.c
sim: overhaul & unify endian settings management
[thirdparty/binutils-gdb.git] / sim / msp430 / msp430-sim.c
1 /* Simulator for TI MSP430 and MSP430X
2
3 Copyright (C) 2013-2021 Free Software Foundation, Inc.
4 Contributed by Red Hat.
5 Based on sim/bfin/bfin-sim.c which was contributed by Analog Devices, Inc.
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-syscall.h"
34 #include "targ-vals.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,
156 (STATE_PROG_ARGV (sd) != NULL
157 ? *STATE_PROG_ARGV (sd)
158 : NULL), abfd) != SIM_RC_OK)
159 {
160 sim_state_free (sd);
161 return 0;
162 }
163
164 /* Establish any remaining configuration options. */
165 if (sim_config (sd) != SIM_RC_OK)
166 {
167 sim_state_free (sd);
168 return 0;
169 }
170
171 if (sim_post_argv_init (sd) != SIM_RC_OK)
172 {
173 sim_state_free (sd);
174 return 0;
175 }
176
177 /* CPU specific initialization. */
178 assert (MAX_NR_PROCESSORS == 1);
179 msp430_initialize_cpu (sd, MSP430_CPU (sd));
180
181 MSP430_CPU (sd)->state.cio_breakpoint = trace_sym_value (sd, "C$$IO$$");
182 MSP430_CPU (sd)->state.cio_buffer = trace_sym_value (sd, "__CIOBUF__");
183 if (MSP430_CPU (sd)->state.cio_buffer == -1)
184 MSP430_CPU (sd)->state.cio_buffer = trace_sym_value (sd, "_CIOBUF_");
185
186 return sd;
187 }
188
189 SIM_RC
190 sim_create_inferior (SIM_DESC sd,
191 struct bfd *abfd,
192 char * const *argv,
193 char * const *env)
194 {
195 unsigned char resetv[2];
196 int c;
197 int new_pc;
198
199 /* Set the PC to the default reset vector if available. */
200 c = sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, resetv, 0xfffe, 2);
201 new_pc = resetv[0] + 256 * resetv[1];
202
203 /* If the reset vector isn't initialized, then use the ELF entry. */
204 if (abfd != NULL && !new_pc)
205 new_pc = bfd_get_start_address (abfd);
206
207 sim_pc_set (MSP430_CPU (sd), new_pc);
208 msp430_pc_store (MSP430_CPU (sd), new_pc);
209
210 return SIM_RC_OK;
211 }
212
213 typedef struct
214 {
215 SIM_DESC sd;
216 int gb_addr;
217 } Get_Byte_Local_Data;
218
219 static int
220 msp430_getbyte (void *vld)
221 {
222 Get_Byte_Local_Data *ld = (Get_Byte_Local_Data *)vld;
223 char buf[1];
224 SIM_DESC sd = ld->sd;
225
226 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, ld->gb_addr, 1);
227 ld->gb_addr ++;
228 return buf[0];
229 }
230
231 #define REG(N) MSP430_CPU (sd)->state.regs[(N)]
232 #define PC REG(MSR_PC)
233 #define SP REG(MSR_SP)
234 #define SR REG(MSR_SR)
235
236 static const char *
237 register_names[] =
238 {
239 "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8",
240 "R9", "R10", "R11", "R12", "R13", "R14", "R15"
241 };
242
243 static void
244 trace_reg_put (SIM_DESC sd, int n, unsigned int v)
245 {
246 TRACE_REGISTER (MSP430_CPU (sd), "PUT: %#x -> %s", v, register_names[n]);
247 REG (n) = v;
248 }
249
250 static unsigned int
251 trace_reg_get (SIM_DESC sd, int n)
252 {
253 TRACE_REGISTER (MSP430_CPU (sd), "GET: %s -> %#x", register_names[n], REG (n));
254 return REG (n);
255 }
256
257 #define REG_PUT(N,V) trace_reg_put (sd, N, V)
258 #define REG_GET(N) trace_reg_get (sd, N)
259
260 /* Hardware multiply (and accumulate) support. */
261
262 static unsigned int
263 zero_ext (unsigned int v, unsigned int bits)
264 {
265 v &= ((1 << bits) - 1);
266 return v;
267 }
268
269 static signed long long
270 sign_ext (signed long long v, unsigned int bits)
271 {
272 signed long long sb = 1LL << (bits-1); /* Sign bit. */
273 signed long long mb = (1LL << (bits-1)) - 1LL; /* Mantissa bits. */
274
275 if (v & sb)
276 v = v | ~mb;
277 else
278 v = v & mb;
279 return v;
280 }
281
282 static int
283 get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n)
284 {
285 MSP430_Opcode_Operand *op = opc->op + n;
286 int rv = 0;
287 int addr;
288 unsigned char buf[4];
289 int incval = 0;
290
291 switch (op->type)
292 {
293 case MSP430_Operand_Immediate:
294 rv = op->addend;
295 break;
296 case MSP430_Operand_Register:
297 rv = REG_GET (op->reg);
298 break;
299 case MSP430_Operand_Indirect:
300 case MSP430_Operand_Indirect_Postinc:
301 addr = op->addend;
302 if (op->reg != MSR_None)
303 {
304 int reg = REG_GET (op->reg);
305 int sign = opc->ofs_430x ? 20 : 16;
306
307 /* Index values are signed. */
308 if (addr & (1 << (sign - 1)))
309 addr |= -(1 << sign);
310
311 addr += reg;
312
313 /* For MSP430 instructions the sum is limited to 16 bits if the
314 address in the index register is less than 64k even if we are
315 running on an MSP430X CPU. This is for MSP430 compatibility. */
316 if (reg < 0x10000 && ! opc->ofs_430x)
317 {
318 if (addr >= 0x10000)
319 fprintf (stderr, " XXX WRAPPING ADDRESS %x on read\n", addr);
320
321 addr &= 0xffff;
322 }
323 }
324 addr &= 0xfffff;
325 switch (opc->size)
326 {
327 case 8:
328 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 1);
329 rv = buf[0];
330 break;
331 case 16:
332 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 2);
333 rv = buf[0] | (buf[1] << 8);
334 break;
335 case 20:
336 case 32:
337 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 4);
338 rv = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
339 break;
340 default:
341 assert (! opc->size);
342 break;
343 }
344 #if 0
345 /* Hack - MSP430X5438 serial port status register. */
346 if (addr == 0x5dd)
347 rv = 2;
348 #endif
349 if ((addr >= 0x130 && addr <= 0x15B)
350 || (addr >= 0x4C0 && addr <= 0x4EB))
351 {
352 switch (addr)
353 {
354 case 0x4CA:
355 case 0x13A:
356 switch (HWMULT (sd, hwmult_type))
357 {
358 case UNSIGN_MAC_32:
359 case UNSIGN_32:
360 rv = zero_ext (HWMULT (sd, hwmult_result), 16);
361 break;
362 case SIGN_MAC_32:
363 case SIGN_32:
364 rv = sign_ext (HWMULT (sd, hwmult_signed_result), 16);
365 break;
366 }
367 break;
368
369 case 0x4CC:
370 case 0x13C:
371 switch (HWMULT (sd, hwmult_type))
372 {
373 case UNSIGN_MAC_32:
374 case UNSIGN_32:
375 rv = zero_ext (HWMULT (sd, hwmult_result) >> 16, 16);
376 break;
377
378 case SIGN_MAC_32:
379 case SIGN_32:
380 rv = sign_ext (HWMULT (sd, hwmult_signed_result) >> 16, 16);
381 break;
382 }
383 break;
384
385 case 0x4CE:
386 case 0x13E:
387 switch (HWMULT (sd, hwmult_type))
388 {
389 case UNSIGN_32:
390 rv = 0;
391 break;
392 case SIGN_32:
393 rv = HWMULT (sd, hwmult_signed_result) < 0 ? -1 : 0;
394 break;
395 case UNSIGN_MAC_32:
396 rv = 0; /* FIXME: Should be carry of last accumulate. */
397 break;
398 case SIGN_MAC_32:
399 rv = HWMULT (sd, hwmult_signed_accumulator) < 0 ? -1 : 0;
400 break;
401 }
402 break;
403
404 case 0x4E4:
405 case 0x154:
406 rv = zero_ext (HWMULT (sd, hw32mult_result), 16);
407 break;
408
409 case 0x4E6:
410 case 0x156:
411 rv = zero_ext (HWMULT (sd, hw32mult_result) >> 16, 16);
412 break;
413
414 case 0x4E8:
415 case 0x158:
416 rv = zero_ext (HWMULT (sd, hw32mult_result) >> 32, 16);
417 break;
418
419 case 0x4EA:
420 case 0x15A:
421 switch (HWMULT (sd, hw32mult_type))
422 {
423 case UNSIGN_64: rv = zero_ext (HWMULT (sd, hw32mult_result) >> 48, 16); break;
424 case SIGN_64: rv = sign_ext (HWMULT (sd, hw32mult_result) >> 48, 16); break;
425 }
426 break;
427
428 default:
429 fprintf (stderr, "unimplemented HW MULT read from %x!\n", addr);
430 break;
431 }
432 }
433
434 TRACE_MEMORY (MSP430_CPU (sd), "GET: [%#x].%d -> %#x", addr, opc->size,
435 rv);
436 break;
437
438 default:
439 fprintf (stderr, "invalid operand %d type %d\n", n, op->type);
440 abort ();
441 }
442
443 switch (opc->size)
444 {
445 case 8:
446 rv &= 0xff;
447 incval = 1;
448 break;
449 case 16:
450 rv &= 0xffff;
451 incval = 2;
452 break;
453 case 20:
454 rv &= 0xfffff;
455 incval = 4;
456 break;
457 case 32:
458 rv &= 0xffffffff;
459 incval = 4;
460 break;
461 }
462
463 if (op->type == MSP430_Operand_Indirect_Postinc)
464 REG_PUT (op->reg, REG_GET (op->reg) + incval);
465
466 return rv;
467 }
468
469 static int
470 put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val)
471 {
472 MSP430_Opcode_Operand *op = opc->op + n;
473 int rv = 0;
474 int addr;
475 unsigned char buf[4];
476 int incval = 0;
477
478 switch (opc->size)
479 {
480 case 8:
481 val &= 0xff;
482 break;
483 case 16:
484 val &= 0xffff;
485 break;
486 case 20:
487 val &= 0xfffff;
488 break;
489 case 32:
490 val &= 0xffffffff;
491 break;
492 }
493
494 switch (op->type)
495 {
496 case MSP430_Operand_Register:
497 REG (op->reg) = val;
498 REG_PUT (op->reg, val);
499 break;
500 case MSP430_Operand_Indirect:
501 case MSP430_Operand_Indirect_Postinc:
502 addr = op->addend;
503 if (op->reg != MSR_None)
504 {
505 int reg = REG_GET (op->reg);
506 int sign = opc->ofs_430x ? 20 : 16;
507
508 /* Index values are signed. */
509 if (addr & (1 << (sign - 1)))
510 addr |= -(1 << sign);
511
512 addr += reg;
513
514 /* For MSP430 instructions the sum is limited to 16 bits if the
515 address in the index register is less than 64k even if we are
516 running on an MSP430X CPU. This is for MSP430 compatibility. */
517 if (reg < 0x10000 && ! opc->ofs_430x)
518 {
519 if (addr >= 0x10000)
520 fprintf (stderr, " XXX WRAPPING ADDRESS %x on write\n", addr);
521
522 addr &= 0xffff;
523 }
524 }
525 addr &= 0xfffff;
526
527 TRACE_MEMORY (MSP430_CPU (sd), "PUT: [%#x].%d <- %#x", addr, opc->size,
528 val);
529 #if 0
530 /* Hack - MSP430X5438 serial port transmit register. */
531 if (addr == 0x5ce)
532 putchar (val);
533 #endif
534 if ((addr >= 0x130 && addr <= 0x15B)
535 || (addr >= 0x4C0 && addr <= 0x4EB))
536 {
537 signed int a,b;
538
539 /* Hardware Multiply emulation. */
540 assert (opc->size == 16);
541
542 switch (addr)
543 {
544 case 0x4C0:
545 case 0x130:
546 HWMULT (sd, hwmult_op1) = val;
547 HWMULT (sd, hwmult_type) = UNSIGN_32;
548 break;
549
550 case 0x4C2:
551 case 0x132:
552 HWMULT (sd, hwmult_op1) = val;
553 HWMULT (sd, hwmult_type) = SIGN_32;
554 break;
555
556 case 0x4C4:
557 case 0x134:
558 HWMULT (sd, hwmult_op1) = val;
559 HWMULT (sd, hwmult_type) = UNSIGN_MAC_32;
560 break;
561
562 case 0x4C6:
563 case 0x136:
564 HWMULT (sd, hwmult_op1) = val;
565 HWMULT (sd, hwmult_type) = SIGN_MAC_32;
566 break;
567
568 case 0x4C8:
569 case 0x138:
570 HWMULT (sd, hwmult_op2) = val;
571 switch (HWMULT (sd, hwmult_type))
572 {
573 case UNSIGN_32:
574 a = HWMULT (sd, hwmult_op1);
575 b = HWMULT (sd, hwmult_op2);
576 /* For unsigned 32-bit multiplication of 16-bit operands, an
577 explicit cast is required to prevent any implicit
578 sign-extension. */
579 HWMULT (sd, hwmult_result) = (unsigned32) a * (unsigned32) b;
580 HWMULT (sd, hwmult_signed_result) = a * b;
581 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_signed_accumulator) = 0;
582 break;
583
584 case SIGN_32:
585 a = sign_ext (HWMULT (sd, hwmult_op1), 16);
586 b = sign_ext (HWMULT (sd, hwmult_op2), 16);
587 HWMULT (sd, hwmult_signed_result) = a * b;
588 HWMULT (sd, hwmult_result) = (unsigned32) a * (unsigned32) b;
589 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_signed_accumulator) = 0;
590 break;
591
592 case UNSIGN_MAC_32:
593 a = HWMULT (sd, hwmult_op1);
594 b = HWMULT (sd, hwmult_op2);
595 HWMULT (sd, hwmult_accumulator)
596 += (unsigned32) a * (unsigned32) b;
597 HWMULT (sd, hwmult_signed_accumulator) += a * b;
598 HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_accumulator);
599 HWMULT (sd, hwmult_signed_result) = HWMULT (sd, hwmult_signed_accumulator);
600 break;
601
602 case SIGN_MAC_32:
603 a = sign_ext (HWMULT (sd, hwmult_op1), 16);
604 b = sign_ext (HWMULT (sd, hwmult_op2), 16);
605 HWMULT (sd, hwmult_accumulator)
606 += (unsigned32) a * (unsigned32) b;
607 HWMULT (sd, hwmult_signed_accumulator) += a * b;
608 HWMULT (sd, hwmult_result) = HWMULT (sd, hwmult_accumulator);
609 HWMULT (sd, hwmult_signed_result) = HWMULT (sd, hwmult_signed_accumulator);
610 break;
611 }
612 break;
613
614 case 0x4CA:
615 case 0x13A:
616 /* Copy into LOW result... */
617 switch (HWMULT (sd, hwmult_type))
618 {
619 case UNSIGN_MAC_32:
620 case UNSIGN_32:
621 HWMULT (sd, hwmult_accumulator) = HWMULT (sd, hwmult_result) = zero_ext (val, 16);
622 HWMULT (sd, hwmult_signed_accumulator) = sign_ext (val, 16);
623 break;
624 case SIGN_MAC_32:
625 case SIGN_32:
626 HWMULT (sd, hwmult_signed_accumulator) = HWMULT (sd, hwmult_result) = sign_ext (val, 16);
627 HWMULT (sd, hwmult_accumulator) = zero_ext (val, 16);
628 break;
629 }
630 break;
631
632 case 0x4D0:
633 case 0x140:
634 HWMULT (sd, hw32mult_op1) = val;
635 HWMULT (sd, hw32mult_type) = UNSIGN_64;
636 break;
637
638 case 0x4D2:
639 case 0x142:
640 HWMULT (sd, hw32mult_op1) = (HWMULT (sd, hw32mult_op1) & 0xFFFF) | (val << 16);
641 break;
642
643 case 0x4D4:
644 case 0x144:
645 HWMULT (sd, hw32mult_op1) = val;
646 HWMULT (sd, hw32mult_type) = SIGN_64;
647 break;
648
649 case 0x4D6:
650 case 0x146:
651 HWMULT (sd, hw32mult_op1) = (HWMULT (sd, hw32mult_op1) & 0xFFFF) | (val << 16);
652 break;
653
654 case 0x4E0:
655 case 0x150:
656 HWMULT (sd, hw32mult_op2) = val;
657 break;
658
659 case 0x4E2:
660 case 0x152:
661 HWMULT (sd, hw32mult_op2) = (HWMULT (sd, hw32mult_op2) & 0xFFFF) | (val << 16);
662 switch (HWMULT (sd, hw32mult_type))
663 {
664 case UNSIGN_64:
665 HWMULT (sd, hw32mult_result)
666 = (unsigned64) HWMULT (sd, hw32mult_op1)
667 * (unsigned64) HWMULT (sd, hw32mult_op2);
668 break;
669 case SIGN_64:
670 HWMULT (sd, hw32mult_result)
671 = sign_ext (HWMULT (sd, hw32mult_op1), 32)
672 * sign_ext (HWMULT (sd, hw32mult_op2), 32);
673 break;
674 }
675 break;
676
677 default:
678 fprintf (stderr, "unimplemented HW MULT write to %x!\n", addr);
679 break;
680 }
681 }
682
683 switch (opc->size)
684 {
685 case 8:
686 buf[0] = val;
687 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 1);
688 break;
689 case 16:
690 buf[0] = val;
691 buf[1] = val >> 8;
692 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 2);
693 break;
694 case 20:
695 case 32:
696 buf[0] = val;
697 buf[1] = val >> 8;
698 buf[2] = val >> 16;
699 buf[3] = val >> 24;
700 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 4);
701 break;
702 default:
703 assert (! opc->size);
704 break;
705 }
706 break;
707 default:
708 fprintf (stderr, "invalid operand %d type %d\n", n, op->type);
709 abort ();
710 }
711
712 switch (opc->size)
713 {
714 case 8:
715 rv &= 0xff;
716 incval = 1;
717 break;
718 case 16:
719 rv &= 0xffff;
720 incval = 2;
721 break;
722 case 20:
723 rv &= 0xfffff;
724 incval = 4;
725 break;
726 case 32:
727 rv &= 0xffffffff;
728 incval = 4;
729 break;
730 }
731
732 if (op->type == MSP430_Operand_Indirect_Postinc)
733 {
734 int new_val = REG_GET (op->reg) + incval;
735 /* SP is always word-aligned. */
736 if (op->reg == MSR_SP && (new_val & 1))
737 new_val ++;
738 REG_PUT (op->reg, new_val);
739 }
740
741 return rv;
742 }
743
744 static void
745 mem_put_val (SIM_DESC sd, int addr, int val, int bits)
746 {
747 MSP430_Opcode_Decoded opc;
748
749 opc.size = bits;
750 opc.op[0].type = MSP430_Operand_Indirect;
751 opc.op[0].addend = addr;
752 opc.op[0].reg = MSR_None;
753 put_op (sd, &opc, 0, val);
754 }
755
756 static int
757 mem_get_val (SIM_DESC sd, int addr, int bits)
758 {
759 MSP430_Opcode_Decoded opc;
760
761 opc.size = bits;
762 opc.op[0].type = MSP430_Operand_Indirect;
763 opc.op[0].addend = addr;
764 opc.op[0].reg = MSR_None;
765 return get_op (sd, &opc, 0);
766 }
767
768 #define CIO_OPEN (0xF0)
769 #define CIO_CLOSE (0xF1)
770 #define CIO_READ (0xF2)
771 #define CIO_WRITE (0xF3)
772 #define CIO_LSEEK (0xF4)
773 #define CIO_UNLINK (0xF5)
774 #define CIO_GETENV (0xF6)
775 #define CIO_RENAME (0xF7)
776 #define CIO_GETTIME (0xF8)
777 #define CIO_GETCLK (0xF9)
778 #define CIO_SYNC (0xFF)
779
780 #define CIO_I(n) (parms[(n)] + parms[(n)+1] * 256)
781 #define CIO_L(n) (parms[(n)] + parms[(n)+1] * 256 \
782 + parms[(n)+2] * 65536 + parms[(n)+3] * 16777216)
783
784 static void
785 msp430_cio (SIM_DESC sd)
786 {
787 /* A block of data at __CIOBUF__ describes the I/O operation to
788 perform. */
789
790 unsigned char raw_parms[13];
791 unsigned char parms[8];
792 long length;
793 int command;
794 unsigned char buffer[512];
795 long ret_buflen = 0;
796 long fd, addr, len, rv;
797
798 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, parms,
799 MSP430_CPU (sd)->state.cio_buffer, 5);
800 length = CIO_I (0);
801 command = parms[2];
802
803 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, parms,
804 MSP430_CPU (sd)->state.cio_buffer + 3, 8);
805
806 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, buffer,
807 MSP430_CPU (sd)->state.cio_buffer + 11, length);
808
809 switch (command)
810 {
811 case CIO_WRITE:
812 fd = CIO_I (0);
813 len = CIO_I (2);
814
815 rv = write (fd, buffer, len);
816 parms[0] = rv & 0xff;
817 parms[1] = rv >> 8;
818
819 break;
820 }
821
822 sim_core_write_buffer (sd, MSP430_CPU (sd), 0, parms,
823 MSP430_CPU (sd)->state.cio_buffer + 4, 8);
824 if (ret_buflen)
825 sim_core_write_buffer (sd, MSP430_CPU (sd), 0, buffer,
826 MSP430_CPU (sd)->state.cio_buffer + 12, ret_buflen);
827 }
828
829 #define SRC get_op (sd, opcode, 1)
830 #define DSRC get_op (sd, opcode, 0)
831 #define DEST(V) put_op (sd, opcode, 0, (V))
832
833 #define DO_ALU(OP,SOP,MORE) \
834 { \
835 int s1 = DSRC; \
836 int s2 = SRC; \
837 int result = s1 OP s2 MORE; \
838 TRACE_ALU (MSP430_CPU (sd), "ALU: %#x %s %#x %s = %#x", s1, SOP, \
839 s2, #MORE, result); \
840 DEST (result); \
841 }
842
843 #define SIGN (1 << (opcode->size - 1))
844 #define POS(x) (((x) & SIGN) ? 0 : 1)
845 #define NEG(x) (((x) & SIGN) ? 1 : 0)
846
847 #define SX(v) sign_ext (v, opcode->size)
848 #define ZX(v) zero_ext (v, opcode->size)
849
850 static char *
851 flags2string (int f)
852 {
853 static char buf[2][6];
854 static int bi = 0;
855 char *bp = buf[bi];
856
857 bi = (bi + 1) % 2;
858
859 bp[0] = f & MSP430_FLAG_V ? 'V' : '-';
860 bp[1] = f & MSP430_FLAG_N ? 'N' : '-';
861 bp[2] = f & MSP430_FLAG_Z ? 'Z' : '-';
862 bp[3] = f & MSP430_FLAG_C ? 'C' : '-';
863 bp[4] = 0;
864 return bp;
865 }
866
867 /* Random number that won't show up in our usual logic. */
868 #define MAGIC_OVERFLOW 0x55000F
869
870 static void
871 do_flags (SIM_DESC sd,
872 MSP430_Opcode_Decoded *opcode,
873 int vnz_val, /* Signed result. */
874 int carry,
875 int overflow)
876 {
877 int f = SR;
878 int new_f = 0;
879 int signbit = 1 << (opcode->size - 1);
880
881 f &= ~opcode->flags_0;
882 f &= ~opcode->flags_set;
883 f |= opcode->flags_1;
884
885 if (vnz_val & signbit)
886 new_f |= MSP430_FLAG_N;
887 if (! (vnz_val & ((signbit << 1) - 1)))
888 new_f |= MSP430_FLAG_Z;
889 if (overflow == MAGIC_OVERFLOW)
890 {
891 if (vnz_val != SX (vnz_val))
892 new_f |= MSP430_FLAG_V;
893 }
894 else
895 if (overflow)
896 new_f |= MSP430_FLAG_V;
897 if (carry)
898 new_f |= MSP430_FLAG_C;
899
900 new_f = f | (new_f & opcode->flags_set);
901 if (SR != new_f)
902 TRACE_ALU (MSP430_CPU (sd), "FLAGS: %s -> %s", flags2string (SR),
903 flags2string (new_f));
904 else
905 TRACE_ALU (MSP430_CPU (sd), "FLAGS: %s", flags2string (new_f));
906 SR = new_f;
907 }
908
909 #define FLAGS(vnz,c) do_flags (sd, opcode, vnz, c, MAGIC_OVERFLOW)
910 #define FLAGSV(vnz,c,v) do_flags (sd, opcode, vnz, c, v)
911
912 /* These two assume unsigned 16-bit (four digit) words.
913 Mask off unwanted bits for byte operations. */
914
915 static int
916 bcd_to_binary (int v)
917 {
918 int r = ( ((v >> 0) & 0xf) * 1
919 + ((v >> 4) & 0xf) * 10
920 + ((v >> 8) & 0xf) * 100
921 + ((v >> 12) & 0xf) * 1000);
922 return r;
923 }
924
925 static int
926 binary_to_bcd (int v)
927 {
928 int r = ( ((v / 1) % 10) << 0
929 | ((v / 10) % 10) << 4
930 | ((v / 100) % 10) << 8
931 | ((v / 1000) % 10) << 12);
932 return r;
933 }
934
935 static const char *
936 cond_string (int cond)
937 {
938 switch (cond)
939 {
940 case MSC_nz:
941 return "NZ";
942 case MSC_z:
943 return "Z";
944 case MSC_nc:
945 return "NC";
946 case MSC_c:
947 return "C";
948 case MSC_n:
949 return "N";
950 case MSC_ge:
951 return "GE";
952 case MSC_l:
953 return "L";
954 case MSC_true:
955 return "MP";
956 default:
957 return "??";
958 }
959 }
960
961 /* Checks a CALL to address CALL_ADDR. If this is a special
962 syscall address then the call is simulated and non-zero is
963 returned. Otherwise 0 is returned. */
964
965 static int
966 maybe_perform_syscall (SIM_DESC sd, int call_addr)
967 {
968 if (call_addr == 0x00160)
969 {
970 int i;
971
972 for (i = 0; i < 16; i++)
973 {
974 if (i % 4 == 0)
975 fprintf (stderr, "\t");
976 fprintf (stderr, "R%-2d %05x ", i, MSP430_CPU (sd)->state.regs[i]);
977 if (i % 4 == 3)
978 {
979 int sp = SP + (3 - (i / 4)) * 2;
980 unsigned char buf[2];
981
982 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, sp, 2);
983
984 fprintf (stderr, "\tSP%+d: %04x", sp - SP,
985 buf[0] + buf[1] * 256);
986
987 if (i / 4 == 0)
988 {
989 int flags = SR;
990
991 fprintf (stderr, flags & 0x100 ? " V" : " -");
992 fprintf (stderr, flags & 0x004 ? "N" : "-");
993 fprintf (stderr, flags & 0x002 ? "Z" : "-");
994 fprintf (stderr, flags & 0x001 ? "C" : "-");
995 }
996
997 fprintf (stderr, "\n");
998 }
999 }
1000 return 1;
1001 }
1002
1003 if ((call_addr & ~0x3f) == 0x00180)
1004 {
1005 /* Syscall! */
1006 int arg1, arg2, arg3, arg4;
1007 int syscall_num = call_addr & 0x3f;
1008
1009 /* syscall_num == 2 is used for the variadic function "open".
1010 The arguments are set up differently for variadic functions.
1011 See slaa534.pdf distributed by TI. */
1012 if (syscall_num == 2)
1013 {
1014 arg1 = MSP430_CPU (sd)->state.regs[12];
1015 arg2 = mem_get_val (sd, SP, 16);
1016 arg3 = mem_get_val (sd, SP + 2, 16);
1017 arg4 = mem_get_val (sd, SP + 4, 16);
1018 }
1019 else
1020 {
1021 arg1 = MSP430_CPU (sd)->state.regs[12];
1022 arg2 = MSP430_CPU (sd)->state.regs[13];
1023 arg3 = MSP430_CPU (sd)->state.regs[14];
1024 arg4 = MSP430_CPU (sd)->state.regs[15];
1025 }
1026
1027 MSP430_CPU (sd)->state.regs[12] = sim_syscall (MSP430_CPU (sd),
1028 syscall_num, arg1, arg2,
1029 arg3, arg4);
1030 return 1;
1031 }
1032
1033 return 0;
1034 }
1035
1036 static void
1037 msp430_step_once (SIM_DESC sd)
1038 {
1039 Get_Byte_Local_Data ld;
1040 unsigned char buf[100];
1041 int i;
1042 int opsize;
1043 unsigned int opcode_pc;
1044 MSP430_Opcode_Decoded opcode_buf;
1045 MSP430_Opcode_Decoded *opcode = &opcode_buf;
1046 int s1, s2, result;
1047 int u1 = 0, u2, uresult;
1048 int c = 0, reg;
1049 int sp;
1050 int carry_to_use;
1051 int n_repeats;
1052 int rept;
1053 int op_bytes = 0, op_bits;
1054
1055 PC &= 0xfffff;
1056 opcode_pc = PC;
1057
1058 if (opcode_pc < 0x10)
1059 {
1060 fprintf (stderr, "Fault: PC(%#x) is less than 0x10\n", opcode_pc);
1061 sim_engine_halt (sd, MSP430_CPU (sd), NULL,
1062 MSP430_CPU (sd)->state.regs[0],
1063 sim_exited, -1);
1064 return;
1065 }
1066
1067 if (PC == MSP430_CPU (sd)->state.cio_breakpoint
1068 && STATE_OPEN_KIND (sd) != SIM_OPEN_DEBUG)
1069 msp430_cio (sd);
1070
1071 ld.sd = sd;
1072 ld.gb_addr = PC;
1073 opsize = msp430_decode_opcode (MSP430_CPU (sd)->state.regs[0],
1074 opcode, msp430_getbyte, &ld);
1075 PC += opsize;
1076 if (opsize <= 0)
1077 {
1078 fprintf (stderr, "Fault: undecodable opcode at %#x\n", opcode_pc);
1079 sim_engine_halt (sd, MSP430_CPU (sd), NULL,
1080 MSP430_CPU (sd)->state.regs[0],
1081 sim_exited, -1);
1082 return;
1083 }
1084
1085 if (opcode->repeat_reg)
1086 n_repeats = (MSP430_CPU (sd)->state.regs[opcode->repeats] & 0x000f) + 1;
1087 else
1088 n_repeats = opcode->repeats + 1;
1089
1090 op_bits = opcode->size;
1091 switch (op_bits)
1092 {
1093 case 8:
1094 op_bytes = 1;
1095 break;
1096 case 16:
1097 op_bytes = 2;
1098 break;
1099 case 20:
1100 case 32:
1101 op_bytes = 4;
1102 break;
1103 }
1104
1105 if (TRACE_ANY_P (MSP430_CPU (sd)))
1106 trace_prefix (sd, MSP430_CPU (sd), NULL_CIA, opcode_pc,
1107 TRACE_LINENUM_P (MSP430_CPU (sd)), NULL, 0, " ");
1108
1109 TRACE_DISASM (MSP430_CPU (sd), opcode_pc);
1110
1111 carry_to_use = 0;
1112 switch (opcode->id)
1113 {
1114 case MSO_unknown:
1115 break;
1116
1117 /* Double-operand instructions. */
1118 case MSO_mov:
1119 if (opcode->n_bytes == 2
1120 && opcode->op[0].type == MSP430_Operand_Register
1121 && opcode->op[0].reg == MSR_CG
1122 && opcode->op[1].type == MSP430_Operand_Immediate
1123 && opcode->op[1].addend == 0
1124 /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK. */
1125 && opcode->size == 8)
1126 {
1127 /* This is the designated software breakpoint instruction. */
1128 PC -= opsize;
1129 sim_engine_halt (sd, MSP430_CPU (sd), NULL,
1130 MSP430_CPU (sd)->state.regs[0],
1131 sim_stopped, SIM_SIGTRAP);
1132
1133 }
1134 else
1135 {
1136 /* Otherwise, do the move. */
1137 for (rept = 0; rept < n_repeats; rept ++)
1138 {
1139 DEST (SRC);
1140 }
1141 }
1142 break;
1143
1144 case MSO_addc:
1145 for (rept = 0; rept < n_repeats; rept ++)
1146 {
1147 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
1148 u1 = DSRC;
1149 u2 = SRC;
1150 s1 = SX (u1);
1151 s2 = SX (u2);
1152 uresult = u1 + u2 + carry_to_use;
1153 result = s1 + s2 + carry_to_use;
1154 TRACE_ALU (MSP430_CPU (sd), "ADDC: %#x + %#x + %d = %#x",
1155 u1, u2, carry_to_use, uresult);
1156 DEST (result);
1157 FLAGS (result, uresult != ZX (uresult));
1158 }
1159 break;
1160
1161 case MSO_add:
1162 for (rept = 0; rept < n_repeats; rept ++)
1163 {
1164 u1 = DSRC;
1165 u2 = SRC;
1166 s1 = SX (u1);
1167 s2 = SX (u2);
1168 uresult = u1 + u2;
1169 result = s1 + s2;
1170 TRACE_ALU (MSP430_CPU (sd), "ADD: %#x + %#x = %#x",
1171 u1, u2, uresult);
1172 DEST (result);
1173 FLAGS (result, uresult != ZX (uresult));
1174 }
1175 break;
1176
1177 case MSO_subc:
1178 for (rept = 0; rept < n_repeats; rept ++)
1179 {
1180 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
1181 u1 = DSRC;
1182 u2 = SRC;
1183 s1 = SX (u1);
1184 s2 = SX (u2);
1185 uresult = ZX (~u2) + u1 + carry_to_use;
1186 result = s1 - s2 + (carry_to_use - 1);
1187 TRACE_ALU (MSP430_CPU (sd), "SUBC: %#x - %#x + %d = %#x",
1188 u1, u2, carry_to_use, uresult);
1189 DEST (result);
1190 FLAGS (result, uresult != ZX (uresult));
1191 }
1192 break;
1193
1194 case MSO_sub:
1195 for (rept = 0; rept < n_repeats; rept ++)
1196 {
1197 u1 = DSRC;
1198 u2 = SRC;
1199 s1 = SX (u1);
1200 s2 = SX (u2);
1201 uresult = ZX (~u2) + u1 + 1;
1202 result = SX (uresult);
1203 TRACE_ALU (MSP430_CPU (sd), "SUB: %#x - %#x = %#x",
1204 u1, u2, uresult);
1205 DEST (result);
1206 FLAGS (result, uresult != ZX (uresult));
1207 }
1208 break;
1209
1210 case MSO_cmp:
1211 for (rept = 0; rept < n_repeats; rept ++)
1212 {
1213 u1 = DSRC;
1214 u2 = SRC;
1215 s1 = SX (u1);
1216 s2 = SX (u2);
1217 uresult = ZX (~u2) + u1 + 1;
1218 result = s1 - s2;
1219 TRACE_ALU (MSP430_CPU (sd), "CMP: %#x - %#x = %x",
1220 u1, u2, uresult);
1221 FLAGS (result, uresult != ZX (uresult));
1222 }
1223 break;
1224
1225 case MSO_dadd:
1226 for (rept = 0; rept < n_repeats; rept ++)
1227 {
1228 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
1229 u1 = DSRC;
1230 u2 = SRC;
1231 uresult = bcd_to_binary (u1) + bcd_to_binary (u2) + carry_to_use;
1232 result = binary_to_bcd (uresult);
1233 TRACE_ALU (MSP430_CPU (sd), "DADD: %#x + %#x + %d = %#x",
1234 u1, u2, carry_to_use, result);
1235 DEST (result);
1236 FLAGS (result, uresult > ((opcode->size == 8) ? 99 : 9999));
1237 }
1238 break;
1239
1240 case MSO_and:
1241 for (rept = 0; rept < n_repeats; rept ++)
1242 {
1243 u1 = DSRC;
1244 u2 = SRC;
1245 uresult = u1 & u2;
1246 TRACE_ALU (MSP430_CPU (sd), "AND: %#x & %#x = %#x",
1247 u1, u2, uresult);
1248 DEST (uresult);
1249 FLAGS (uresult, uresult != 0);
1250 }
1251 break;
1252
1253 case MSO_bit:
1254 for (rept = 0; rept < n_repeats; rept ++)
1255 {
1256 u1 = DSRC;
1257 u2 = SRC;
1258 uresult = u1 & u2;
1259 TRACE_ALU (MSP430_CPU (sd), "BIT: %#x & %#x -> %#x",
1260 u1, u2, uresult);
1261 FLAGS (uresult, uresult != 0);
1262 }
1263 break;
1264
1265 case MSO_bic:
1266 for (rept = 0; rept < n_repeats; rept ++)
1267 {
1268 u1 = DSRC;
1269 u2 = SRC;
1270 uresult = u1 & ~ u2;
1271 TRACE_ALU (MSP430_CPU (sd), "BIC: %#x & ~ %#x = %#x",
1272 u1, u2, uresult);
1273 DEST (uresult);
1274 }
1275 break;
1276
1277 case MSO_bis:
1278 for (rept = 0; rept < n_repeats; rept ++)
1279 {
1280 u1 = DSRC;
1281 u2 = SRC;
1282 uresult = u1 | u2;
1283 TRACE_ALU (MSP430_CPU (sd), "BIS: %#x | %#x = %#x",
1284 u1, u2, uresult);
1285 DEST (uresult);
1286 }
1287 break;
1288
1289 case MSO_xor:
1290 for (rept = 0; rept < n_repeats; rept ++)
1291 {
1292 s1 = 1 << (opcode->size - 1);
1293 u1 = DSRC;
1294 u2 = SRC;
1295 uresult = u1 ^ u2;
1296 TRACE_ALU (MSP430_CPU (sd), "XOR: %#x & %#x = %#x",
1297 u1, u2, uresult);
1298 DEST (uresult);
1299 FLAGSV (uresult, uresult != 0, (u1 & s1) && (u2 & s1));
1300 }
1301 break;
1302
1303 /* Single-operand instructions. Note: the decoder puts the same
1304 operand in SRC as in DEST, for our convenience. */
1305
1306 case MSO_rrc:
1307 for (rept = 0; rept < n_repeats; rept ++)
1308 {
1309 u1 = SRC;
1310 carry_to_use = u1 & 1;
1311 uresult = u1 >> 1;
1312 /* If the ZC bit of the opcode is set, it means we are synthesizing
1313 RRUX, so the carry bit must be ignored. */
1314 if (opcode->zc == 0 && (SR & MSP430_FLAG_C))
1315 uresult |= (1 << (opcode->size - 1));
1316 TRACE_ALU (MSP430_CPU (sd), "RRC: %#x >>= %#x",
1317 u1, uresult);
1318 DEST (uresult);
1319 FLAGS (uresult, carry_to_use);
1320 }
1321 break;
1322
1323 case MSO_swpb:
1324 for (rept = 0; rept < n_repeats; rept ++)
1325 {
1326 u1 = SRC;
1327 uresult = ((u1 >> 8) & 0x00ff) | ((u1 << 8) & 0xff00);
1328 TRACE_ALU (MSP430_CPU (sd), "SWPB: %#x -> %#x",
1329 u1, uresult);
1330 DEST (uresult);
1331 }
1332 break;
1333
1334 case MSO_rra:
1335 for (rept = 0; rept < n_repeats; rept ++)
1336 {
1337 u1 = SRC;
1338 c = u1 & 1;
1339 s1 = 1 << (opcode->size - 1);
1340 uresult = (u1 >> 1) | (u1 & s1);
1341 TRACE_ALU (MSP430_CPU (sd), "RRA: %#x >>= %#x",
1342 u1, uresult);
1343 DEST (uresult);
1344 FLAGS (uresult, c);
1345 }
1346 break;
1347
1348 case MSO_rru:
1349 for (rept = 0; rept < n_repeats; rept ++)
1350 {
1351 u1 = SRC;
1352 c = u1 & 1;
1353 uresult = (u1 >> 1);
1354 TRACE_ALU (MSP430_CPU (sd), "RRU: %#x >>= %#x",
1355 u1, uresult);
1356 DEST (uresult);
1357 FLAGS (uresult, c);
1358 }
1359 break;
1360
1361 case MSO_sxt:
1362 for (rept = 0; rept < n_repeats; rept ++)
1363 {
1364 u1 = SRC;
1365 if (u1 & 0x80)
1366 uresult = u1 | 0xfff00;
1367 else
1368 uresult = u1 & 0x000ff;
1369 TRACE_ALU (MSP430_CPU (sd), "SXT: %#x -> %#x",
1370 u1, uresult);
1371 DEST (uresult);
1372 FLAGS (uresult, c);
1373 }
1374 break;
1375
1376 case MSO_push:
1377 for (rept = 0; rept < n_repeats; rept ++)
1378 {
1379 int new_sp;
1380
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 --;
1390 }
1391 break;
1392
1393 case MSO_pop:
1394 for (rept = 0; rept < n_repeats; rept ++)
1395 {
1396 int new_sp;
1397
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);
1407 }
1408 break;
1409
1410 case MSO_call:
1411 u1 = SRC;
1412
1413 if (maybe_perform_syscall (sd, u1))
1414 break;
1415
1416 REG_PUT (MSR_SP, REG_GET (MSR_SP) - op_bytes);
1417 mem_put_val (sd, SP, PC, op_bits);
1418 TRACE_ALU (MSP430_CPU (sd), "CALL: func %#x ret %#x, sp %#x",
1419 u1, PC, SP);
1420 REG_PUT (MSR_PC, u1);
1421 break;
1422
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 (MSP430_CPU (sd), "RETI: pc %#x sr %#x",
1435 PC, SR);
1436 break;
1437
1438 /* Jumps. */
1439
1440 case MSO_jmp:
1441 i = SRC;
1442 switch (opcode->cond)
1443 {
1444 case MSC_nz:
1445 u1 = (SR & MSP430_FLAG_Z) ? 0 : 1;
1446 break;
1447 case MSC_z:
1448 u1 = (SR & MSP430_FLAG_Z) ? 1 : 0;
1449 break;
1450 case MSC_nc:
1451 u1 = (SR & MSP430_FLAG_C) ? 0 : 1;
1452 break;
1453 case MSC_c:
1454 u1 = (SR & MSP430_FLAG_C) ? 1 : 0;
1455 break;
1456 case MSC_n:
1457 u1 = (SR & MSP430_FLAG_N) ? 1 : 0;
1458 break;
1459 case MSC_ge:
1460 u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 1 : 0;
1461 break;
1462 case MSC_l:
1463 u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 0 : 1;
1464 break;
1465 case MSC_true:
1466 u1 = 1;
1467 break;
1468 }
1469
1470 if (u1)
1471 {
1472 TRACE_BRANCH (MSP430_CPU (sd), "J%s: pc %#x -> %#x sr %#x, taken",
1473 cond_string (opcode->cond), PC, i, SR);
1474 PC = i;
1475 if (PC == opcode_pc)
1476 exit (0);
1477 }
1478 else
1479 TRACE_BRANCH (MSP430_CPU (sd), "J%s: pc %#x to %#x sr %#x, not taken",
1480 cond_string (opcode->cond), PC, i, SR);
1481 break;
1482
1483 default:
1484 fprintf (stderr, "error: unexpected opcode id %d\n", opcode->id);
1485 exit (1);
1486 }
1487 }
1488
1489 void
1490 sim_engine_run (SIM_DESC sd,
1491 int next_cpu_nr,
1492 int nr_cpus,
1493 int siggnal)
1494 {
1495 while (1)
1496 {
1497 msp430_step_once (sd);
1498 if (sim_events_tick (sd))
1499 sim_events_process (sd);
1500 }
1501 }