OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [sim/] [scarts_16/] [scarts_16-iss.c] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 jlechner
/* SCARTS (16-bit) target-dependent code for the GNU simulator.
2
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3
   Free Software Foundation, Inc.
4
   Contributed by Martin Walter <mwalter@opencores.org>
5
 
6
   This file is part of the GNU simulators.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
 
22
#define GNU_SOURCE
23
#define _GNU_SOURCE
24
 
25
#ifndef PARAMS
26
#define PARAMS(ARGS) ARGS
27
#endif
28
 
29
#include <assert.h>
30
#include <signal.h>
31
#include <stdlib.h>
32
#include <string.h>
33
 
34
#include "modules.h"
35
#include "scarts_16-codemem.h"
36
#include "scarts_16-datamem.h"
37
#include "scarts_16-iss.h"
38
#include "scarts_16-mad.h"
39
#include "scarts-op.h"
40
#include "scarts_16-plugins.h"
41
#include "scarts_16-desc.h"
42
#include "scarts_16-tdep.h"
43
 
44
/* Macros for mapping the Processor Control Module plugin registers. */
45
#undef PROC_CTRL_STATUS_C
46
#define PROC_CTRL_STATUS_C      (*(uint8_t *const)  (plugin_proc_ctrl->get_mem() + PROC_CTRL_STATUS_C_BOFF))
47
#undef PROC_CTRL_CONFIG_C
48
#define PROC_CTRL_CONFIG_C      (*(uint8_t *const)  (plugin_proc_ctrl->get_mem() + PROC_CTRL_CONFIG_C_BOFF))
49
#undef PROC_CTRL_INTPROT
50
#define PROC_CTRL_INTPROT       (*(uint16_t *const) (plugin_proc_ctrl->get_mem() + PROC_CTRL_INTPROT_BOFF))
51
#undef PROC_CTRL_INTMASK
52
#define PROC_CTRL_INTMASK       (*(uint16_t *const) (plugin_proc_ctrl->get_mem() + PROC_CTRL_INTMASK_BOFF))
53
#undef PROC_CTRL_FPW
54
#define PROC_CTRL_FPW           (*(uint16_t *const) (plugin_proc_ctrl->get_mem() + PROC_CTRL_FPW_BOFF))
55
#undef PROC_CTRL_FPX
56
#define PROC_CTRL_FPX           (*(uint16_t *const) (plugin_proc_ctrl->get_mem() + PROC_CTRL_FPX_BOFF))
57
#undef PROC_CTRL_FPY
58
#define PROC_CTRL_FPY           (*(uint16_t *const) (plugin_proc_ctrl->get_mem() + PROC_CTRL_FPY_BOFF))
59
#undef PROC_CTRL_FPZ
60
#define PROC_CTRL_FPZ           (*(uint16_t *const) (plugin_proc_ctrl->get_mem() + PROC_CTRL_FPZ_BOFF))
61
#undef PROC_CTRL_SAVE_STATUS_C
62
#define PROC_CTRL_SAVE_STATUS_C (*(uint8_t *const)  (plugin_proc_ctrl->get_mem() + PROC_CTRL_SAVE_STATUS_C_BOFF))
63
#undef PROGRAMMER_CONFIG_C
64
#define PROGRAMMER_CONFIG_C     (*(uint8_t *const)  (plugin_programmer->get_mem() + PROGRAMMER_CONFIG_C_BOFF))
65
 
66
 
67
static int32_t          cond;
68
static int32_t          carry, old_carry;
69
static uint16_t         regfile[SCARTS_TOTAL_NUM_REGS];
70
static uint16_t         vectab[SCARTS_NUM_VECTORS];
71
static scarts_plugin_t *plugin_programmer;
72
static scarts_plugin_t *plugin_proc_ctrl;
73
 
74
static int is_addr_aligned (uint16_t addr, uint8_t alignment);
75
static int load_data       (uint16_t addr, uint16_t *data, enum scarts_access_mode mode);
76
static int store_data      (uint16_t addr, uint16_t data, enum scarts_access_mode mode);
77
 
78
static int
79
is_addr_aligned (uint16_t addr, uint8_t alignment)
80
{
81
  if ((addr % alignment) != 0)
82
  {
83
    error ("Unaligned memory access at 0x%X", addr);
84
    return 0;
85
  }
86
 
87
  return 1;
88
}
89
 
90
static int
91
load_data (uint16_t vma, uint16_t* data, enum scarts_access_mode mode)
92
{
93
  int i;
94
  uint8_t size, temp;
95
  uint16_t addr, result;
96
  scarts_datamem_read_fptr_t read_fptr;
97
  scarts_datamem_write_fptr_t write_fptr;
98
  enum scarts_mem_type mem_type;
99
 
100
  result = *data = 0;
101
 
102
  switch (mode)
103
  {
104
    case WORD:
105
    {
106
      if (!is_addr_aligned (vma, SCARTS_WORD_SIZE))
107
        return SIGBUS;
108
 
109
      size = 2;
110
      break;
111
    }
112
    case HWORD:
113
    case HWORDU:
114
    {
115
      if (!is_addr_aligned (vma, SCARTS_WORD_SIZE))
116
        return SIGBUS;
117
 
118
      size = 2;
119
      break;
120
    }
121
    case BYTE:
122
    case BYTEU:
123
    {
124
      size = 1;
125
      break;
126
    }
127
    default:
128
    {
129
      error ("Unsupported access mode.");
130
      return SIGILL;
131
    }
132
  }
133
 
134
  mem_type = scarts_datamem_vma_decode (vma, &read_fptr, &write_fptr, &addr);
135
  if (mem_type == SCARTS_NOMEM)
136
  {
137
    error ("Memory access at 0x%X is out of bounds.", vma);
138
    return SIGSEGV;
139
  }
140
 
141
  for (i = 0; i < size; ++i)
142
  {
143
    (void) (*read_fptr) (addr + i, &temp);
144
    result |= temp << (i * 8);
145
  }
146
 
147
  *data = result;
148
  return 0;
149
}
150
 
151
static int
152
store_data (uint16_t vma, uint16_t data, enum scarts_access_mode mode)
153
{
154
  int i;
155
  uint8_t size;
156
  uint16_t addr;
157
  scarts_datamem_read_fptr_t read_fptr;
158
  scarts_datamem_write_fptr_t write_fptr;
159
  enum scarts_mem_type mem_type;
160
 
161
  switch (mode)
162
  {
163
    case WORD:
164
    {
165
      if (!is_addr_aligned (vma, SCARTS_WORD_SIZE))
166
        return SIGBUS;
167
 
168
      size = 2;
169
      break;
170
    }
171
    case HWORD:
172
    case HWORDU:
173
    {
174
      if (!is_addr_aligned (vma, SCARTS_WORD_SIZE / 2))
175
        return SIGBUS;
176
 
177
      size = 2;
178
      break;
179
    }
180
    case BYTE:
181
    case BYTEU:
182
    {
183
      size = 1;
184
      break;
185
    }
186
    default:
187
    {
188
      error ("Unsupported access mode.");
189
      return SIGILL;
190
    }
191
  }
192
 
193
  mem_type = scarts_datamem_vma_decode (vma, &read_fptr, &write_fptr, &addr);
194
  if (mem_type == SCARTS_NOMEM)
195
  {
196
    error ("Memory access at 0x%X is out of bounds.", vma);
197
    return SIGSEGV;
198
  }
199
 
200
  for (i = 0; i < size; ++i)
201
  {
202
    (void) (*write_fptr) (addr + i, (uint8_t) (data >> (i * 8)));
203
  }
204
 
205
  return 0;
206
}
207
 
208
void
209
scarts_init (void)
210
{
211
  scarts_load_plugins ();
212
  plugin_programmer = scarts_get_plugin (PROGRAMMER_BADDR);
213
  if (plugin_programmer != NULL)
214
  {
215
    if (plugin_programmer->set_codemem_read_fptr == NULL)
216
    {
217
      /* Function 'set_codemem_read_fptr' is mandatory for the Programmer Module plugin. */
218
      error ("Unable to find function 'set_codemem_read_fptr' in Programmer Module plugin.");
219
      exit (EXIT_FAILURE);
220
    }
221
 
222
    plugin_programmer->set_codemem_read_fptr (scarts_codemem_read);
223
 
224
    if (plugin_programmer->set_codemem_write_fptr == NULL)
225
    {
226
      /* Function 'set_codemem_write_fptr' is mandatory for the Programmer Module plugin. */
227
      error ("Unable to find function 'set_codemem_write_fptr' in Programmer Module plugin.");
228
      exit (EXIT_FAILURE);
229
    }
230
 
231
    plugin_programmer->set_codemem_write_fptr (scarts_codemem_write);
232
 
233
    if (plugin_programmer->set_datamem_read_fptr == NULL)
234
    {
235
      /* Function 'set_datamem_read_fptr' is mandatory for the Programmer Module plugin. */
236
      error ("Unable to find function 'set_datamem_read_fptr' in Programmer Module plugin.");
237
      exit (EXIT_FAILURE);
238
    }
239
 
240
    plugin_programmer->set_datamem_read_fptr (scarts_datamem_read);
241
 
242
    if (plugin_programmer->set_datamem_write_fptr == NULL)
243
    {
244
      /* Function 'set_datamem_write_fptr' is mandatory for the Programmer Module plugin. */
245
      error ("Unable to find function 'set_datamem_write_fptr' in Programmer Module plugin.");
246
      exit (EXIT_FAILURE);
247
    }
248
 
249
    plugin_programmer->set_datamem_write_fptr (scarts_datamem_write);
250
  }
251
 
252
  plugin_proc_ctrl = scarts_get_plugin (PROC_CTRL_BADDR);
253
  if (plugin_proc_ctrl == NULL)
254
  {
255
    /* The System Control Module plugin is mandatory. */
256
    error ("Unable to find System Control Module plugin.");
257
    exit (EXIT_FAILURE);
258
  }
259
 
260
  scarts_bootmem_init ();
261
  regfile[SCARTS_PC_REGNUM] = SCARTS_BOOTMEM_VMA;
262
}
263
 
264
int
265
scarts_mem_read (uint16_t lma, uint8_t* value)
266
{
267
  uint16_t addr, temp;
268
  scarts_codemem_read_fptr_t codemem_read_fptr;
269
  scarts_codemem_write_fptr_t codemem_write_fptr;
270
  scarts_datamem_read_fptr_t datamem_read_fptr;
271
  scarts_datamem_write_fptr_t datamem_write_fptr;
272
  enum scarts_mem_type mem_type;
273
 
274
  mem_type = scarts_lma_decode (lma,
275
                                &codemem_read_fptr,
276
                                &codemem_write_fptr,
277
                                &datamem_read_fptr,
278
                                &datamem_write_fptr,
279
                                &addr);
280
 
281
  if (mem_type == SCARTS_NOMEM)
282
  {
283
    /* If the LMA could not be decoded properly, the following scenario might
284
       have occurred: the GDB has passed the VMA of a function pointer whose
285
       address got determined from the data memory beforehand. */
286
    mem_type = scarts_codemem_vma_decode (lma * SCARTS_INSN_SIZE,
287
                                          &codemem_read_fptr,
288
                                          &codemem_write_fptr,
289
                                          &addr);
290
 
291
    if (mem_type == SCARTS_NOMEM)
292
    {
293
      error ("Memory access at 0x%X is out of bounds.", lma);
294
      return SIGSEGV;
295
    }
296
  }
297
 
298
  switch (mem_type)
299
  {
300
    case SCARTS_BOOTMEM:
301
    case SCARTS_CODEMEM:
302
    {
303
      if ((*codemem_read_fptr) (addr, &temp) == 0)
304
        return 0;
305
 
306
      if ((lma & 1) == 0)
307
        *value = temp & 0x00FF;
308
      else
309
        *value = (temp >> 8) & 0x00FF;
310
 
311
      break;
312
    }
313
    default:
314
      break;
315
  }
316
 
317
  switch (mem_type)
318
  {
319
    case SCARTS_DATAMEM:
320
    case SCARTS_PLUGIN:
321
    {
322
      if ((*datamem_read_fptr) (addr, value) == 0)
323
        return 0;
324
 
325
      break;
326
    }
327
    default:
328
      break;
329
  }
330
 
331
  return 1;
332
}
333
 
334
int
335
scarts_mem_write (uint16_t lma, uint8_t value)
336
{
337
  uint16_t addr, temp;
338
  scarts_codemem_read_fptr_t codemem_read_fptr;
339
  scarts_codemem_write_fptr_t codemem_write_fptr;
340
  scarts_datamem_read_fptr_t datamem_read_fptr;
341
  scarts_datamem_write_fptr_t datamem_write_fptr;
342
  enum scarts_mem_type mem_type;
343
 
344
  mem_type = scarts_lma_decode (lma,
345
                                &codemem_read_fptr,
346
                                &codemem_write_fptr,
347
                                &datamem_read_fptr,
348
                                &datamem_write_fptr,
349
                                &addr);
350
 
351
  if (mem_type == SCARTS_NOMEM)
352
  {
353
    error ("Memory access at 0x%X is out of bounds.", lma);
354
    return SIGSEGV;
355
  }
356
 
357
  switch (mem_type)
358
  {
359
    case SCARTS_BOOTMEM:
360
    case SCARTS_CODEMEM:
361
    {
362
      if ((*codemem_read_fptr) (addr, &temp) == 0)
363
        return 0;
364
 
365
      if ((lma & 1) == 0)
366
      {
367
        temp &= 0xFF00;
368
        temp |= value;
369
      }
370
      else
371
      {
372
        temp &= 0x00FF;
373
        temp |= (value << 8);
374
      }
375
 
376
      (*codemem_write_fptr) (addr, temp);
377
      break;
378
    }
379
    default:
380
      break;
381
  }
382
 
383
  switch (mem_type)
384
  {
385
    case SCARTS_DATAMEM:
386
    case SCARTS_PLUGIN:
387
    {
388
      if ((*datamem_write_fptr) (addr, value) == 0)
389
        return 0;
390
 
391
      break;
392
    }
393
    default:
394
      break;
395
  }
396
 
397
  return 1;
398
}
399
 
400
uint16_t
401
scarts_regfile_read (int regno)
402
{
403
  if (regno >= 0 && regno < SCARTS_NUM_GP_REGS)
404
  {
405
    return regfile[regno];
406
  }
407
  else if (regno >= SCARTS_NUM_GP_REGS && regno < SCARTS_TOTAL_NUM_REGS)
408
  {
409
    switch (regno)
410
    {
411
      case SCARTS_FP_REGNUM:
412
        return PROC_CTRL_FPY;
413
      case SCARTS_SP_REGNUM:
414
        return PROC_CTRL_FPZ;
415
      default:
416
        return regfile[regno];
417
    }
418
  }
419
}
420
 
421
void
422
scarts_regfile_write (int regno, uint16_t value)
423
{
424
  if (regno >= 0 && regno < SCARTS_NUM_GP_REGS)
425
  {
426
    regfile[regno] = value;
427
  }
428
  else if (regno >= SCARTS_NUM_GP_REGS && regno < SCARTS_TOTAL_NUM_REGS)
429
  {
430
    switch (regno)
431
    {
432
      case SCARTS_FP_REGNUM:
433
        PROC_CTRL_FPY = value;
434
        break;
435
      case SCARTS_SP_REGNUM:
436
        PROC_CTRL_FPZ = value;
437
        break;
438
      default:
439
        regfile[regno] = value;
440
        break;
441
    }
442
  }
443
}
444
 
445
void
446
scarts_reset (void)
447
{
448
  uint16_t old_pc;
449
 
450
  cond = 0;
451
  carry = old_carry = 0;
452
  old_pc = regfile[SCARTS_PC_REGNUM];
453
 
454
  memset (regfile, 0, SCARTS_WORD_SIZE * SCARTS_TOTAL_NUM_REGS);
455
  memset (vectab, 0, SCARTS_WORD_SIZE * SCARTS_NUM_VECTORS);
456
  scarts_reset_plugins ();
457
 
458
  regfile[SCARTS_PC_REGNUM] = old_pc;
459
}
460
 
461
int
462
scarts_tick (void)
463
{
464
  int i, int_num, decode_steps, result;
465
  uint16_t unmasked_ints;
466
  uint16_t data;
467
  uint16_t addr, next_pc, *pc;
468
  scarts_codemem_read_fptr_t read_fptr;
469
  scarts_codemem_write_fptr_t write_fptr;
470
  scarts_op_t insn;
471
  enum scarts_mem_type mem_type;
472
 
473
  decode_steps = result = 0;
474
  data = 0;
475
  pc = &(regfile[SCARTS_PC_REGNUM]);
476
 
477
  if (plugin_programmer != NULL)
478
  {
479
    /* Check if the programmer module issued a soft-reset. */
480
    if ((PROGRAMMER_CONFIG_C & (1 << PROGRAMMER_CONFIG_C_CLR)))
481
      scarts_reset ();
482
  }
483
 
484
  next_pc = *pc;
485
 
486
  /* Call tick() for each plugin. */
487
  scarts_tick_plugins (pc);
488
 
489
  /* Check if a plugin requested an interrupt. */
490
  int_num = scarts_get_plugin_int_request ();
491
  if (int_num != -1)
492
  {
493
    /* Set interrupt bit in the Processor Control Module. */
494
    PROC_CTRL_INTPROT |= (1 << int_num);
495
  }
496
 
497
  /* Check for pending interrupts (INT0 is non-maskable). */
498
  unmasked_ints = PROC_CTRL_INTPROT & ((~PROC_CTRL_INTMASK) | 1);
499
 
500
  /* Check if the GIE flag is set in the config register. */
501
  if ((PROC_CTRL_CONFIG_C & (1 << PROC_CTRL_CONFIG_C_GIE)) && unmasked_ints != 0)
502
  {
503
    /* There is at least one interrupt pending and not masked. */
504
    int_num = 0;
505
    while (!(unmasked_ints & 1))
506
    {
507
      unmasked_ints >>= 1;
508
      int_num++;
509
    }
510
 
511
    /* De-protocol the interrupt in the protocol register. */
512
    PROC_CTRL_INTPROT &= ~(1 << int_num);
513
 
514
    /* Save the status register. */
515
    PROC_CTRL_SAVE_STATUS_C = PROC_CTRL_STATUS_C;
516
 
517
    /* Save the PC as return address for the RTE instruction. */
518
    regfile[SCARTS_RTE_REGNUM] = *pc;
519
 
520
    /* Disable the GIE flag in the config register. */
521
    PROC_CTRL_CONFIG_C &= ~(1 << PROC_CTRL_CONFIG_C_GIE);
522
 
523
    /* Jump to the ISR. */
524
    next_pc = *pc = vectab[int_num];
525
  }
526
 
527
  mem_type = scarts_codemem_vma_decode (*pc, &read_fptr, &write_fptr, &addr);
528
  if (mem_type == SCARTS_NOMEM)
529
  {
530
     error ("Memory access at 0x%X is out of bounds.", *pc);
531
     return SIGSEGV;
532
  }
533
 
534
  (void) (*read_fptr) (addr, &insn.raw);
535
 
536
  switch (insn.ldiop.op)
537
  {
538
    case OPC4_LDLI:
539
      regfile[insn.ldiop.reg] = insn.ldiop.val;
540
      break;
541
    case OPC4_LDHI:
542
      regfile[insn.ldiop.reg] &= 0xFF;
543
      regfile[insn.ldiop.reg] |= (int16_t) insn.ldiop.val << 8;
544
      assert(((regfile[insn.ldiop.reg] & 0x8000) == 0x8000) || ((regfile[insn.ldiop.reg] & 0x8000) == 0));
545
      break;
546
    case OPC4_LDLIU:
547
      regfile[insn.ldiop.reg] &= 0xFF00;
548
      regfile[insn.ldiop.reg] |= insn.ldiop.val & 0xFF;
549
      break;
550
    default:
551
      decode_steps++;
552
  }
553
 
554
  switch (insn.imm7op.op)
555
  {
556
    case OPC5_CMPI_LT:
557
      cond = ((int16_t) regfile[insn.imm7op.reg] < (int16_t) insn.imm7op.val);
558
      break;
559
    case OPC5_CMPI_GT:
560
      cond = ((int16_t) regfile[insn.imm7op.reg] > (int16_t) insn.imm7op.val);
561
      break;
562
    case OPC5_CMPI_EQ:
563
      cond = ((int16_t) regfile[insn.imm7op.reg] == (int16_t) insn.imm7op.val);
564
      break;
565
    default:
566
      decode_steps++;
567
  }
568
 
569
  switch (insn.imm6op.op)
570
  {
571
    case OPC6_LDFPW:
572
      if (result = load_data (PROC_CTRL_FPW + SCARTS_WORD_SIZE * insn.imm6op.val, &data, WORD))
573
        break;
574
 
575
      regfile[insn.imm6op.reg] = data;
576
      break;
577
    case OPC6_LDFPX:
578
      if (result = load_data (PROC_CTRL_FPX + SCARTS_WORD_SIZE * insn.imm6op.val, &data, WORD))
579
        break;
580
 
581
      regfile[insn.imm6op.reg] = data;
582
      break;
583
    case OPC6_LDFPY:
584
      if (result = load_data (PROC_CTRL_FPY + SCARTS_WORD_SIZE * insn.imm6op.val, &data, WORD))
585
        break;
586
 
587
      regfile[insn.imm6op.reg] = data;
588
      break;
589
    case OPC6_LDFPZ:
590
      if (result = load_data (PROC_CTRL_FPZ + SCARTS_WORD_SIZE * insn.imm6op.val, &data, WORD))
591
        break;
592
 
593
      regfile[insn.imm6op.reg] = data;
594
      break;
595
    case OPC6_STFPW:
596
      result = store_data (PROC_CTRL_FPW + SCARTS_WORD_SIZE * insn.imm6op.val, regfile[insn.imm6op.reg], WORD);
597
      break;
598
    case OPC6_STFPX:
599
      result = store_data (PROC_CTRL_FPX + SCARTS_WORD_SIZE * insn.imm6op.val, regfile[insn.imm6op.reg], WORD);
600
      break;
601
    case OPC6_STFPY:
602
      result = store_data (PROC_CTRL_FPY + SCARTS_WORD_SIZE * insn.imm6op.val, regfile[insn.imm6op.reg], WORD);
603
      break;
604
    case OPC6_STFPZ:
605
      result = store_data (PROC_CTRL_FPZ + SCARTS_WORD_SIZE * insn.imm6op.val, regfile[insn.imm6op.reg], WORD);
606
      break;
607
    case OPC6_ADDI:
608
      carry = ((int32_t) regfile[insn.imm6op.reg] + (int32_t) insn.imm6op.val) >> 16;
609
      regfile[insn.imm6op.reg] += insn.imm6op.val;
610
      break;
611
    case OPC6_ADDI_CT:
612
      if (cond)
613
      {
614
        carry = ((int32_t) regfile[insn.imm6op.reg] + (int32_t) insn.imm6op.val) >> 16;
615
        regfile[insn.imm6op.reg] += insn.imm6op.val;
616
      }
617
      break;
618
    case OPC6_ADDI_CF:
619
      if (!cond)
620
      {
621
        carry = ((int32_t) regfile[insn.imm6op.reg] + (int32_t) insn.imm6op.val) >> 16;
622
        regfile[insn.imm6op.reg] += insn.imm6op.val;
623
      }
624
      break;
625
    default:
626
      decode_steps++;
627
  }
628
 
629
  switch (insn.imm5op.op)
630
  {
631
    case OPC7_LDFPW_INC:
632
      if (result = load_data (PROC_CTRL_FPW + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
633
        break;
634
 
635
      regfile[insn.imm5op.reg] = data;
636
      PROC_CTRL_FPW += SCARTS_WORD_SIZE;
637
      break;
638
    case OPC7_LDFPW_DEC:
639
      if (result = load_data (PROC_CTRL_FPW + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
640
        break;
641
 
642
      regfile[insn.imm5op.reg] = data;
643
      PROC_CTRL_FPW -= SCARTS_WORD_SIZE;
644
      break;
645
    case OPC7_LDFPX_INC:
646
      if (result = load_data (PROC_CTRL_FPX + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
647
        break;
648
 
649
      regfile[insn.imm5op.reg] = data;
650
      PROC_CTRL_FPX += SCARTS_WORD_SIZE;
651
      break;
652
    case OPC7_LDFPX_DEC:
653
      if (result = load_data (PROC_CTRL_FPX + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
654
        break;
655
 
656
      regfile[insn.imm5op.reg] = data;
657
      PROC_CTRL_FPX -= SCARTS_WORD_SIZE;
658
      break;
659
    case OPC7_LDFPY_INC:
660
      if (result = load_data (PROC_CTRL_FPY + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
661
        break;
662
 
663
      regfile[insn.imm5op.reg] = data;
664
      PROC_CTRL_FPY += SCARTS_WORD_SIZE;
665
      break;
666
    case OPC7_LDFPY_DEC:
667
      if (result = load_data (PROC_CTRL_FPY + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
668
        break;
669
 
670
      regfile[insn.imm5op.reg] = data;
671
      PROC_CTRL_FPY -= SCARTS_WORD_SIZE;
672
      break;
673
    case OPC7_LDFPZ_INC:
674
      if (result = load_data (PROC_CTRL_FPZ + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
675
        break;
676
 
677
      regfile[insn.imm5op.reg] = data;
678
      PROC_CTRL_FPZ += SCARTS_WORD_SIZE;
679
      break;
680
    case OPC7_LDFPZ_DEC:
681
      if (result = load_data (PROC_CTRL_FPZ + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
682
        break;
683
 
684
      regfile[insn.imm5op.reg] = data;
685
      PROC_CTRL_FPZ -= SCARTS_WORD_SIZE;
686
      break;
687
    case OPC7_STFPW_INC:
688
      if (result = store_data (PROC_CTRL_FPW + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
689
        break;
690
 
691
      PROC_CTRL_FPW += SCARTS_WORD_SIZE;
692
      break;
693
    case OPC7_STFPW_DEC:
694
      if (result = store_data (PROC_CTRL_FPW + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
695
        break;
696
 
697
      PROC_CTRL_FPW -= SCARTS_WORD_SIZE;
698
      break;
699
    case OPC7_STFPX_INC:
700
      if (result = store_data (PROC_CTRL_FPX + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
701
        break;
702
 
703
      PROC_CTRL_FPX += SCARTS_WORD_SIZE;
704
      break;
705
    case OPC7_STFPX_DEC:
706
      if (result = store_data (PROC_CTRL_FPX + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
707
        break;
708
 
709
      PROC_CTRL_FPX -= SCARTS_WORD_SIZE;
710
    case OPC7_STFPY_INC:
711
      if (result = store_data (PROC_CTRL_FPY + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
712
        break;
713
 
714
      PROC_CTRL_FPY += SCARTS_WORD_SIZE;
715
      break;
716
    case OPC7_STFPY_DEC:
717
      if (result = store_data (PROC_CTRL_FPY + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
718
        break;
719
 
720
      PROC_CTRL_FPY -= SCARTS_WORD_SIZE;
721
      break;
722
    case OPC7_STFPZ_INC:
723
      if (result = store_data (PROC_CTRL_FPZ + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
724
        break;
725
 
726
      PROC_CTRL_FPZ += SCARTS_WORD_SIZE;
727
      break;
728
    case OPC7_STFPZ_DEC:
729
      if (result = store_data (PROC_CTRL_FPZ + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
730
        break;
731
 
732
      PROC_CTRL_FPZ -= SCARTS_WORD_SIZE;
733
      break;
734
    case OPC7_STVEC:
735
      vectab[insn.imm5op.val + 16] = regfile[insn.imm5op.reg];
736
      break;
737
    case OPC7_LDVEC:
738
      regfile[insn.imm5op.reg] = vectab[insn.imm5op.val + 16];
739
      break;
740
    default:
741
      decode_steps++;
742
  }
743
 
744
  switch (insn.imm4op.op)
745
  {
746
    case OPC8_BSET:
747
      regfile[insn.imm4op.reg] |= 1 << (uint16_t) insn.imm4op.val;
748
      break;
749
    case OPC8_BCLR:
750
      regfile[insn.imm4op.reg] &= ~(1 << (uint16_t) insn.imm4op.val);
751
      break;
752
    case OPC8_BSET_CT:
753
      if (cond)
754
      {
755
        regfile[insn.imm4op.reg] |= 1 << (uint16_t) insn.imm4op.val;
756
      }
757
      break;
758
    case OPC8_BCLR_CT:
759
      if (cond)
760
      {
761
        regfile[insn.imm4op.reg] &= ~(1 << (uint16_t) insn.imm4op.val);
762
      }
763
      break;
764
    case OPC8_BSET_CF:
765
      if (!cond)
766
      {
767
        regfile[insn.imm4op.reg] |= 1 << (uint16_t) insn.imm4op.val;
768
      }
769
      break;
770
    case OPC8_BCLR_CF:
771
      if (!cond)
772
      {
773
        regfile[insn.imm4op.reg] &= ~(1 << (uint16_t) insn.imm4op.val);
774
      }
775
      break;
776
    case OPC8_BTEST:
777
      cond = ((regfile[insn.imm4op.reg] & (1 << (uint16_t) insn.imm4op.val)) != 0);
778
      break;
779
    case OPC8_SLI:
780
      carry = (regfile[insn.imm4op.reg] >> (16 - (uint16_t) insn.imm4op.val)) & 1;
781
      regfile[insn.imm4op.reg] <<= (uint16_t) insn.imm4op.val;
782
      break;
783
    case OPC8_SRI:
784
      carry = regfile[insn.imm4op.reg] & (1 << ((uint16_t) insn.imm4op.val - 1));
785
      regfile[insn.imm4op.reg] >>= (uint16_t) insn.imm4op.val;
786
      break;
787
    case OPC8_SRAI:
788
      carry = regfile[insn.imm4op.reg] & (1 << ((uint16_t) insn.imm4op.val - 1));
789
      regfile[insn.imm4op.reg] = (int16_t) regfile[insn.imm4op.reg] >> (uint16_t) insn.imm4op.val;
790
      break;
791
    case OPC8_TRAP:
792
      regfile[SCARTS_RTE_REGNUM] = *pc + SCARTS_INSN_SIZE;
793
      next_pc = vectab[insn.imm4op.val + 16] - SCARTS_INSN_SIZE;
794
      break;
795
    case OPC8_SLI_CT:
796
      if (cond)
797
      {
798
        carry = (regfile[insn.imm4op.reg] >> (16 - (uint16_t) insn.imm4op.val)) & 1;
799
        regfile[insn.imm4op.reg] <<= (uint16_t) insn.imm4op.val;
800
      }
801
      break;
802
    case OPC8_SRI_CT:
803
      if (cond)
804
      {
805
        carry = regfile[insn.imm4op.reg] & (1 << ((uint16_t) insn.imm4op.val - 1));
806
        regfile[insn.imm4op.reg] >>= (uint16_t) insn.imm4op.val;
807
      }
808
      break;
809
    case OPC8_SRAI_CT:
810
      if (cond)
811
      {
812
        carry = regfile[insn.imm4op.reg] & (1 << ((uint16_t) insn.imm4op.val - 1));
813
        regfile[insn.imm4op.reg] = (int16_t) regfile[insn.imm4op.reg] >> (uint16_t) insn.imm4op.val;
814
      }
815
      break;
816
    case OPC8_TRAP_CT:
817
      if (cond)
818
      {
819
        regfile[SCARTS_RTE_REGNUM] = *pc + SCARTS_INSN_SIZE;
820
        next_pc = vectab[insn.imm4op.val + 16] - SCARTS_INSN_SIZE;
821
      }
822
      break;
823
    case OPC8_SLI_CF:
824
      if (!cond)
825
      {
826
        carry = (regfile[insn.imm4op.reg] >> (16 - (uint16_t) insn.imm4op.val)) & 1;
827
        regfile[insn.imm4op.reg] <<= (uint16_t) insn.imm4op.val;
828
      }
829
      break;
830
    case OPC8_SRI_CF:
831
      if (!cond)
832
      {
833
        carry = regfile[insn.imm4op.reg] & (1 << ((uint16_t) insn.imm4op.val - 1));
834
        regfile[insn.imm4op.reg] >>= (uint16_t) insn.imm4op.val;
835
      }
836
      break;
837
    case OPC8_SRAI_CF:
838
      if (!cond)
839
      {
840
        carry = regfile[insn.imm4op.reg] & (1 << ((uint16_t) insn.imm4op.val - 1));
841
        regfile[insn.imm4op.reg] = (int16_t) regfile[insn.imm4op.reg] >> (uint16_t) insn.imm4op.val;
842
      }
843
      break;
844
    case OPC8_TRAP_CF:
845
      if (!cond)
846
      {
847
        regfile[SCARTS_RTE_REGNUM] = *pc + SCARTS_INSN_SIZE;
848
        next_pc = vectab[insn.imm4op.val + 16] - SCARTS_INSN_SIZE;
849
      }
850
      break;
851
    default:
852
      decode_steps++;
853
  }
854
 
855
  switch (insn.binop.op)
856
  {
857
    case OPC8_SL:
858
      carry = (regfile[insn.binop.reg1] >> (16 - regfile[insn.binop.reg2])) & 1;
859
      regfile[insn.binop.reg1] <<= regfile[insn.binop.reg2];
860
      break;
861
    case OPC8_SR:
862
      carry = regfile[insn.binop.reg1] & (1 << (regfile[insn.binop.reg2] - 1));
863
      regfile[insn.binop.reg1] >>= regfile[insn.binop.reg2];
864
      break;
865
    case OPC8_SRA:
866
      carry = regfile[insn.binop.reg1] & (1 << (regfile[insn.binop.reg2] - 1));
867
      regfile[insn.binop.reg1] = (int16_t) regfile[insn.binop.reg1] >> regfile[insn.binop.reg2];
868
      break;
869
    case OPC8_SL_CT:
870
      if (cond)
871
      {
872
        carry = (regfile[insn.binop.reg1] >> (16 - regfile[insn.binop.reg2])) & 1;
873
        regfile[insn.binop.reg1] <<= regfile[insn.binop.reg2];
874
      }
875
      break;
876
    case OPC8_SR_CT:
877
      if (cond)
878
      {
879
        carry = regfile[insn.binop.reg1] & (1 << (regfile[insn.binop.reg2] - 1));
880
        regfile[insn.binop.reg1] >>= regfile[insn.binop.reg2];
881
      }
882
      break;
883
    case OPC8_SRA_CT:
884
      if (cond)
885
      {
886
        carry = regfile[insn.binop.reg1] & (1 << (regfile[insn.binop.reg2] - 1));
887
        regfile[insn.binop.reg1] = (int16_t) regfile[insn.binop.reg1] >> regfile[insn.binop.reg2];
888
      }
889
      break;
890
    case OPC8_SL_CF:
891
      if (!cond)
892
      {
893
        carry = (regfile[insn.binop.reg1] >> (16 - regfile[insn.binop.reg2])) & 1;
894
        regfile[insn.binop.reg1] <<= regfile[insn.binop.reg2];
895
      }
896
      break;
897
    case OPC8_SR_CF:
898
      if (!cond)
899
      {
900
        carry = regfile[insn.binop.reg1] & (1 << (regfile[insn.binop.reg2] - 1));
901
        regfile[insn.binop.reg1] >>= regfile[insn.binop.reg2];
902
      }
903
      break;
904
    case OPC8_SRA_CF:
905
      if (!cond)
906
      {
907
        carry = regfile[insn.binop.reg1] & (1 << (regfile[insn.binop.reg2] - 1));
908
        regfile[insn.binop.reg1] = (int16_t) regfile[insn.binop.reg1] >> regfile[insn.binop.reg2];
909
      }
910
      break;
911
    case OPC8_CMP_EQ:
912
      cond = (regfile[insn.binop.reg1] == regfile[insn.binop.reg2]);
913
      break;
914
    case OPC8_CMP_LT:
915
      cond = ((int16_t) regfile[insn.binop.reg1] < (int16_t) regfile[insn.binop.reg2]);
916
      break;
917
    case OPC8_CMP_GT:
918
      cond = ((int16_t) regfile[insn.binop.reg1] > (int16_t) regfile[insn.binop.reg2]);
919
      break;
920
    case OPC8_CMPU_LT:
921
      cond = ((uint16_t) regfile[insn.binop.reg1] < (uint16_t) regfile[insn.binop.reg2]);
922
      break;
923
    case OPC8_CMPU_GT:
924
      cond = ((uint16_t) regfile[insn.binop.reg1] > (uint16_t) regfile[insn.binop.reg2]);
925
      break;
926
    case OPC8_MOV:
927
      regfile[insn.binop.reg1] = regfile[insn.binop.reg2];
928
      break;
929
    case OPC8_ADD:
930
      carry = ((int32_t) regfile[insn.binop.reg1] + (int32_t) regfile[insn.binop.reg2]) >> 16;
931
      regfile[insn.binop.reg1] += regfile[insn.binop.reg2];
932
      break;
933
    case OPC8_ADDC:
934
      old_carry = carry;
935
      carry = ((int32_t) regfile[insn.binop.reg1] + (int32_t) regfile[insn.binop.reg2] + old_carry) >> 16;
936
      regfile[insn.binop.reg1] += regfile[insn.binop.reg2] + old_carry;
937
      break;
938
    case OPC8_SUB:
939
      carry = ((int32_t) regfile[insn.binop.reg1] - (int32_t) regfile[insn.binop.reg2]) >> 16;
940
      regfile[insn.binop.reg1] -= regfile[insn.binop.reg2];
941
      break;
942
    case OPC8_SUBC:
943
      old_carry = carry;
944
      carry = ((int32_t) regfile[insn.binop.reg1] - (int32_t) regfile[insn.binop.reg2] - old_carry) >> 16;
945
      regfile[insn.binop.reg1] -= regfile[insn.binop.reg2] + old_carry;
946
      break;
947
    case OPC8_AND:
948
      regfile[insn.binop.reg1] &= regfile[insn.binop.reg2];
949
      break;
950
    case OPC8_OR:
951
      regfile[insn.binop.reg1] |= regfile[insn.binop.reg2];
952
      break;
953
    case OPC8_EOR:
954
      regfile[insn.binop.reg1] ^= regfile[insn.binop.reg2];
955
      break;
956
    case OPC8_MOV_CT:
957
      if (cond)
958
      {
959
        regfile[insn.binop.reg1] = regfile[insn.binop.reg2];
960
      }
961
      break;
962
    case OPC8_ADD_CT:
963
      if (cond)
964
      {
965
        carry = ((int32_t) regfile[insn.binop.reg1] + (int32_t) regfile[insn.binop.reg2]) >> 16;
966
        regfile[insn.binop.reg1] += regfile[insn.binop.reg2];
967
      }
968
      break;
969
    case OPC8_ADDC_CT:
970
      if (cond)
971
      {
972
        old_carry = carry;
973
        carry = ((int32_t) regfile[insn.binop.reg1] + (int32_t) regfile[insn.binop.reg2] + old_carry) >> 16;
974
        regfile[insn.binop.reg1] += regfile[insn.binop.reg2] + old_carry;
975
      }
976
      break;
977
    case OPC8_SUB_CT:
978
      if (cond)
979
      {
980
        carry = ((int32_t) regfile[insn.binop.reg1] - (int32_t) regfile[insn.binop.reg2]) >> 16;
981
        regfile[insn.binop.reg1] -= regfile[insn.binop.reg2];
982
      }
983
      break;
984
    case OPC8_SUBC_CT:
985
      if (cond)
986
      {
987
        old_carry = carry;
988
        carry = ((int32_t) regfile[insn.binop.reg1] - (int32_t) regfile[insn.binop.reg2] - old_carry) >> 16;
989
        regfile[insn.binop.reg1] -= regfile[insn.binop.reg2] + old_carry;
990
      }
991
      break;
992
    case OPC8_AND_CT:
993
      if (cond)
994
      {
995
        regfile[insn.binop.reg1] &= regfile[insn.binop.reg2];
996
      }
997
      break;
998
    case OPC8_OR_CT:
999
      if (cond)
1000
      {
1001
        regfile[insn.binop.reg1] |= regfile[insn.binop.reg2];
1002
      }
1003
      break;
1004
    case OPC8_EOR_CT:
1005
      if (cond)
1006
      {
1007
        regfile[insn.binop.reg1] ^= regfile[insn.binop.reg2];
1008
      }
1009
      break;
1010
    case OPC8_MOV_CF:
1011
      if (!cond)
1012
      {
1013
        regfile[insn.binop.reg1] = regfile[insn.binop.reg2];
1014
      }
1015
      break;
1016
    case OPC8_ADD_CF:
1017
      if (!cond)
1018
      {
1019
        carry = ((int32_t) regfile[insn.binop.reg1] + (int32_t) regfile[insn.binop.reg2]) >> 16;
1020
        regfile[insn.binop.reg1] += regfile[insn.binop.reg2];
1021
      }
1022
      break;
1023
    case OPC8_ADDC_CF:
1024
      if (!cond)
1025
      {
1026
        old_carry = carry;
1027
        carry = ((int32_t) regfile[insn.binop.reg1] + (int32_t) regfile[insn.binop.reg2] + old_carry) >> 16;
1028
        regfile[insn.binop.reg1] += regfile[insn.binop.reg2] + old_carry;
1029
      }
1030
      break;
1031
    case OPC8_SUB_CF:
1032
      if (!cond)
1033
      {
1034
        carry = ((int32_t)regfile[insn.binop.reg1] - (int32_t)regfile[insn.binop.reg2]) >> 16;
1035
        regfile[insn.binop.reg1] -= regfile[insn.binop.reg2];
1036
      }
1037
      break;
1038
    case OPC8_SUBC_CF:
1039
      if (!cond)
1040
      {
1041
        old_carry = carry;
1042
        carry = ((int32_t) regfile[insn.binop.reg1] - (int32_t) regfile[insn.binop.reg2] - old_carry) >> 16;
1043
        regfile[insn.binop.reg1] -= regfile[insn.binop.reg2] + old_carry;
1044
      }
1045
      break;
1046
    case OPC8_AND_CF:
1047
      if (!cond)
1048
      {
1049
        regfile[insn.binop.reg1] &= regfile[insn.binop.reg2];
1050
      }
1051
      break;
1052
    case OPC8_OR_CF:
1053
      if (!cond)
1054
      {
1055
        regfile[insn.binop.reg1] |= regfile[insn.binop.reg2];
1056
      }
1057
      break;
1058
    case OPC8_EOR_CF:
1059
      if (!cond)
1060
      {
1061
        regfile[insn.binop.reg1] ^= regfile[insn.binop.reg2];
1062
      }
1063
      break;
1064
    case OPC8_LDH:
1065
      if (result = load_data (regfile[insn.binop.reg2], &data, HWORD))
1066
        break;
1067
 
1068
      regfile[insn.binop.reg1] = data;
1069
      break;
1070
    case OPC8_LDB:
1071
      if (result = load_data (regfile[insn.binop.reg2], &data, BYTE))
1072
        break;
1073
 
1074
      regfile[insn.binop.reg1] = data;
1075
      break;
1076
    case OPC8_LDBU:
1077
      if (result = load_data (regfile[insn.binop.reg2], &data, BYTEU))
1078
        break;
1079
 
1080
      regfile[insn.binop.reg1] = data;
1081
      break;
1082
    case OPC8_STH:
1083
      result = store_data (regfile[insn.binop.reg2], regfile[insn.binop.reg1], HWORD);
1084
      break;
1085
    case OPC8_STB:
1086
      result = store_data (regfile[insn.binop.reg2], regfile[insn.binop.reg1], BYTE);
1087
      break;
1088
    default:
1089
      decode_steps++;
1090
  }
1091
 
1092
  switch (insn.jmpiop.op)
1093
  {
1094
    case OPC6_JMPI:
1095
      next_pc += (insn.jmpiop.dest * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1096
      break;
1097
    case OPC6_JMPI_CT:
1098
      if (cond)
1099
      {
1100
        next_pc += (insn.jmpiop.dest * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1101
      }
1102
      break;
1103
    case OPC6_JMPI_CF:
1104
      if (!cond)
1105
      {
1106
        next_pc += (insn.jmpiop.dest * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1107
      }
1108
      break;
1109
    default:
1110
      decode_steps++;
1111
  }
1112
 
1113
  switch (insn.unop.op)
1114
  {
1115
    case OPC12_RRC:
1116
      old_carry = carry;
1117
      carry = regfile[insn.unop.reg] & 1;
1118
      regfile[insn.unop.reg] >>= 1;
1119
      regfile[insn.unop.reg] |= old_carry << 15;
1120
      break;
1121
    case OPC12_NOT:
1122
      regfile[insn.unop.reg] = ~regfile[insn.unop.reg];
1123
      break;
1124
    case OPC12_NEG:
1125
      regfile[insn.unop.reg] = -regfile[insn.unop.reg];
1126
      break;
1127
    case OPC12_JSR:
1128
      regfile[SCARTS_RTS_REGNUM] = *pc + SCARTS_INSN_SIZE;
1129
      next_pc = (regfile[insn.unop.reg] * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1130
      break;
1131
    case OPC12_JMP:
1132
      next_pc = (regfile[insn.unop.reg] * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1133
      break;
1134
    case OPC12_RRC_CT:
1135
      if (cond)
1136
      {
1137
        old_carry = carry;
1138
        carry = regfile[insn.unop.reg] & 1;
1139
        regfile[insn.unop.reg] >>= 1;
1140
        regfile[insn.unop.reg] |= old_carry << 15;
1141
      }
1142
      break;
1143
    case OPC12_NOT_CT:
1144
      if (cond)
1145
      {
1146
        regfile[insn.unop.reg] = ~regfile[insn.unop.reg];
1147
      }
1148
      break;
1149
    case OPC12_NEG_CT:
1150
      if (cond)
1151
      {
1152
        regfile[insn.unop.reg] = -regfile[insn.unop.reg];
1153
      }
1154
      break;
1155
    case OPC12_JSR_CT:
1156
      if (cond)
1157
      {
1158
        regfile[SCARTS_RTS_REGNUM] = *pc + SCARTS_INSN_SIZE;
1159
        next_pc = (regfile[insn.unop.reg] * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1160
      }
1161
      break;
1162
    case OPC12_JMP_CT:
1163
      if (cond)
1164
      {
1165
        next_pc = (regfile[insn.unop.reg] * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1166
      }
1167
      break;
1168
    case OPC12_RRC_CF:
1169
      if (!cond)
1170
      {
1171
        old_carry = carry;
1172
        carry = regfile[insn.unop.reg] & 1;
1173
        regfile[insn.unop.reg] >>= 1;
1174
        regfile[insn.unop.reg] |= old_carry << 15;
1175
      }
1176
      break;
1177
    case OPC12_NOT_CF:
1178
      if (!cond)
1179
      {
1180
        regfile[insn.unop.reg] = ~regfile[insn.unop.reg];
1181
      }
1182
      break;
1183
    case OPC12_NEG_CF:
1184
      if (!cond)
1185
      {
1186
        regfile[insn.unop.reg] = -regfile[insn.unop.reg];
1187
      }
1188
      break;
1189
    case OPC12_JSR_CF:
1190
      if (!cond)
1191
      {
1192
        regfile[SCARTS_RTS_REGNUM] = *pc + SCARTS_INSN_SIZE;
1193
        next_pc = (regfile[insn.unop.reg] * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1194
      }
1195
      break;
1196
    case OPC12_JMP_CF:
1197
      if (!cond)
1198
      {
1199
        next_pc = (regfile[insn.unop.reg] * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1200
      }
1201
      break;
1202
    default:
1203
      decode_steps++;
1204
  }
1205
 
1206
  switch (insn.nulop.op)
1207
  {
1208
    case OPC16_RTS:
1209
      next_pc = regfile[SCARTS_RTS_REGNUM] - SCARTS_INSN_SIZE;
1210
      break;
1211
    case OPC16_RTE:
1212
      PROC_CTRL_CONFIG_C |= (1 << PROC_CTRL_CONFIG_C_GIE);
1213
      PROC_CTRL_STATUS_C = PROC_CTRL_SAVE_STATUS_C;
1214
      next_pc = regfile[SCARTS_RTS_REGNUM] - SCARTS_INSN_SIZE;
1215
      break;
1216
    case OPC16_NOP:
1217
      break;
1218
    case OPC16_ILLOP:
1219
      result = SIGILL;
1220
      break;
1221
    default:
1222
      decode_steps++;
1223
  }
1224
 
1225
  carry = (!!carry) & 1;
1226
 
1227
  /* Compute the PC. */
1228
  *pc = next_pc;
1229
  *pc += SCARTS_INSN_SIZE;
1230
 
1231
  if (decode_steps != 8)
1232
  {
1233
    error ("Error in decoder stage (PC: 0x%X)", *pc - SCARTS_INSN_SIZE);
1234
    exit (EXIT_FAILURE);
1235
  }
1236
 
1237
  return result;
1238
}
1239
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.