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