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