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