sim: syscall: unify memory helpers
[deliverable/binutils-gdb.git] / sim / msp430 / msp430-sim.c
... / ...
CommitLineData
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
37static int
38loader_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
47static sim_cia
48msp430_pc_fetch (SIM_CPU *cpu)
49{
50 return cpu->state.regs[0];
51}
52
53static void
54msp430_pc_store (SIM_CPU *cpu, sim_cia newpc)
55{
56 cpu->state.regs[0] = newpc;
57}
58
59static long
60lookup_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
89static int
90msp430_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
117static int
118msp430_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
139static inline void
140msp430_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu)
141{
142 memset (&cpu->state, 0, sizeof (cpu->state));
143}
144
145SIM_DESC
146sim_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
241void
242sim_close (SIM_DESC sd,
243 int quitting)
244{
245 free (STATE_SYMBOL_TABLE (sd));
246 sim_state_free (sd);
247}
248
249SIM_RC
250sim_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
273typedef struct
274{
275 SIM_DESC sd;
276 int gb_addr;
277} Get_Byte_Local_Data;
278
279static int
280msp430_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
296static const char *
297register_names[] =
298{
299 "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8",
300 "R9", "R10", "R11", "R12", "R13", "R14", "R15"
301};
302
303static void
304trace_reg_put (SIM_DESC sd, int n, unsigned int v)
305{
306 TRACE_VPU (MSP430_CPU (sd), "PUT: %#x -> %s", v, register_names[n]);
307 REG (n) = v;
308}
309
310static unsigned int
311trace_reg_get (SIM_DESC sd, int n)
312{
313 TRACE_VPU (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
322static unsigned int
323zero_ext (unsigned int v, unsigned int bits)
324{
325 v &= ((1 << bits) - 1);
326 return v;
327}
328
329static signed long long
330sign_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
342static int
343get_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
521static int
522put_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
751static void
752mem_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
763static int
764mem_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
791static void
792msp430_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
840static int
841msp430_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
868static char *
869flags2string (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
888static void
889do_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
933static int
934bcd_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
943static int
944binary_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
953static const char *
954cond_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
983static int
984maybe_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 host_callback *cb = STATE_CALLBACK (sd);
1026 CB_SYSCALL sc;
1027
1028 CB_SYSCALL_INIT (&sc);
1029
1030 sc.func = syscall_num;
1031 sc.arg1 = MSP430_CPU (sd)->state.regs[12];
1032 sc.arg2 = MSP430_CPU (sd)->state.regs[13];
1033 sc.arg3 = MSP430_CPU (sd)->state.regs[14];
1034 sc.arg4 = MSP430_CPU (sd)->state.regs[15];
1035
1036 if (TRACE_SYSCALL_P (MSP430_CPU (sd)))
1037 {
1038 const char *syscall_name = "*unknown*";
1039
1040 switch (syscall_num)
1041 {
1042 case TARGET_SYS_exit:
1043 syscall_name = "exit(%d)";
1044 break;
1045 case TARGET_SYS_open:
1046 syscall_name = "open(%#x,%#x)";
1047 break;
1048 case TARGET_SYS_close:
1049 syscall_name = "close(%d)";
1050 break;
1051 case TARGET_SYS_read:
1052 syscall_name = "read(%d,%#x,%d)";
1053 break;
1054 case TARGET_SYS_write:
1055 syscall_name = "write(%d,%#x,%d)";
1056 break;
1057 }
1058 trace_generic (sd, MSP430_CPU (sd), TRACE_SYSCALL_IDX,
1059 syscall_name, sc.arg1, sc.arg2, sc.arg3, sc.arg4);
1060 }
1061
1062 /* Handle SYS_exit here. */
1063 if (syscall_num == 1)
1064 {
1065 sim_engine_halt (sd, MSP430_CPU (sd), NULL,
1066 MSP430_CPU (sd)->state.regs[0],
1067 sim_exited, sc.arg1);
1068 return 1;
1069 }
1070
1071 sc.p1 = sd;
1072 sc.p2 = MSP430_CPU (sd);
1073 sc.read_mem = sim_syscall_read_mem;
1074 sc.write_mem = sim_syscall_write_mem;
1075
1076 cb_syscall (cb, &sc);
1077
1078 TRACE_SYSCALL (MSP430_CPU (sd), "returns %ld", sc.result);
1079
1080 MSP430_CPU (sd)->state.regs[12] = sc.result;
1081 return 1;
1082 }
1083
1084 return 0;
1085}
1086
1087static void
1088msp430_step_once (SIM_DESC sd)
1089{
1090 Get_Byte_Local_Data ld;
1091 unsigned char buf[100];
1092 int i;
1093 int opsize;
1094 unsigned int opcode_pc;
1095 MSP430_Opcode_Decoded opcode_buf;
1096 MSP430_Opcode_Decoded *opcode = &opcode_buf;
1097 int s1, s2, result;
1098 int u1, u2, uresult;
1099 int c, reg;
1100 int sp;
1101 int carry_to_use;
1102 int n_repeats;
1103 int rept;
1104 int op_bytes, op_bits;
1105
1106 PC &= 0xfffff;
1107 opcode_pc = PC;
1108
1109 if (opcode_pc < 0x10)
1110 {
1111 fprintf (stderr, "Fault: PC(%#x) is less than 0x10\n", opcode_pc);
1112 sim_engine_halt (sd, MSP430_CPU (sd), NULL,
1113 MSP430_CPU (sd)->state.regs[0],
1114 sim_exited, -1);
1115 return;
1116 }
1117
1118 if (PC == MSP430_CPU (sd)->state.cio_breakpoint
1119 && STATE_OPEN_KIND (sd) != SIM_OPEN_DEBUG)
1120 msp430_cio (sd);
1121
1122 ld.sd = sd;
1123 ld.gb_addr = PC;
1124 opsize = msp430_decode_opcode (MSP430_CPU (sd)->state.regs[0],
1125 opcode, msp430_getbyte, &ld);
1126 PC += opsize;
1127 if (opsize <= 0)
1128 {
1129 fprintf (stderr, "Fault: undecodable opcode at %#x\n", opcode_pc);
1130 sim_engine_halt (sd, MSP430_CPU (sd), NULL,
1131 MSP430_CPU (sd)->state.regs[0],
1132 sim_exited, -1);
1133 return;
1134 }
1135
1136 if (opcode->repeat_reg)
1137 n_repeats = (MSP430_CPU (sd)->state.regs[opcode->repeats] & 0x000f) + 1;
1138 else
1139 n_repeats = opcode->repeats + 1;
1140
1141 op_bits = opcode->size;
1142 switch (op_bits)
1143 {
1144 case 8:
1145 op_bytes = 1;
1146 break;
1147 case 16:
1148 op_bytes = 2;
1149 break;
1150 case 20:
1151 case 32:
1152 op_bytes = 4;
1153 break;
1154 }
1155
1156 if (TRACE_INSN_P (MSP430_CPU (sd)))
1157 {
1158 disassemble_info info;
1159 unsigned char b[10];
1160
1161 msp430_trace_one (opcode_pc);
1162
1163 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, b, opcode_pc, opsize);
1164
1165 init_disassemble_info (&info, stderr, (fprintf_ftype) fprintf);
1166 info.private_data = sd;
1167 info.read_memory_func = msp430_dis_read;
1168 fprintf (stderr, "%#8x ", opcode_pc);
1169 for (i = 0; i < opsize; i += 2)
1170 fprintf (stderr, " %02x%02x", b[i+1], b[i]);
1171 for (; i < 6; i += 2)
1172 fprintf (stderr, " ");
1173 fprintf (stderr, " ");
1174 print_insn_msp430 (opcode_pc, &info);
1175 fprintf (stderr, "\n");
1176 fflush (stdout);
1177 }
1178
1179 if (TRACE_ANY_P (MSP430_CPU (sd)))
1180 trace_prefix (sd, MSP430_CPU (sd), NULL_CIA, opcode_pc,
1181 TRACE_LINENUM_P (MSP430_CPU (sd)), NULL, 0, "");
1182
1183 carry_to_use = 0;
1184 switch (opcode->id)
1185 {
1186 case MSO_unknown:
1187 break;
1188
1189 /* Double-operand instructions. */
1190 case MSO_mov:
1191 if (opcode->n_bytes == 2
1192 && opcode->op[0].type == MSP430_Operand_Register
1193 && opcode->op[0].reg == MSR_CG
1194 && opcode->op[1].type == MSP430_Operand_Immediate
1195 && opcode->op[1].addend == 0
1196 /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK. */
1197 && opcode->size == 8)
1198 {
1199 /* This is the designated software breakpoint instruction. */
1200 PC -= opsize;
1201 sim_engine_halt (sd, MSP430_CPU (sd), NULL,
1202 MSP430_CPU (sd)->state.regs[0],
1203 sim_stopped, SIM_SIGTRAP);
1204
1205 }
1206 else
1207 {
1208 /* Otherwise, do the move. */
1209 for (rept = 0; rept < n_repeats; rept ++)
1210 {
1211 DEST (SRC);
1212 }
1213 }
1214 break;
1215
1216 case MSO_addc:
1217 for (rept = 0; rept < n_repeats; rept ++)
1218 {
1219 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
1220 u1 = DSRC;
1221 u2 = SRC;
1222 s1 = SX (u1);
1223 s2 = SX (u2);
1224 uresult = u1 + u2 + carry_to_use;
1225 result = s1 + s2 + carry_to_use;
1226 TRACE_ALU (MSP430_CPU (sd), "ADDC: %#x + %#x + %d = %#x",
1227 u1, u2, carry_to_use, uresult);
1228 DEST (result);
1229 FLAGS (result, uresult != ZX (uresult));
1230 }
1231 break;
1232
1233 case MSO_add:
1234 for (rept = 0; rept < n_repeats; rept ++)
1235 {
1236 u1 = DSRC;
1237 u2 = SRC;
1238 s1 = SX (u1);
1239 s2 = SX (u2);
1240 uresult = u1 + u2;
1241 result = s1 + s2;
1242 TRACE_ALU (MSP430_CPU (sd), "ADD: %#x + %#x = %#x",
1243 u1, u2, uresult);
1244 DEST (result);
1245 FLAGS (result, uresult != ZX (uresult));
1246 }
1247 break;
1248
1249 case MSO_subc:
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 s1 = SX (u1);
1256 s2 = SX (u2);
1257 uresult = ZX (~u2) + u1 + carry_to_use;
1258 result = s1 - s2 + (carry_to_use - 1);
1259 TRACE_ALU (MSP430_CPU (sd), "SUBC: %#x - %#x + %d = %#x",
1260 u1, u2, carry_to_use, uresult);
1261 DEST (result);
1262 FLAGS (result, uresult != ZX (uresult));
1263 }
1264 break;
1265
1266 case MSO_sub:
1267 for (rept = 0; rept < n_repeats; rept ++)
1268 {
1269 u1 = DSRC;
1270 u2 = SRC;
1271 s1 = SX (u1);
1272 s2 = SX (u2);
1273 uresult = ZX (~u2) + u1 + 1;
1274 result = SX (uresult);
1275 TRACE_ALU (MSP430_CPU (sd), "SUB: %#x - %#x = %#x",
1276 u1, u2, uresult);
1277 DEST (result);
1278 FLAGS (result, uresult != ZX (uresult));
1279 }
1280 break;
1281
1282 case MSO_cmp:
1283 for (rept = 0; rept < n_repeats; rept ++)
1284 {
1285 u1 = DSRC;
1286 u2 = SRC;
1287 s1 = SX (u1);
1288 s2 = SX (u2);
1289 uresult = ZX (~u2) + u1 + 1;
1290 result = s1 - s2;
1291 TRACE_ALU (MSP430_CPU (sd), "CMP: %#x - %#x = %x",
1292 u1, u2, uresult);
1293 FLAGS (result, uresult != ZX (uresult));
1294 }
1295 break;
1296
1297 case MSO_dadd:
1298 for (rept = 0; rept < n_repeats; rept ++)
1299 {
1300 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0;
1301 u1 = DSRC;
1302 u2 = SRC;
1303 uresult = bcd_to_binary (u1) + bcd_to_binary (u2) + carry_to_use;
1304 result = binary_to_bcd (uresult);
1305 TRACE_ALU (MSP430_CPU (sd), "DADD: %#x + %#x + %d = %#x",
1306 u1, u2, carry_to_use, result);
1307 DEST (result);
1308 FLAGS (result, uresult > ((opcode->size == 8) ? 99 : 9999));
1309 }
1310 break;
1311
1312 case MSO_and:
1313 for (rept = 0; rept < n_repeats; rept ++)
1314 {
1315 u1 = DSRC;
1316 u2 = SRC;
1317 uresult = u1 & u2;
1318 TRACE_ALU (MSP430_CPU (sd), "AND: %#x & %#x = %#x",
1319 u1, u2, uresult);
1320 DEST (uresult);
1321 FLAGS (uresult, uresult != 0);
1322 }
1323 break;
1324
1325 case MSO_bit:
1326 for (rept = 0; rept < n_repeats; rept ++)
1327 {
1328 u1 = DSRC;
1329 u2 = SRC;
1330 uresult = u1 & u2;
1331 TRACE_ALU (MSP430_CPU (sd), "BIT: %#x & %#x -> %#x",
1332 u1, u2, uresult);
1333 FLAGS (uresult, uresult != 0);
1334 }
1335 break;
1336
1337 case MSO_bic:
1338 for (rept = 0; rept < n_repeats; rept ++)
1339 {
1340 u1 = DSRC;
1341 u2 = SRC;
1342 uresult = u1 & ~ u2;
1343 TRACE_ALU (MSP430_CPU (sd), "BIC: %#x & ~ %#x = %#x",
1344 u1, u2, uresult);
1345 DEST (uresult);
1346 }
1347 break;
1348
1349 case MSO_bis:
1350 for (rept = 0; rept < n_repeats; rept ++)
1351 {
1352 u1 = DSRC;
1353 u2 = SRC;
1354 uresult = u1 | u2;
1355 TRACE_ALU (MSP430_CPU (sd), "BIS: %#x | %#x = %#x",
1356 u1, u2, uresult);
1357 DEST (uresult);
1358 }
1359 break;
1360
1361 case MSO_xor:
1362 for (rept = 0; rept < n_repeats; rept ++)
1363 {
1364 s1 = 1 << (opcode->size - 1);
1365 u1 = DSRC;
1366 u2 = SRC;
1367 uresult = u1 ^ u2;
1368 TRACE_ALU (MSP430_CPU (sd), "XOR: %#x & %#x = %#x",
1369 u1, u2, uresult);
1370 DEST (uresult);
1371 FLAGSV (uresult, uresult != 0, (u1 & s1) && (u2 & s1));
1372 }
1373 break;
1374
1375 /* Single-operand instructions. Note: the decoder puts the same
1376 operand in SRC as in DEST, for our convenience. */
1377
1378 case MSO_rrc:
1379 for (rept = 0; rept < n_repeats; rept ++)
1380 {
1381 u1 = SRC;
1382 carry_to_use = u1 & 1;
1383 uresult = u1 >> 1;
1384 if (SR & MSP430_FLAG_C)
1385 uresult |= (1 << (opcode->size - 1));
1386 TRACE_ALU (MSP430_CPU (sd), "RRC: %#x >>= %#x",
1387 u1, uresult);
1388 DEST (uresult);
1389 FLAGS (uresult, carry_to_use);
1390 }
1391 break;
1392
1393 case MSO_swpb:
1394 for (rept = 0; rept < n_repeats; rept ++)
1395 {
1396 u1 = SRC;
1397 uresult = ((u1 >> 8) & 0x00ff) | ((u1 << 8) & 0xff00);
1398 TRACE_ALU (MSP430_CPU (sd), "SWPB: %#x -> %#x",
1399 u1, uresult);
1400 DEST (uresult);
1401 }
1402 break;
1403
1404 case MSO_rra:
1405 for (rept = 0; rept < n_repeats; rept ++)
1406 {
1407 u1 = SRC;
1408 c = u1 & 1;
1409 s1 = 1 << (opcode->size - 1);
1410 uresult = (u1 >> 1) | (u1 & s1);
1411 TRACE_ALU (MSP430_CPU (sd), "RRA: %#x >>= %#x",
1412 u1, uresult);
1413 DEST (uresult);
1414 FLAGS (uresult, c);
1415 }
1416 break;
1417
1418 case MSO_rru:
1419 for (rept = 0; rept < n_repeats; rept ++)
1420 {
1421 u1 = SRC;
1422 c = u1 & 1;
1423 uresult = (u1 >> 1);
1424 TRACE_ALU (MSP430_CPU (sd), "RRU: %#x >>= %#x",
1425 u1, uresult);
1426 DEST (uresult);
1427 FLAGS (uresult, c);
1428 }
1429 break;
1430
1431 case MSO_sxt:
1432 for (rept = 0; rept < n_repeats; rept ++)
1433 {
1434 u1 = SRC;
1435 if (u1 & 0x80)
1436 uresult = u1 | 0xfff00;
1437 else
1438 uresult = u1 & 0x000ff;
1439 TRACE_ALU (MSP430_CPU (sd), "SXT: %#x -> %#x",
1440 u1, uresult);
1441 DEST (uresult);
1442 FLAGS (uresult, c);
1443 }
1444 break;
1445
1446 case MSO_push:
1447 for (rept = 0; rept < n_repeats; rept ++)
1448 {
1449 int new_sp;
1450
1451 new_sp = REG_GET (MSR_SP) - op_bytes;
1452 /* SP is always word-aligned. */
1453 if (new_sp & 1)
1454 new_sp --;
1455 REG_PUT (MSR_SP, new_sp);
1456 u1 = SRC;
1457 mem_put_val (sd, SP, u1, op_bits);
1458 if (opcode->op[1].type == MSP430_Operand_Register)
1459 opcode->op[1].reg --;
1460 }
1461 break;
1462
1463 case MSO_pop:
1464 for (rept = 0; rept < n_repeats; rept ++)
1465 {
1466 int new_sp;
1467
1468 u1 = mem_get_val (sd, SP, op_bits);
1469 DEST (u1);
1470 if (opcode->op[0].type == MSP430_Operand_Register)
1471 opcode->op[0].reg ++;
1472 new_sp = REG_GET (MSR_SP) + op_bytes;
1473 /* SP is always word-aligned. */
1474 if (new_sp & 1)
1475 new_sp ++;
1476 REG_PUT (MSR_SP, new_sp);
1477 }
1478 break;
1479
1480 case MSO_call:
1481 u1 = SRC;
1482
1483 if (maybe_perform_syscall (sd, u1))
1484 break;
1485
1486 REG_PUT (MSR_SP, REG_GET (MSR_SP) - op_bytes);
1487 mem_put_val (sd, SP, PC, op_bits);
1488 TRACE_ALU (MSP430_CPU (sd), "CALL: func %#x ret %#x, sp %#x",
1489 u1, PC, SP);
1490 REG_PUT (MSR_PC, u1);
1491 break;
1492
1493 case MSO_reti:
1494 u1 = mem_get_val (sd, SP, 16);
1495 SR = u1 & 0xFF;
1496 SP += 2;
1497 PC = mem_get_val (sd, SP, 16);
1498 SP += 2;
1499 /* Emulate the RETI action of the 20-bit CPUX architecure.
1500 This is safe for 16-bit CPU architectures as well, since the top
1501 8-bits of SR will have been written to the stack here, and will
1502 have been read as 0. */
1503 PC |= (u1 & 0xF000) << 4;
1504 TRACE_ALU (MSP430_CPU (sd), "RETI: pc %#x sr %#x",
1505 PC, SR);
1506 break;
1507
1508 /* Jumps. */
1509
1510 case MSO_jmp:
1511 i = SRC;
1512 switch (opcode->cond)
1513 {
1514 case MSC_nz:
1515 u1 = (SR & MSP430_FLAG_Z) ? 0 : 1;
1516 break;
1517 case MSC_z:
1518 u1 = (SR & MSP430_FLAG_Z) ? 1 : 0;
1519 break;
1520 case MSC_nc:
1521 u1 = (SR & MSP430_FLAG_C) ? 0 : 1;
1522 break;
1523 case MSC_c:
1524 u1 = (SR & MSP430_FLAG_C) ? 1 : 0;
1525 break;
1526 case MSC_n:
1527 u1 = (SR & MSP430_FLAG_N) ? 1 : 0;
1528 break;
1529 case MSC_ge:
1530 u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 1 : 0;
1531 break;
1532 case MSC_l:
1533 u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 0 : 1;
1534 break;
1535 case MSC_true:
1536 u1 = 1;
1537 break;
1538 }
1539
1540 if (u1)
1541 {
1542 TRACE_BRANCH (MSP430_CPU (sd), "J%s: pc %#x -> %#x sr %#x, taken",
1543 cond_string (opcode->cond), PC, i, SR);
1544 PC = i;
1545 if (PC == opcode_pc)
1546 exit (0);
1547 }
1548 else
1549 TRACE_BRANCH (MSP430_CPU (sd), "J%s: pc %#x to %#x sr %#x, not taken",
1550 cond_string (opcode->cond), PC, i, SR);
1551 break;
1552
1553 default:
1554 fprintf (stderr, "error: unexpected opcode id %d\n", opcode->id);
1555 exit (1);
1556 }
1557}
1558
1559void
1560sim_engine_run (SIM_DESC sd,
1561 int next_cpu_nr,
1562 int nr_cpus,
1563 int siggnal)
1564{
1565 while (1)
1566 {
1567 msp430_step_once (sd);
1568 if (sim_events_tick (sd))
1569 sim_events_process (sd);
1570 }
1571}
This page took 0.027575 seconds and 4 git commands to generate.