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

Subversion Repositories scarts

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 jlechner
/* SCARTS (32-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_32-codemem.h"
36
#include "scarts_32-datamem.h"
37
#include "scarts_32-iss.h"
38
#include "scarts_32-mad.h"
39
#include "scarts-op.h"
40
#include "scarts_32-plugins.h"
41
#include "scarts_32-desc.h"
42
#include "scarts_32-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           (*(uint32_t *const) (plugin_proc_ctrl->get_mem() + PROC_CTRL_FPW_BOFF))
55
#undef PROC_CTRL_FPX
56
#define PROC_CTRL_FPX           (*(uint32_t *const) (plugin_proc_ctrl->get_mem() + PROC_CTRL_FPX_BOFF))
57
#undef PROC_CTRL_FPY
58
#define PROC_CTRL_FPY           (*(uint32_t *const) (plugin_proc_ctrl->get_mem() + PROC_CTRL_FPY_BOFF))
59
#undef PROC_CTRL_FPZ
60
#define PROC_CTRL_FPZ           (*(uint32_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 uint32_t         regfile[SCARTS_TOTAL_NUM_REGS];
70
static uint32_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 (uint32_t addr, uint8_t alignment);
75
static int load_data       (uint32_t addr, uint32_t *data, enum scarts_access_mode mode);
76
static int store_data      (uint32_t addr, uint32_t data, enum scarts_access_mode mode);
77
 
78
static int
79
is_addr_aligned (uint32_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 (uint32_t vma, uint32_t* data, enum scarts_access_mode mode)
92
{
93
  int i;
94
  uint8_t size, temp;
95
  uint32_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 = 4;
110
      break;
111
    }
112
    case HWORD:
113
    case HWORDU:
114
    {
115
      if (!is_addr_aligned (vma, SCARTS_WORD_SIZE / 2))
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 (uint32_t vma, uint32_t data, enum scarts_access_mode mode)
153
{
154
  int i;
155
  uint8_t size;
156
  uint32_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 = 4;
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 (uint32_t lma, uint8_t* value)
266
{
267
  uint16_t temp;
268
  uint32_t addr;
269
  scarts_codemem_read_fptr_t codemem_read_fptr;
270
  scarts_codemem_write_fptr_t codemem_write_fptr;
271
  scarts_datamem_read_fptr_t datamem_read_fptr;
272
  scarts_datamem_write_fptr_t datamem_write_fptr;
273
  enum scarts_mem_type mem_type;
274
 
275
  mem_type = scarts_lma_decode (lma,
276
                                &codemem_read_fptr,
277
                                &codemem_write_fptr,
278
                                &datamem_read_fptr,
279
                                &datamem_write_fptr,
280
                                &addr);
281
 
282
  if (mem_type == SCARTS_NOMEM)
283
  {
284
    /* If the LMA could not be decoded properly, the following scenario might
285
       have occurred: the GDB has passed the VMA of a function pointer whose
286
       address got determined from the data memory beforehand. */
287
    mem_type = scarts_codemem_vma_decode (lma * SCARTS_INSN_SIZE,
288
                                          &codemem_read_fptr,
289
                                          &codemem_write_fptr,
290
                                          &addr);
291
 
292
    if (mem_type == SCARTS_NOMEM)
293
    {
294
      error ("Memory access at 0x%X is out of bounds.", lma);
295
      return SIGSEGV;
296
    }
297
  }
298
 
299
  switch (mem_type)
300
  {
301
    case SCARTS_BOOTMEM:
302
    case SCARTS_CODEMEM:
303
    {
304
      if ((*codemem_read_fptr) (addr, &temp) == 0)
305
        return 0;
306
 
307
      if ((lma & 1) == 0)
308
        *value = temp & 0x00FF;
309
      else
310
        *value = (temp >> 8) & 0x00FF;
311
 
312
      break;
313
    }
314
    default:
315
      break;
316
  }
317
 
318
  switch (mem_type)
319
  {
320
    case SCARTS_DATAMEM:
321
    case SCARTS_PLUGIN:
322
    {
323
      if ((*datamem_read_fptr) (addr, value) == 0)
324
        return 0;
325
 
326
      break;
327
    }
328
    default:
329
      break;
330
  }
331
 
332
  return 1;
333
}
334
 
335
int
336
scarts_mem_write (uint32_t lma, uint8_t value)
337
{
338
  uint16_t temp;
339
  uint32_t addr;
340
  scarts_codemem_read_fptr_t codemem_read_fptr;
341
  scarts_codemem_write_fptr_t codemem_write_fptr;
342
  scarts_datamem_read_fptr_t datamem_read_fptr;
343
  scarts_datamem_write_fptr_t datamem_write_fptr;
344
  enum scarts_mem_type mem_type;
345
 
346
  mem_type = scarts_lma_decode (lma,
347
                                &codemem_read_fptr,
348
                                &codemem_write_fptr,
349
                                &datamem_read_fptr,
350
                                &datamem_write_fptr,
351
                                &addr);
352
 
353
  if (mem_type == SCARTS_NOMEM)
354
  {
355
    error ("Memory access at 0x%X is out of bounds.", lma);
356
    return SIGSEGV;
357
  }
358
 
359
  switch (mem_type)
360
  {
361
    case SCARTS_BOOTMEM:
362
    case SCARTS_CODEMEM:
363
    {
364
      if ((*codemem_read_fptr) (addr, &temp) == 0)
365
        return 0;
366
 
367
      if ((lma & 1) == 0)
368
      {
369
        temp &= 0xFF00;
370
        temp |= value;
371
      }
372
      else
373
      {
374
        temp &= 0x00FF;
375
        temp |= (value << 8);
376
      }
377
 
378
      (*codemem_write_fptr) (addr, temp);
379
      break;
380
    }
381
    default:
382
      break;
383
  }
384
 
385
  switch (mem_type)
386
  {
387
    case SCARTS_DATAMEM:
388
    case SCARTS_PLUGIN:
389
    {
390
      if ((*datamem_write_fptr) (addr, value) == 0)
391
        return 0;
392
 
393
      break;
394
    }
395
    default:
396
      break;
397
  }
398
 
399
  return 1;
400
}
401
 
402
uint32_t
403
scarts_regfile_read (int regno)
404
{
405
  if (regno >= 0 && regno < SCARTS_NUM_GP_REGS)
406
  {
407
    return regfile[regno];
408
  }
409
  else if (regno >= SCARTS_NUM_GP_REGS && regno < SCARTS_TOTAL_NUM_REGS)
410
  {
411
    switch (regno)
412
    {
413
      case SCARTS_FP_REGNUM:
414
        return PROC_CTRL_FPY;
415
      case SCARTS_SP_REGNUM:
416
        return PROC_CTRL_FPZ;
417
      default:
418
        return regfile[regno];
419
    }
420
  }
421
}
422
 
423
void
424
scarts_regfile_write (int regno, uint32_t value)
425
{
426
  if (regno >= 0 && regno < SCARTS_NUM_GP_REGS)
427
  {
428
    regfile[regno] = value;
429
  }
430
  else if (regno >= SCARTS_NUM_GP_REGS && regno < SCARTS_TOTAL_NUM_REGS)
431
  {
432
    switch (regno)
433
    {
434
      case SCARTS_FP_REGNUM:
435
        PROC_CTRL_FPY = value;
436
        break;
437
      case SCARTS_SP_REGNUM:
438
        PROC_CTRL_FPZ = value;
439
        break;
440
      default:
441
        regfile[regno] = value;
442
        break;
443
    }
444
  }
445
}
446
 
447
void
448
scarts_reset (void)
449
{
450
  uint32_t old_pc;
451
 
452
  cond = 0;
453
  carry = old_carry = 0;
454
  old_pc = regfile[SCARTS_PC_REGNUM];
455
 
456
  memset (regfile, 0, SCARTS_WORD_SIZE * SCARTS_TOTAL_NUM_REGS);
457
  memset (vectab, 0, SCARTS_WORD_SIZE * SCARTS_NUM_VECTORS);
458
  scarts_reset_plugins ();
459
 
460
  regfile[SCARTS_PC_REGNUM] = old_pc;
461
}
462
 
463
int
464
scarts_tick (void)
465
{
466
  int i, int_num, decode_steps, result;
467
  uint16_t unmasked_ints;
468
  uint32_t data;
469
  uint32_t addr, next_pc, *pc;
470
  scarts_codemem_read_fptr_t read_fptr;
471
  scarts_codemem_write_fptr_t write_fptr;
472
  scarts_op_t insn;
473
  enum scarts_mem_type mem_type;
474
 
475
  decode_steps = result = 0;
476
  data = 0;
477
  pc = &(regfile[SCARTS_PC_REGNUM]);
478
 
479
  if (plugin_programmer != NULL)
480
  {
481
    /* Check if the programmer module issued a soft-reset. */
482
    if ((PROGRAMMER_CONFIG_C & (1 << PROGRAMMER_CONFIG_C_CLR)))
483
      scarts_reset ();
484
  }
485
 
486
  next_pc = *pc;
487
 
488
  /* Call tick() for each plugin. */
489
  scarts_tick_plugins (pc);
490
 
491
  /* Check if a plugin requested an interrupt. */
492
  int_num = scarts_get_plugin_int_request ();
493
  if (int_num != -1)
494
  {
495
    /* Set interrupt bit in the Processor Control Module. */
496
    PROC_CTRL_INTPROT |= (1 << int_num);
497
  }
498
 
499
  /* Check for pending interrupts (INT0 is non-maskable). */
500
  unmasked_ints = PROC_CTRL_INTPROT & ((~PROC_CTRL_INTMASK) | 1);
501
 
502
  /* Check if the GIE flag is set in the config register. */
503
  if ((PROC_CTRL_CONFIG_C & (1 << PROC_CTRL_CONFIG_C_GIE)) && unmasked_ints != 0)
504
  {
505
    /* There is at least one interrupt pending and not masked. */
506
    int_num = 0;
507
    while (!(unmasked_ints & 1))
508
    {
509
      unmasked_ints >>= 1;
510
      int_num++;
511
    }
512
 
513
    /* De-protocol the interrupt in the protocol register. */
514
    PROC_CTRL_INTPROT &= ~(1 << int_num);
515
 
516
    /* Save the status register. */
517
    PROC_CTRL_SAVE_STATUS_C = PROC_CTRL_STATUS_C;
518
 
519
    /* Save the PC as return address for the RTE instruction. */
520
    regfile[SCARTS_RTE_REGNUM] = *pc;
521
 
522
    /* Disable the GIE flag in the config register. */
523
    PROC_CTRL_CONFIG_C &= ~(1 << PROC_CTRL_CONFIG_C_GIE);
524
 
525
    /* Jump to the ISR. */
526
    next_pc = *pc = vectab[int_num];
527
  }
528
 
529
  mem_type = scarts_codemem_vma_decode (*pc, &read_fptr, &write_fptr, &addr);
530
  if (mem_type == SCARTS_NOMEM)
531
  {
532
     error ("Memory access at 0x%X is out of bounds.", *pc);
533
     return SIGSEGV;
534
  }
535
 
536
  (void) (*read_fptr) (addr, &insn.raw);
537
 
538
  switch (insn.ldiop.op)
539
  {
540
    case OPC4_LDLI:
541
      regfile[insn.ldiop.reg] = insn.ldiop.val;
542
      break;
543
    case OPC4_LDHI:
544
      regfile[insn.ldiop.reg] &= 0xFF;
545
      regfile[insn.ldiop.reg] |= (int32_t) insn.ldiop.val << 8;
546
      assert(((regfile[insn.ldiop.reg] & 0xFFFF8000) == 0xFFFF8000) || ((regfile[insn.ldiop.reg] & 0xFFFF8000) == 0));
547
      break;
548
    case OPC4_LDLIU:
549
      regfile[insn.ldiop.reg] &= 0xFFFFFF00;
550
      regfile[insn.ldiop.reg] |= insn.ldiop.val & 0xFF;
551
      break;
552
    default:
553
      decode_steps++;
554
  }
555
 
556
  switch (insn.imm7op.op)
557
  {
558
    case OPC5_CMPI_LT:
559
      cond = ((int32_t) regfile[insn.imm7op.reg] < (int32_t) insn.imm7op.val);
560
      break;
561
    case OPC5_CMPI_GT:
562
      cond = ((int32_t) regfile[insn.imm7op.reg] > (int32_t) insn.imm7op.val);
563
      break;
564
    case OPC5_CMPI_EQ:
565
      cond = ((int32_t) regfile[insn.imm7op.reg] == (int32_t) insn.imm7op.val);
566
      break;
567
    default:
568
      decode_steps++;
569
  }
570
 
571
  switch (insn.imm6op.op)
572
  {
573
    case OPC6_LDFPW:
574
      if (result = load_data (PROC_CTRL_FPW + SCARTS_WORD_SIZE * insn.imm6op.val, &data, WORD))
575
        break;
576
 
577
      regfile[insn.imm6op.reg] = data;
578
      break;
579
    case OPC6_LDFPX:
580
      if (result = load_data (PROC_CTRL_FPX + SCARTS_WORD_SIZE * insn.imm6op.val, &data, WORD))
581
        break;
582
 
583
      regfile[insn.imm6op.reg] = data;
584
      break;
585
    case OPC6_LDFPY:
586
      if (result = load_data (PROC_CTRL_FPY + SCARTS_WORD_SIZE * insn.imm6op.val, &data, WORD))
587
        break;
588
 
589
      regfile[insn.imm6op.reg] = data;
590
      break;
591
    case OPC6_LDFPZ:
592
      if (result = load_data (PROC_CTRL_FPZ + SCARTS_WORD_SIZE * insn.imm6op.val, &data, WORD))
593
        break;
594
 
595
      regfile[insn.imm6op.reg] = data;
596
      break;
597
    case OPC6_STFPW:
598
      result = store_data (PROC_CTRL_FPW + SCARTS_WORD_SIZE * insn.imm6op.val, regfile[insn.imm6op.reg], WORD);
599
      break;
600
    case OPC6_STFPX:
601
      result = store_data (PROC_CTRL_FPX + SCARTS_WORD_SIZE * insn.imm6op.val, regfile[insn.imm6op.reg], WORD);
602
      break;
603
    case OPC6_STFPY:
604
      result = store_data (PROC_CTRL_FPY + SCARTS_WORD_SIZE * insn.imm6op.val, regfile[insn.imm6op.reg], WORD);
605
      break;
606
    case OPC6_STFPZ:
607
      result = store_data (PROC_CTRL_FPZ + SCARTS_WORD_SIZE * insn.imm6op.val, regfile[insn.imm6op.reg], WORD);
608
      break;
609
    case OPC6_ADDI:
610
      carry = ((int64_t) regfile[insn.imm6op.reg] + (int64_t) insn.imm6op.val) >> 32;
611
      regfile[insn.imm6op.reg] += insn.imm6op.val;
612
      break;
613
    case OPC6_ADDI_CT:
614
      if (cond)
615
      {
616
        carry = ((int64_t) regfile[insn.imm6op.reg] + (int64_t) insn.imm6op.val) >> 32;
617
        regfile[insn.imm6op.reg] += insn.imm6op.val;
618
      }
619
      break;
620
    case OPC6_ADDI_CF:
621
      if (!cond)
622
      {
623
        carry = ((int64_t) regfile[insn.imm6op.reg] + (int64_t) insn.imm6op.val) >> 32;
624
        regfile[insn.imm6op.reg] += insn.imm6op.val;
625
      }
626
      break;
627
    default:
628
      decode_steps++;
629
  }
630
 
631
  switch (insn.imm5op.op)
632
  {
633
    case OPC7_LDFPW_INC:
634
      if (result = load_data (PROC_CTRL_FPW + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
635
        break;
636
 
637
      regfile[insn.imm5op.reg] = data;
638
      PROC_CTRL_FPW += SCARTS_WORD_SIZE;
639
      break;
640
    case OPC7_LDFPW_DEC:
641
      if (result = load_data (PROC_CTRL_FPW + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
642
        break;
643
 
644
      regfile[insn.imm5op.reg] = data;
645
      PROC_CTRL_FPW -= SCARTS_WORD_SIZE;
646
      break;
647
    case OPC7_LDFPX_INC:
648
      if (result = load_data (PROC_CTRL_FPX + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
649
        break;
650
 
651
      regfile[insn.imm5op.reg] = data;
652
      PROC_CTRL_FPX += SCARTS_WORD_SIZE;
653
      break;
654
    case OPC7_LDFPX_DEC:
655
      if (result = load_data (PROC_CTRL_FPX + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
656
        break;
657
 
658
      regfile[insn.imm5op.reg] = data;
659
      PROC_CTRL_FPX -= SCARTS_WORD_SIZE;
660
      break;
661
    case OPC7_LDFPY_INC:
662
      if (result = load_data (PROC_CTRL_FPY + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
663
        break;
664
 
665
      regfile[insn.imm5op.reg] = data;
666
      PROC_CTRL_FPY += SCARTS_WORD_SIZE;
667
      break;
668
    case OPC7_LDFPY_DEC:
669
      if (result = load_data (PROC_CTRL_FPY + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
670
        break;
671
 
672
      regfile[insn.imm5op.reg] = data;
673
      PROC_CTRL_FPY -= SCARTS_WORD_SIZE;
674
      break;
675
    case OPC7_LDFPZ_INC:
676
      if (result = load_data (PROC_CTRL_FPZ + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
677
        break;
678
 
679
      regfile[insn.imm5op.reg] = data;
680
      PROC_CTRL_FPZ += SCARTS_WORD_SIZE;
681
      break;
682
    case OPC7_LDFPZ_DEC:
683
      if (result = load_data (PROC_CTRL_FPZ + SCARTS_WORD_SIZE * insn.imm5op.val, &data, WORD))
684
        break;
685
 
686
      regfile[insn.imm5op.reg] = data;
687
      PROC_CTRL_FPZ -= SCARTS_WORD_SIZE;
688
      break;
689
    case OPC7_STFPW_INC:
690
      if (result = store_data (PROC_CTRL_FPW + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
691
        break;
692
 
693
      PROC_CTRL_FPW += SCARTS_WORD_SIZE;
694
      break;
695
    case OPC7_STFPW_DEC:
696
      if (result = store_data (PROC_CTRL_FPW + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
697
        break;
698
 
699
      PROC_CTRL_FPW -= SCARTS_WORD_SIZE;
700
      break;
701
    case OPC7_STFPX_INC:
702
      if (result = store_data (PROC_CTRL_FPX + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
703
        break;
704
 
705
      PROC_CTRL_FPX += SCARTS_WORD_SIZE;
706
      break;
707
    case OPC7_STFPX_DEC:
708
      if (result = store_data (PROC_CTRL_FPX + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
709
        break;
710
 
711
      PROC_CTRL_FPX -= SCARTS_WORD_SIZE;
712
    case OPC7_STFPY_INC:
713
      if (result = store_data (PROC_CTRL_FPY + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
714
        break;
715
 
716
      PROC_CTRL_FPY += SCARTS_WORD_SIZE;
717
      break;
718
    case OPC7_STFPY_DEC:
719
      if (result = store_data (PROC_CTRL_FPY + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
720
        break;
721
 
722
      PROC_CTRL_FPY -= SCARTS_WORD_SIZE;
723
      break;
724
    case OPC7_STFPZ_INC:
725
      if (result = store_data (PROC_CTRL_FPZ + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
726
        break;
727
 
728
      PROC_CTRL_FPZ += SCARTS_WORD_SIZE;
729
      break;
730
    case OPC7_STFPZ_DEC:
731
      if (result = store_data (PROC_CTRL_FPZ + SCARTS_WORD_SIZE * insn.imm5op.val, regfile[insn.imm5op.reg], WORD))
732
        break;
733
 
734
      PROC_CTRL_FPZ -= SCARTS_WORD_SIZE;
735
      break;
736
    case OPC7_BSET:
737
      regfile[insn.imm5op.reg] |= 1 << (uint32_t) insn.imm5op.val;
738
      break;
739
    case OPC7_BCLR:
740
      regfile[insn.imm5op.reg] &= ~(1 << (uint32_t) insn.imm5op.val);
741
      break;
742
    case OPC7_BSET_CT:
743
      if (cond)
744
      {
745
        regfile[insn.imm5op.reg] |= 1 << (uint32_t) insn.imm5op.val;
746
      }
747
      break;
748
    case OPC7_BCLR_CT:
749
      if (cond)
750
      {
751
        regfile[insn.imm5op.reg] &= ~(1 << (uint32_t) insn.imm5op.val);
752
      }
753
      break;
754
    case OPC7_BSET_CF:
755
      if (!cond)
756
      {
757
        regfile[insn.imm5op.reg] |= 1 << (uint32_t) insn.imm5op.val;
758
      }
759
      break;
760
    case OPC7_BCLR_CF:
761
      if (!cond)
762
      {
763
        regfile[insn.imm5op.reg] &= ~(1 << (uint32_t) insn.imm5op.val);
764
      }
765
      break;
766
    case OPC7_BTEST:
767
      cond = ((regfile[insn.imm5op.reg] & (1 << (uint32_t) insn.imm5op.val)) != 0);
768
      break;
769
    case OPC7_STVEC:
770
      vectab[insn.imm5op.val + 16] = regfile[insn.imm5op.reg];
771
      break;
772
    case OPC7_LDVEC:
773
      regfile[insn.imm5op.reg] = vectab[insn.imm5op.val + 16];
774
      break;
775
    default:
776
      decode_steps++;
777
  }
778
 
779
  switch (insn.imm4op.op)
780
  {
781
    case OPC8_SLI:
782
      carry = (regfile[insn.imm4op.reg] >> (32 - (uint32_t) insn.imm4op.val)) & 1;
783
      regfile[insn.imm4op.reg] <<= (uint32_t) insn.imm4op.val;
784
      break;
785
    case OPC8_SRI:
786
      carry = regfile[insn.imm4op.reg] & (1 << ((uint32_t) insn.imm4op.val - 1));
787
      regfile[insn.imm4op.reg] >>= (uint32_t) insn.imm4op.val;
788
      break;
789
    case OPC8_SRAI:
790
      carry = regfile[insn.imm4op.reg] & (1 << ((uint32_t) insn.imm4op.val - 1));
791
      regfile[insn.imm4op.reg] = (int32_t) regfile[insn.imm4op.reg] >> (uint32_t) insn.imm4op.val;
792
      break;
793
    case OPC8_TRAP:
794
      regfile[SCARTS_RTE_REGNUM] = *pc + SCARTS_INSN_SIZE;
795
      next_pc = vectab[insn.imm4op.val + 16] - SCARTS_INSN_SIZE;
796
      break;
797
    case OPC8_SLI_CT:
798
      if (cond)
799
      {
800
        carry = (regfile[insn.imm4op.reg] >> (32 - (uint32_t) insn.imm4op.val)) & 1;
801
        regfile[insn.imm4op.reg] <<= (uint32_t) insn.imm4op.val;
802
      }
803
      break;
804
    case OPC8_SRI_CT:
805
      if (cond)
806
      {
807
        carry = regfile[insn.imm4op.reg] & (1 << ((uint32_t) insn.imm4op.val - 1));
808
        regfile[insn.imm4op.reg] >>= (uint32_t) insn.imm4op.val;
809
      }
810
      break;
811
    case OPC8_SRAI_CT:
812
      if (cond)
813
      {
814
        carry = regfile[insn.imm4op.reg] & (1 << ((uint32_t) insn.imm4op.val - 1));
815
        regfile[insn.imm4op.reg] = (int32_t) regfile[insn.imm4op.reg] >> (uint32_t) insn.imm4op.val;
816
      }
817
      break;
818
    case OPC8_TRAP_CT:
819
      if (cond)
820
      {
821
        regfile[SCARTS_RTE_REGNUM] = *pc + SCARTS_INSN_SIZE;
822
        next_pc = vectab[insn.imm4op.val + 16] - SCARTS_INSN_SIZE;
823
      }
824
      break;
825
    case OPC8_SLI_CF:
826
      if (!cond)
827
      {
828
        carry = (regfile[insn.imm4op.reg] >> (32 - (uint32_t) insn.imm4op.val)) & 1;
829
        regfile[insn.imm4op.reg] <<= (uint32_t) insn.imm4op.val;
830
      }
831
      break;
832
    case OPC8_SRI_CF:
833
      if (!cond)
834
      {
835
        carry = regfile[insn.imm4op.reg] & (1 << ((uint32_t) insn.imm4op.val - 1));
836
        regfile[insn.imm4op.reg] >>= (uint32_t) insn.imm4op.val;
837
      }
838
      break;
839
    case OPC8_SRAI_CF:
840
      if (!cond)
841
      {
842
        carry = regfile[insn.imm4op.reg] & (1 << ((uint32_t) insn.imm4op.val - 1));
843
        regfile[insn.imm4op.reg] = (int32_t) regfile[insn.imm4op.reg] >> (uint32_t) insn.imm4op.val;
844
      }
845
      break;
846
    case OPC8_TRAP_CF:
847
      if (!cond)
848
      {
849
        regfile[SCARTS_RTE_REGNUM] = *pc + SCARTS_INSN_SIZE;
850
        next_pc = vectab[insn.imm4op.val + 16] - SCARTS_INSN_SIZE;
851
      }
852
      break;
853
    default:
854
      decode_steps++;
855
  }
856
 
857
  switch (insn.binop.op)
858
  {
859
    case OPC8_SL:
860
      carry = (regfile[insn.binop.reg1] >> (32 - regfile[insn.binop.reg2])) & 1;
861
      regfile[insn.binop.reg1] <<= regfile[insn.binop.reg2];
862
      break;
863
    case OPC8_SR:
864
      carry = regfile[insn.binop.reg1] & (1 << (regfile[insn.binop.reg2] - 1));
865
      regfile[insn.binop.reg1] >>= regfile[insn.binop.reg2];
866
      break;
867
    case OPC8_SRA:
868
      carry = regfile[insn.binop.reg1] & (1 << (regfile[insn.binop.reg2] - 1));
869
      regfile[insn.binop.reg1] = (int32_t) regfile[insn.binop.reg1] >> regfile[insn.binop.reg2];
870
      break;
871
    case OPC8_SL_CT:
872
      if (cond)
873
      {
874
        carry = (regfile[insn.binop.reg1] >> (32 - regfile[insn.binop.reg2])) & 1;
875
        regfile[insn.binop.reg1] <<= regfile[insn.binop.reg2];
876
      }
877
      break;
878
    case OPC8_SR_CT:
879
      if (cond)
880
      {
881
        carry = regfile[insn.binop.reg1] & (1 << (regfile[insn.binop.reg2] - 1));
882
        regfile[insn.binop.reg1] >>= regfile[insn.binop.reg2];
883
      }
884
      break;
885
    case OPC8_SRA_CT:
886
      if (cond)
887
      {
888
        carry = regfile[insn.binop.reg1] & (1 << (regfile[insn.binop.reg2] - 1));
889
        regfile[insn.binop.reg1] = (int32_t) regfile[insn.binop.reg1] >> regfile[insn.binop.reg2];
890
      }
891
      break;
892
    case OPC8_SL_CF:
893
      if (!cond)
894
      {
895
        carry = (regfile[insn.binop.reg1] >> (32 - regfile[insn.binop.reg2])) & 1;
896
        regfile[insn.binop.reg1] <<= regfile[insn.binop.reg2];
897
      }
898
      break;
899
    case OPC8_SR_CF:
900
      if (!cond)
901
      {
902
        carry = regfile[insn.binop.reg1] & (1 << (regfile[insn.binop.reg2] - 1));
903
        regfile[insn.binop.reg1] >>= regfile[insn.binop.reg2];
904
      }
905
      break;
906
    case OPC8_SRA_CF:
907
      if (!cond)
908
      {
909
        carry = regfile[insn.binop.reg1] & (1 << (regfile[insn.binop.reg2] - 1));
910
        regfile[insn.binop.reg1] = (int32_t) regfile[insn.binop.reg1] >> regfile[insn.binop.reg2];
911
      }
912
      break;
913
    case OPC8_CMP_EQ:
914
      cond = (regfile[insn.binop.reg1] == regfile[insn.binop.reg2]);
915
      break;
916
    case OPC8_CMP_LT:
917
      cond = ((int32_t) regfile[insn.binop.reg1] < (int32_t) regfile[insn.binop.reg2]);
918
      break;
919
    case OPC8_CMP_GT:
920
      cond = ((int32_t) regfile[insn.binop.reg1] > (int32_t) regfile[insn.binop.reg2]);
921
      break;
922
    case OPC8_CMPU_LT:
923
      cond = ((uint32_t) regfile[insn.binop.reg1] < (uint32_t) regfile[insn.binop.reg2]);
924
      break;
925
    case OPC8_CMPU_GT:
926
      cond = ((uint32_t) regfile[insn.binop.reg1] > (uint32_t) regfile[insn.binop.reg2]);
927
      break;
928
    case OPC8_MOV:
929
      regfile[insn.binop.reg1] = regfile[insn.binop.reg2];
930
      break;
931
    case OPC8_ADD:
932
      carry = ((int64_t) regfile[insn.binop.reg1] + (int64_t) regfile[insn.binop.reg2]) >> 32;
933
      regfile[insn.binop.reg1] += regfile[insn.binop.reg2];
934
      break;
935
    case OPC8_ADDC:
936
      old_carry = carry;
937
      carry = ((int64_t) regfile[insn.binop.reg1] + (int64_t) regfile[insn.binop.reg2] + old_carry) >> 32;
938
      regfile[insn.binop.reg1] += regfile[insn.binop.reg2] + old_carry;
939
      break;
940
    case OPC8_SUB:
941
      carry = ((int64_t) regfile[insn.binop.reg1] - (int64_t) regfile[insn.binop.reg2]) >> 32;
942
      regfile[insn.binop.reg1] -= regfile[insn.binop.reg2];
943
      break;
944
    case OPC8_SUBC:
945
      old_carry = carry;
946
      carry = ((int64_t) regfile[insn.binop.reg1] - (int64_t) regfile[insn.binop.reg2] - old_carry) >> 32;
947
      regfile[insn.binop.reg1] -= regfile[insn.binop.reg2] + old_carry;
948
      break;
949
    case OPC8_AND:
950
      regfile[insn.binop.reg1] &= regfile[insn.binop.reg2];
951
      break;
952
    case OPC8_OR:
953
      regfile[insn.binop.reg1] |= regfile[insn.binop.reg2];
954
      break;
955
    case OPC8_EOR:
956
      regfile[insn.binop.reg1] ^= regfile[insn.binop.reg2];
957
      break;
958
    case OPC8_MOV_CT:
959
      if (cond)
960
      {
961
        regfile[insn.binop.reg1] = regfile[insn.binop.reg2];
962
      }
963
      break;
964
    case OPC8_ADD_CT:
965
      if (cond)
966
      {
967
        carry = ((int64_t) regfile[insn.binop.reg1] + (int64_t) regfile[insn.binop.reg2]) >> 32;
968
        regfile[insn.binop.reg1] += regfile[insn.binop.reg2];
969
      }
970
      break;
971
    case OPC8_ADDC_CT:
972
      if (cond)
973
      {
974
        old_carry = carry;
975
        carry = ((int64_t) regfile[insn.binop.reg1] + (int64_t) regfile[insn.binop.reg2] + old_carry) >> 32;
976
        regfile[insn.binop.reg1] += regfile[insn.binop.reg2] + old_carry;
977
      }
978
      break;
979
    case OPC8_SUB_CT:
980
      if (cond)
981
      {
982
        carry = ((int64_t) regfile[insn.binop.reg1] - (int64_t) regfile[insn.binop.reg2]) >> 32;
983
        regfile[insn.binop.reg1] -= regfile[insn.binop.reg2];
984
      }
985
      break;
986
    case OPC8_SUBC_CT:
987
      if (cond)
988
      {
989
        old_carry = carry;
990
        carry = ((int64_t) regfile[insn.binop.reg1] - (int64_t) regfile[insn.binop.reg2] - old_carry) >> 32;
991
        regfile[insn.binop.reg1] -= regfile[insn.binop.reg2] + old_carry;
992
      }
993
      break;
994
    case OPC8_AND_CT:
995
      if (cond)
996
      {
997
        regfile[insn.binop.reg1] &= regfile[insn.binop.reg2];
998
      }
999
      break;
1000
    case OPC8_OR_CT:
1001
      if (cond)
1002
      {
1003
        regfile[insn.binop.reg1] |= regfile[insn.binop.reg2];
1004
      }
1005
      break;
1006
    case OPC8_EOR_CT:
1007
      if (cond)
1008
      {
1009
        regfile[insn.binop.reg1] ^= regfile[insn.binop.reg2];
1010
      }
1011
      break;
1012
    case OPC8_MOV_CF:
1013
      if (!cond)
1014
      {
1015
        regfile[insn.binop.reg1] = regfile[insn.binop.reg2];
1016
      }
1017
      break;
1018
    case OPC8_ADD_CF:
1019
      if (!cond)
1020
      {
1021
        carry = ((int64_t) regfile[insn.binop.reg1] + (int64_t) regfile[insn.binop.reg2]) >> 32;
1022
        regfile[insn.binop.reg1] += regfile[insn.binop.reg2];
1023
      }
1024
      break;
1025
    case OPC8_ADDC_CF:
1026
      if (!cond)
1027
      {
1028
        old_carry = carry;
1029
        carry = ((int64_t) regfile[insn.binop.reg1] + (int64_t) regfile[insn.binop.reg2] + old_carry) >> 32;
1030
        regfile[insn.binop.reg1] += regfile[insn.binop.reg2] + old_carry;
1031
      }
1032
      break;
1033
    case OPC8_SUB_CF:
1034
      if (!cond)
1035
      {
1036
        carry = ((int64_t)regfile[insn.binop.reg1] - (int64_t)regfile[insn.binop.reg2]) >> 32;
1037
        regfile[insn.binop.reg1] -= regfile[insn.binop.reg2];
1038
      }
1039
      break;
1040
    case OPC8_SUBC_CF:
1041
      if (!cond)
1042
      {
1043
        old_carry = carry;
1044
        carry = ((int64_t) regfile[insn.binop.reg1] - (int64_t) regfile[insn.binop.reg2] - old_carry) >> 32;
1045
        regfile[insn.binop.reg1] -= regfile[insn.binop.reg2] + old_carry;
1046
      }
1047
      break;
1048
    case OPC8_AND_CF:
1049
      if (!cond)
1050
      {
1051
        regfile[insn.binop.reg1] &= regfile[insn.binop.reg2];
1052
      }
1053
      break;
1054
    case OPC8_OR_CF:
1055
      if (!cond)
1056
      {
1057
        regfile[insn.binop.reg1] |= regfile[insn.binop.reg2];
1058
      }
1059
      break;
1060
    case OPC8_EOR_CF:
1061
      if (!cond)
1062
      {
1063
        regfile[insn.binop.reg1] ^= regfile[insn.binop.reg2];
1064
      }
1065
      break;
1066
    case OPC8_LDW:
1067
      if (result = load_data (regfile[insn.binop.reg2], &data, WORD))
1068
        break;
1069
 
1070
      regfile[insn.binop.reg1] = data;
1071
      break;
1072
    case OPC8_LDH:
1073
      if (result = load_data (regfile[insn.binop.reg2], &data, HWORD))
1074
        break;
1075
 
1076
      regfile[insn.binop.reg1] = data;
1077
      break;
1078
    case OPC8_LDHU:
1079
      if (result = load_data (regfile[insn.binop.reg2], &data, HWORDU))
1080
        break;
1081
 
1082
      regfile[insn.binop.reg1] = data;
1083
      break;
1084
    case OPC8_LDB:
1085
      if (result = load_data (regfile[insn.binop.reg2], &data, BYTE))
1086
        break;
1087
 
1088
      regfile[insn.binop.reg1] = data;
1089
      break;
1090
    case OPC8_LDBU:
1091
      if (result = load_data (regfile[insn.binop.reg2], &data, BYTEU))
1092
        break;
1093
 
1094
      regfile[insn.binop.reg1] = data;
1095
      break;
1096
    case OPC8_STW:
1097
      result = store_data (regfile[insn.binop.reg2], regfile[insn.binop.reg1], WORD);
1098
      break;
1099
    case OPC8_STH:
1100
      result = store_data (regfile[insn.binop.reg2], regfile[insn.binop.reg1], HWORD);
1101
      break;
1102
    case OPC8_STB:
1103
      result = store_data (regfile[insn.binop.reg2], regfile[insn.binop.reg1], BYTE);
1104
      break;
1105
    default:
1106
      decode_steps++;
1107
  }
1108
 
1109
  switch (insn.jmpiop.op)
1110
  {
1111
    case OPC6_JMPI:
1112
      next_pc += (insn.jmpiop.dest * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1113
      break;
1114
    case OPC6_JMPI_CT:
1115
      if (cond)
1116
      {
1117
        next_pc += (insn.jmpiop.dest * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1118
      }
1119
      break;
1120
    case OPC6_JMPI_CF:
1121
      if (!cond)
1122
      {
1123
        next_pc += (insn.jmpiop.dest * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1124
      }
1125
      break;
1126
    default:
1127
      decode_steps++;
1128
  }
1129
 
1130
  switch (insn.unop.op)
1131
  {
1132
    case OPC12_RRC:
1133
      old_carry = carry;
1134
      carry = regfile[insn.unop.reg] & 1;
1135
      regfile[insn.unop.reg] >>= 1;
1136
      regfile[insn.unop.reg] |= old_carry << 31;
1137
      break;
1138
    case OPC12_NOT:
1139
      regfile[insn.unop.reg] = ~regfile[insn.unop.reg];
1140
      break;
1141
    case OPC12_NEG:
1142
      regfile[insn.unop.reg] = -regfile[insn.unop.reg];
1143
      break;
1144
    case OPC12_JSR:
1145
      regfile[SCARTS_RTS_REGNUM] = *pc + SCARTS_INSN_SIZE;
1146
      next_pc = (regfile[insn.unop.reg] * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1147
      break;
1148
    case OPC12_JMP:
1149
      next_pc = (regfile[insn.unop.reg] * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1150
      break;
1151
    case OPC12_RRC_CT:
1152
      if (cond)
1153
      {
1154
        old_carry = carry;
1155
        carry = regfile[insn.unop.reg] & 1;
1156
        regfile[insn.unop.reg] >>= 1;
1157
        regfile[insn.unop.reg] |= old_carry << 31;
1158
      }
1159
      break;
1160
    case OPC12_NOT_CT:
1161
      if (cond)
1162
      {
1163
        regfile[insn.unop.reg] = ~regfile[insn.unop.reg];
1164
      }
1165
      break;
1166
    case OPC12_NEG_CT:
1167
      if (cond)
1168
      {
1169
        regfile[insn.unop.reg] = -regfile[insn.unop.reg];
1170
      }
1171
      break;
1172
    case OPC12_JSR_CT:
1173
      if (cond)
1174
      {
1175
        regfile[SCARTS_RTS_REGNUM] = *pc + SCARTS_INSN_SIZE;
1176
        next_pc = (regfile[insn.unop.reg] * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1177
      }
1178
      break;
1179
    case OPC12_JMP_CT:
1180
      if (cond)
1181
      {
1182
        next_pc = (regfile[insn.unop.reg] * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1183
      }
1184
      break;
1185
    case OPC12_RRC_CF:
1186
      if (!cond)
1187
      {
1188
        old_carry = carry;
1189
        carry = regfile[insn.unop.reg] & 1;
1190
        regfile[insn.unop.reg] >>= 1;
1191
        regfile[insn.unop.reg] |= old_carry << 31;
1192
      }
1193
      break;
1194
    case OPC12_NOT_CF:
1195
      if (!cond)
1196
      {
1197
        regfile[insn.unop.reg] = ~regfile[insn.unop.reg];
1198
      }
1199
      break;
1200
    case OPC12_NEG_CF:
1201
      if (!cond)
1202
      {
1203
        regfile[insn.unop.reg] = -regfile[insn.unop.reg];
1204
      }
1205
      break;
1206
    case OPC12_JSR_CF:
1207
      if (!cond)
1208
      {
1209
        regfile[SCARTS_RTS_REGNUM] = *pc + SCARTS_INSN_SIZE;
1210
        next_pc = (regfile[insn.unop.reg] * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1211
      }
1212
      break;
1213
    case OPC12_JMP_CF:
1214
      if (!cond)
1215
      {
1216
        next_pc = (regfile[insn.unop.reg] * SCARTS_INSN_SIZE) - SCARTS_INSN_SIZE;
1217
      }
1218
      break;
1219
    default:
1220
      decode_steps++;
1221
  }
1222
 
1223
  switch (insn.nulop.op)
1224
  {
1225
    case OPC16_RTS:
1226
      next_pc = regfile[SCARTS_RTS_REGNUM] - SCARTS_INSN_SIZE;
1227
      break;
1228
    case OPC16_RTE:
1229
      PROC_CTRL_CONFIG_C |= (1 << PROC_CTRL_CONFIG_C_GIE);
1230
      PROC_CTRL_STATUS_C = PROC_CTRL_SAVE_STATUS_C;
1231
      next_pc = regfile[SCARTS_RTS_REGNUM] - SCARTS_INSN_SIZE;
1232
      break;
1233
    case OPC16_NOP:
1234
      break;
1235
    case OPC16_ILLOP:
1236
      result = SIGILL;
1237
      break;
1238
    default:
1239
      decode_steps++;
1240
  }
1241
 
1242
  carry = (!!carry) & 1;
1243
 
1244
  /* Compute the PC. */
1245
  *pc = next_pc;
1246
  *pc += SCARTS_INSN_SIZE;
1247
 
1248
  if (decode_steps != 8)
1249
  {
1250
    error ("Error in decoder stage (PC: 0x%X)", *pc - SCARTS_INSN_SIZE);
1251
    exit (EXIT_FAILURE);
1252
  }
1253
 
1254
  return result;
1255
}
1256
 

powered by: WebSVN 2.1.0

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