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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [sim/] [sh/] [gencode.c] - Blame information for rev 578

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Simulator/Opcode generator for the Hitachi Super-H architecture.
2
 
3
   Written by Steve Chamberlain of Cygnus Support.
4
   sac@cygnus.com
5
 
6
   This file is part of SH sim
7
 
8
 
9
                THIS SOFTWARE IS NOT COPYRIGHTED
10
 
11
   Cygnus offers the following for use in the public domain.  Cygnus
12
   makes no warranty with regard to the software or it's performance
13
   and the user accepts the software "AS IS" with all faults.
14
 
15
   CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
16
   THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18
 
19
*/
20
 
21
/* This program generates the opcode table for the assembler and
22
   the simulator code
23
 
24
   -t           prints a pretty table for the assembler manual
25
   -s           generates the simulator code jump table
26
   -d           generates a define table
27
   -x           generates the simulator code switch statement
28
   default      used to generate the opcode tables
29
 
30
*/
31
 
32
#include <stdio.h>
33
 
34
#define MAX_NR_STUFF 42
35
 
36
typedef struct
37
{
38
  char *defs;
39
  char *refs;
40
  char *name;
41
  char *code;
42
  char *stuff[MAX_NR_STUFF];
43
  int index;
44
} op;
45
 
46
 
47
op tab[] =
48
{
49
 
50
  { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
51
    "R[n] += SEXT(i);",
52
    "if (i == 0) {",
53
    "  UNDEF(n); /* see #ifdef PARANOID */",
54
    "  break;",
55
    "}",
56
  },
57
  { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
58
    "R[n] += R[m];",
59
  },
60
 
61
  { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
62
    "ult = R[n] + T;",
63
    "SET_SR_T (ult < R[n]);",
64
    "R[n] = ult + R[m];",
65
    "SET_SR_T (T || (R[n] < ult));",
66
  },
67
 
68
  { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
69
    "ult = R[n] + R[m];",
70
    "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
71
    "R[n] = ult;",
72
  },
73
 
74
  { "0", "", "and #<imm>,R0", "11001001i8*1....",
75
    "R0 &= i;",
76
  },
77
  { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
78
    "R[n] &= R[m];",
79
  },
80
  { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
81
    "MA (1);",
82
    "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
83
  },
84
 
85
  { "", "", "bf <bdisp8>", "10001011i8p1....",
86
    "if (!T) {",
87
    "  SET_NIP (PC + 4 + (SEXT(i) * 2));",
88
    "  cycles += 2;",
89
    "}",
90
  },
91
 
92
  { "", "", "bf.s <bdisp8>", "10001111i8p1....",
93
    "if (!T) {",
94
    "  SET_NIP (PC + 4 + (SEXT (i) * 2));",
95
    "  cycles += 2;",
96
    "  Delay_Slot (PC + 2);",
97
    "}",
98
  },
99
 
100
  { "", "", "bra <bdisp12>", "1010i12.........",
101
    "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
102
    "cycles += 2;",
103
    "Delay_Slot (PC + 2);",
104
  },
105
 
106
  { "", "n", "braf <REG_N>", "0000nnnn00100011",
107
    "SET_NIP (PC + 4 + R[n]);",
108
    "cycles += 2;",
109
    "Delay_Slot (PC + 2);",
110
  },
111
 
112
  { "", "", "bsr <bdisp12>", "1011i12.........",
113
    "PR = PH2T (PC + 4);",
114
    "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
115
    "cycles += 2;",
116
    "Delay_Slot (PC + 2);",
117
  },
118
 
119
  { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
120
    "PR = PH2T (PC) + 4;",
121
    "SET_NIP (PC + 4 + R[n]);",
122
    "cycles += 2;",
123
    "Delay_Slot (PC + 2);",
124
  },
125
 
126
  { "", "", "bt <bdisp8>", "10001001i8p1....",
127
    "if (T) {",
128
    "  SET_NIP (PC + 4 + (SEXT (i) * 2));",
129
    "  cycles += 2;",
130
    "}",
131
  },
132
 
133
  { "", "", "bt.s <bdisp8>", "10001101i8p1....",
134
    "if (T) {",
135
    "  SET_NIP (PC + 4 + (SEXT (i) * 2));",
136
    "  cycles += 2;",
137
    "  Delay_Slot (PC + 2);",
138
    "}",
139
  },
140
 
141
  { "", "", "clrmac", "0000000000101000",
142
    "MACH = 0;",
143
    "MACL = 0;",
144
  },
145
 
146
  { "", "", "clrs", "0000000001001000",
147
    "SET_SR_S (0);",
148
  },
149
 
150
  { "", "", "clrt", "0000000000001000",
151
    "SET_SR_T (0);",
152
  },
153
 
154
  { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
155
    "SET_SR_T (R0 == SEXT (i));",
156
  },
157
  { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
158
    "SET_SR_T (R[n] == R[m]);",
159
  },
160
  { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
161
    "SET_SR_T (R[n] >= R[m]);",
162
  },
163
  { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
164
    "SET_SR_T (R[n] > R[m]);",
165
  },
166
  { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
167
    "SET_SR_T (UR[n] > UR[m]);",
168
  },
169
  { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
170
    "SET_SR_T (UR[n] >= UR[m]);",
171
  },
172
  { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
173
    "SET_SR_T (R[n] > 0);",
174
  },
175
  { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
176
    "SET_SR_T (R[n] >= 0);",
177
  },
178
  { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
179
    "ult = R[n] ^ R[m];",
180
    "SET_SR_T (((ult & 0xff000000) == 0)",
181
    "          | ((ult & 0xff0000) == 0)",
182
    "          | ((ult & 0xff00) == 0)",
183
    "          | ((ult & 0xff) == 0));",
184
  },
185
 
186
  { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
187
    "SET_SR_Q ((R[n] & sbit) != 0);",
188
    "SET_SR_M ((R[m] & sbit) != 0);",
189
    "SET_SR_T (M != Q);",
190
  },
191
 
192
  { "", "", "div0u", "0000000000011001",
193
    "SET_SR_M (0);",
194
    "SET_SR_Q (0);",
195
    "SET_SR_T (0);",
196
  },
197
 
198
  { "", "", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
199
    "div1 (R, m, n/*, T*/);",
200
  },
201
 
202
  { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
203
    "dmul (1/*signed*/, R[n], R[m]);",
204
  },
205
 
206
  { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
207
    "dmul (0/*unsigned*/, R[n], R[m]);",
208
  },
209
 
210
  { "n", "n", "dt <REG_N>", "0100nnnn00010000",
211
    "R[n]--;",
212
    "SET_SR_T (R[n] == 0);",
213
  },
214
 
215
  { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
216
    "R[n] = SEXT (R[m]);",
217
  },
218
  { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
219
    "R[n] = SEXTW (R[m]);",
220
  },
221
 
222
  { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
223
    "R[n] = (R[m] & 0xff);",
224
  },
225
  { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
226
    "R[n] = (R[m] & 0xffff);",
227
  },
228
 
229
  /* sh3e */
230
  { "", "", "fabs <FREG_N>", "1111nnnn01011101",
231
    "FP_UNARY (n, fabs);",
232
    "/* FIXME: FR(n) &= 0x7fffffff; */",
233
  },
234
 
235
  /* sh3e */
236
  { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
237
    "FP_OP (n, +, m);",
238
  },
239
 
240
  /* sh3e */
241
  { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
242
    "FP_CMP (n, ==, m);",
243
  },
244
  /* sh3e */
245
  { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
246
    "FP_CMP (n, >, m);",
247
  },
248
 
249
  /* sh4 */
250
  { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
251
    "if (! FPSCR_PR || n & 1)",
252
    "  RAISE_EXCEPTION (SIGILL);",
253
    "else",
254
    "{",
255
    "  union",
256
    "  {",
257
    "    int i;",
258
    "    float f;",
259
    "  } u;",
260
    "  u.f = DR(n);",
261
    "  FPUL = u.i;",
262
    "}",
263
  },
264
 
265
  /* sh4 */
266
  { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
267
    "if (! FPSCR_PR || n & 1)",
268
    "  RAISE_EXCEPTION (SIGILL);",
269
    "else",
270
    "{",
271
    "  union",
272
    "  {",
273
    "    int i;",
274
    "    float f;",
275
    "  } u;",
276
    "  u.i = FPUL;",
277
    "  SET_DR(n, u.f);",
278
    "}",
279
  },
280
 
281
  /* sh3e */
282
  { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
283
    "FP_OP (n, /, m);",
284
    "/* FIXME: check for DP and (n & 1) == 0? */",
285
  },
286
 
287
  /* sh4 */
288
  { "", "", "fipr <FV_M>,<FV_N>", "1111nnmm11101101",
289
    "/* FIXME: not implemented */",
290
    "RAISE_EXCEPTION (SIGILL);",
291
    "/* FIXME: check for DP and (n & 1) == 0? */",
292
  },
293
 
294
  /* sh3e */
295
  { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
296
    "SET_FR (n, (float)0.0);",
297
    "/* FIXME: check for DP and (n & 1) == 0? */",
298
  },
299
 
300
  /* sh3e */
301
  { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
302
    "SET_FR (n, (float)1.0);",
303
    "/* FIXME: check for DP and (n & 1) == 0? */",
304
  },
305
 
306
  /* sh3e */
307
  { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
308
    "  union",
309
    "  {",
310
    "    int i;",
311
    "    float f;",
312
    "  } u;",
313
    "  u.f = FR(n);",
314
    "  FPUL = u.i;",
315
  },
316
 
317
  /* sh3e */
318
  { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
319
    /* sh4 */
320
    "if (FPSCR_PR)",
321
    "  SET_DR (n, (double)FPUL);",
322
    "else",
323
    "{",
324
    "  SET_FR (n, (float)FPUL);",
325
    "}",
326
  },
327
 
328
  /* sh3e */
329
  { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
330
    "SET_FR (n, FR(m) * FR(0) + FR(n));",
331
    "/* FIXME: check for DP and (n & 1) == 0? */",
332
  },
333
 
334
  /* sh3e */
335
  { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
336
    /* sh4 */
337
    "if (FPSCR_SZ) {",
338
    "  int ni = XD_TO_XF (n);",
339
    "  int mi = XD_TO_XF (m);",
340
    "  SET_XF (ni + 0, XF (mi + 0));",
341
    "  SET_XF (ni + 1, XF (mi + 1));",
342
    "}",
343
    "else",
344
    "{",
345
    "  SET_FR (n, FR (m));",
346
    "}",
347
  },
348
  /* sh3e */
349
  { "", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
350
    /* sh4 */
351
    "if (FPSCR_SZ) {",
352
    "  MA (2);",
353
    "  WDAT (R[n], m);",
354
    "}",
355
    "else",
356
    "{",
357
    "  MA (1);",
358
    "  WLAT (R[n], FI(m));",
359
    "}",
360
  },
361
  /* sh3e */
362
  { "", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
363
    /* sh4 */
364
    "if (FPSCR_SZ) {",
365
    "  MA (2);",
366
    "  RDAT (R[m], n);",
367
    "}",
368
    "else",
369
    "{",
370
    "  MA (1);",
371
    "  SET_FI(n, RLAT(R[m]));",
372
    "}",
373
  },
374
  /* sh3e */
375
  { "", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
376
    /* sh4 */
377
    "if (FPSCR_SZ) {",
378
    "  MA (2);",
379
    "  RDAT (R[m], n);",
380
    "  R[m] += 8;",
381
    "}",
382
    "else",
383
    "{",
384
    "  MA (1);",
385
    "  SET_FI (n, RLAT (R[m]));",
386
    "  R[m] += 4;",
387
    "}",
388
  },
389
  /* sh3e */
390
  { "", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
391
    /* sh4 */
392
    "if (FPSCR_SZ) {",
393
    "  MA (2);",
394
    "  R[n] -= 8;",
395
    "  WDAT (R[n], m);",
396
    "}",
397
    "else",
398
    "{",
399
    "  MA (1);",
400
    "  R[n] -= 4;",
401
    "  WLAT (R[n], FI(m));",
402
    "}",
403
  },
404
  /* sh3e */
405
  { "", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
406
    /* sh4 */
407
    "if (FPSCR_SZ) {",
408
    "  MA (2);",
409
    "  RDAT (R[0]+R[m], n);",
410
    "}",
411
    "else",
412
    "{",
413
    "  MA (1);",
414
    "  SET_FI(n, RLAT(R[0] + R[m]));",
415
    "}",
416
  },
417
  /* sh3e */
418
  { "", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
419
    /* sh4 */
420
    "if (FPSCR_SZ) {",
421
    "  MA (2);",
422
    "  WDAT (R[0]+R[n], m);",
423
    "}",
424
    "else",
425
    "{",
426
    "  MA (1);",
427
    "  WLAT((R[0]+R[n]), FI(m));",
428
    "}",
429
  },
430
 
431
  /* sh4: See fmov instructions above for move to/from extended fp registers */
432
 
433
  /* sh3e */
434
  { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
435
    "FP_OP(n, *, m);",
436
  },
437
 
438
  /* sh3e */
439
  { "", "", "fneg <FREG_N>", "1111nnnn01001101",
440
    "FP_UNARY(n, -);",
441
  },
442
 
443
  /* sh4 */
444
  { "", "", "frchg", "1111101111111101",
445
    "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_FR);",
446
  },
447
 
448
  /* sh4 */
449
  { "", "", "fschg", "1111001111111101",
450
    "SET_FPSCR (GET_FPSCR() ^ FPSCR_MASK_SZ);",
451
  },
452
 
453
  /* sh3e */
454
  { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
455
    "FP_UNARY(n, sqrt);",
456
  },
457
 
458
  /* sh3e */
459
  { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
460
    "FP_OP(n, -, m);",
461
  },
462
 
463
  /* sh3e */
464
  { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
465
    /* sh4 */
466
    "if (FPSCR_PR) {",
467
    "  if (DR(n) != DR(n)) /* NaN */",
468
    "    FPUL = 0x80000000;",
469
    "  else",
470
    "    FPUL =  (int)DR(n);",
471
    "}",
472
    "else",
473
    "if (FR(n) != FR(n)) /* NaN */",
474
    "  FPUL = 0x80000000;",
475
    "else",
476
    "  FPUL = (int)FR(n);",
477
  },
478
 
479
  /* sh3e */
480
  { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
481
    "  union",
482
    "  {",
483
    "    int i;",
484
    "    float f;",
485
    "  } u;",
486
    "  u.i = FPUL;",
487
    "  SET_FR (n, u.f);",
488
  },
489
 
490
  { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
491
    "SET_NIP (PT2H (R[n]));",
492
    "cycles += 2;",
493
    "Delay_Slot (PC + 2);",
494
  },
495
 
496
  { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
497
    "PR = PH2T (PC + 4);",
498
    "if (~doprofile)",
499
    "  gotcall (PR, R[n]);",
500
    "SET_NIP (PT2H (R[n]));",
501
    "cycles += 2;",
502
    "Delay_Slot (PC + 2);",
503
  },
504
 
505
  { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
506
    "CREG (m) = R[n];",
507
    "/* FIXME: user mode */",
508
  },
509
  { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
510
    "SET_SR (R[n]);",
511
    "/* FIXME: user mode */",
512
  },
513
  { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
514
    "SET_MOD (R[n]);",
515
  },
516
#if 0
517
  { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
518
    "DBR = R[n];",
519
    "/* FIXME: user mode */",
520
  },
521
#endif
522
  { "", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
523
    "MA (1);",
524
    "CREG (m) = RLAT (R[n]);",
525
    "R[n] += 4;",
526
    "/* FIXME: user mode */",
527
  },
528
  { "", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
529
    "MA (1);",
530
    "SET_SR (RLAT (R[n]));",
531
    "R[n] += 4;",
532
    "/* FIXME: user mode */",
533
  },
534
  { "", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
535
    "MA (1);",
536
    "SET_MOD (RLAT (R[n]));",
537
    "R[n] += 4;",
538
  },
539
#if 0
540
  { "", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
541
    "MA (1);",
542
    "DBR = RLAT (R[n]);",
543
    "R[n] += 4;",
544
    "/* FIXME: user mode */",
545
  },
546
#endif
547
 
548
  /* sh-dsp */
549
  { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
550
    "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
551
  },
552
  { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
553
    "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
554
  },
555
 
556
  { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
557
    "SREG (m) = R[n];",
558
  },
559
  { "", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
560
    "MA (1);",
561
    "SREG (m) = RLAT(R[n]);",
562
    "R[n] += 4;",
563
  },
564
  /* sh3e / sh-dsp (lds <REG_N>,DSR) */
565
  { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
566
    "SET_FPSCR(R[n]);",
567
  },
568
  /* sh3e / sh-dsp (lds.l @<REG_N>+,DSR) */
569
  { "", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
570
    "MA (1);",
571
    "SET_FPSCR (RLAT(R[n]));",
572
    "R[n] += 4;",
573
  },
574
 
575
  { "", "", "ldtlb", "0000000000111000",
576
    "/* FIXME: XXX*/ abort();",
577
  },
578
 
579
  { "", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
580
    "trap (255,R0,memory,maskl,maskw, endianw);",
581
    "/* FIXME: mac.l support */",
582
  },
583
 
584
  { "", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
585
    "macw(R0,memory,n,m,endianw);",
586
  },
587
 
588
  { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
589
    "R[n] = SEXT(i);",
590
  },
591
  { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
592
    "R[n] = R[m];",
593
  },
594
 
595
  { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
596
    "MA (1);",
597
    "R0 = RSBAT (i + GBR);",
598
    "L (0);",
599
  },
600
  { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
601
    "MA (1);",
602
    "R0 = RSBAT (i + R[m]);",
603
    "L (0);",
604
  },
605
  { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
606
    "MA (1);",
607
    "R[n] = RSBAT (R0 + R[m]);",
608
    "L (n);",
609
  },
610
  { "n", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
611
    "MA (1);",
612
    "R[n] = RSBAT (R[m]);",
613
    "R[m] += 1;",
614
    "L (n);",
615
  },
616
  { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
617
    "MA (1);",
618
    "WBAT (R[n], R[m]);",
619
  },
620
  { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
621
    "MA (1);",
622
    "WBAT (i + GBR, R0);",
623
  },
624
  { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
625
    "MA (1);",
626
    "WBAT (i + R[m], R0);",
627
  },
628
  { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
629
    "MA (1);",
630
    "WBAT (R[n] + R0, R[m]);",
631
  },
632
  { "", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
633
    "MA (1);",
634
    "R[n] -= 1;",
635
    "WBAT (R[n], R[m]);",
636
  },
637
  { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
638
    "MA (1);",
639
    "R[n] = RSBAT (R[m]);",
640
    "L (n);",
641
  },
642
 
643
  { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
644
    "MA (1);",
645
    "R0 = RLAT (i + GBR);",
646
    "L (0);",
647
  },
648
  { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
649
    "MA (1);",
650
    "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
651
    "L (n);",
652
  },
653
  { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
654
    "MA (1);",
655
    "R[n] = RLAT (i + R[m]);",
656
    "L (n);",
657
  },
658
  { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
659
    "MA (1);",
660
    "R[n] = RLAT (R0 + R[m]);",
661
    "L (n);",
662
  },
663
  { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
664
    "MA (1);",
665
    "R[n] = RLAT (R[m]);",
666
    "R[m] += 4;",
667
    "L (n);",
668
  },
669
  { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
670
    "MA (1);",
671
    "R[n] = RLAT (R[m]);",
672
    "L (n);",
673
  },
674
  { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
675
    "MA (1);",
676
    "WLAT (i + GBR, R0);",
677
  },
678
  { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
679
    "MA (1);",
680
    "WLAT (i + R[n], R[m]);",
681
  },
682
  { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
683
    "MA (1);",
684
    "WLAT (R0 + R[n], R[m]);",
685
  },
686
  { "", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
687
    "MA (1) ;",
688
    "R[n] -= 4;",
689
    "WLAT (R[n], R[m]);",
690
  },
691
  { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
692
    "MA (1);",
693
    "WLAT (R[n], R[m]);",
694
  },
695
 
696
  { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
697
    "MA (1)",
698
    ";R0 = RSWAT (i + GBR);",
699
    "L (0);",
700
  },
701
  { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
702
    "MA (1);",
703
    "R[n] = RSWAT (PH2T (PC + 4 + i));",
704
    "L (n);",
705
  },
706
  { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
707
    "MA (1);",
708
    "R0 = RSWAT (i + R[m]);",
709
    "L (0);",
710
  },
711
  { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
712
    "MA (1);",
713
    "R[n] = RSWAT (R0 + R[m]);",
714
    "L (n);",
715
  },
716
  { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
717
    "MA (1);",
718
    "R[n] = RSWAT (R[m]);",
719
    "R[m] += 2;",
720
    "L (n);",
721
  },
722
  { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
723
    "MA (1);",
724
    "R[n] = RSWAT (R[m]);",
725
    "L (n);",
726
  },
727
  { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
728
    "MA (1);",
729
    "WWAT (i + GBR, R0);",
730
  },
731
  { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
732
    "MA (1);",
733
    "WWAT (i + R[m], R0);",
734
  },
735
  { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
736
    "MA (1);",
737
    "WWAT (R0 + R[n], R[m]);",
738
  },
739
  { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
740
    "MA (1);",
741
    "R[n] -= 2;",
742
    "WWAT (R[n], R[m]);",
743
  },
744
  { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
745
    "MA (1);",
746
    "WWAT (R[n], R[m]);",
747
  },
748
 
749
  { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
750
    "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
751
  },
752
 
753
  { "0", "", "movca.l @R0, <REG_N>", "0000nnnn11000011",
754
    "/* FIXME: Not implemented */",
755
    "RAISE_EXCEPTION (SIGILL);",
756
  },
757
 
758
  { "n", "", "movt <REG_N>", "0000nnnn00101001",
759
    "R[n] = T;",
760
  },
761
 
762
  { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
763
    "MACL = ((int)R[n]) * ((int)R[m]);",
764
  },
765
#if 0
766
  { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
767
    "MACL = R[n] * R[m];",
768
  },
769
#endif
770
 
771
  /* muls.w - see muls */
772
  { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
773
    "MACL = ((int)(short)R[n]) * ((int)(short)R[m]);",
774
  },
775
 
776
  /* mulu.w - see mulu */
777
  { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
778
    "MACL = (((unsigned int)(unsigned short)R[n])",
779
    "        * ((unsigned int)(unsigned short)R[m]));",
780
  },
781
 
782
  { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
783
    "R[n] = - R[m];",
784
  },
785
 
786
  { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
787
    "ult = -T;",
788
    "SET_SR_T (ult > 0);",
789
    "R[n] = ult - R[m];",
790
    "SET_SR_T (T || (R[n] > ult));",
791
  },
792
 
793
  { "", "", "nop", "0000000000001001",
794
    "/* nop */",
795
  },
796
 
797
  { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
798
    "R[n] = ~R[m];",
799
  },
800
 
801
  { "0", "", "ocbi @<REG_N>", "0000nnnn10010011",
802
    "/* FIXME: Not implemented */",
803
    "RAISE_EXCEPTION (SIGILL);",
804
  },
805
 
806
  { "0", "", "ocbp @<REG_N>", "0000nnnn10100011",
807
    "/* FIXME: Not implemented */",
808
    "RAISE_EXCEPTION (SIGILL);",
809
  },
810
 
811
  { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
812
    "RSBAT (R[n]); /* Take exceptions like byte load.  */",
813
    "/* FIXME: Cache not implemented */",
814
  },
815
 
816
  { "0", "", "or #<imm>,R0", "11001011i8*1....",
817
    "R0 |= i;",
818
  },
819
  { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
820
    "R[n] |= R[m];",
821
  },
822
  { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
823
    "MA (1);",
824
    "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
825
  },
826
 
827
  { "", "n", "pref @<REG_N>", "0000nnnn10000011",
828
    "/* Except for the effect on the cache - which is not simulated -",
829
    "   this is like a nop.  */",
830
  },
831
 
832
  { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
833
    "ult = R[n] < 0;",
834
    "R[n] = (R[n] << 1) | T;",
835
    "SET_SR_T (ult);",
836
  },
837
 
838
  { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
839
    "ult = R[n] & 1;",
840
    "R[n] = (UR[n] >> 1) | (T << 31);",
841
    "SET_SR_T (ult);",
842
  },
843
 
844
  { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
845
    "SET_SR_T (R[n] < 0);",
846
    "R[n] <<= 1;",
847
    "R[n] |= T;",
848
  },
849
 
850
  { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
851
    "SET_SR_T (R[n] & 1);",
852
    "R[n] = UR[n] >> 1;",
853
    "R[n] |= (T << 31);",
854
  },
855
 
856
  { "", "", "rte", "0000000000101011",
857
#if 0
858
    /* SH-[12] */
859
    "int tmp = PC;",
860
    "SET_NIP (PT2H (RLAT (R[15]) + 2));",
861
    "R[15] += 4;",
862
    "SET_SR (RLAT (R[15]) & 0x3f3);",
863
    "R[15] += 4;",
864
    "Delay_Slot (PC + 2);",
865
#else
866
    "SET_SR (SSR);",
867
    "SET_NIP (PT2H (SPC));",
868
    "cycles += 2;",
869
    "Delay_Slot (PC + 2);",
870
#endif
871
  },
872
 
873
  { "", "", "rts", "0000000000001011",
874
    "SET_NIP (PT2H (PR));",
875
    "cycles += 2;",
876
    "Delay_Slot (PC + 2);",
877
  },
878
 
879
  /* sh-dsp */
880
  { "", "n", "setrc <REG_N>", "0100nnnn00010100",
881
    "SET_RC (R[n]);",
882
  },
883
  { "", "n", "setrc #<imm>", "10000010i8*1....",
884
    /* It would be more realistic to let loop_start point to some static
885
       memory that contains an illegal opcode and then give a bus error when
886
       the loop is eventually encountered, but it seems not only simpler,
887
       but also more debugging-friendly to just catch the failure here.  */
888
    "if (BUSERROR (RS | RE, maskw))",
889
    "  RAISE_EXCEPTION (SIGILL);",
890
    "else {",
891
    "  SET_RC (i);",
892
    "  loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
893
    "  CHECK_INSN_PTR (insn_ptr);",
894
    "}",
895
  },
896
 
897
  { "", "", "sets", "0000000001011000",
898
    "SET_SR_S (1);",
899
  },
900
 
901
  { "", "", "sett", "0000000000011000",
902
    "SET_SR_T (1);",
903
  },
904
 
905
  { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
906
    "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));",
907
  },
908
 
909
  { "n", "n", "shal <REG_N>", "0100nnnn00100000",
910
    "SET_SR_T (R[n] < 0);",
911
    "R[n] <<= 1;",
912
  },
913
 
914
  { "n", "n", "shar <REG_N>", "0100nnnn00100001",
915
    "SET_SR_T (R[n] & 1);",
916
    "R[n] = R[n] >> 1;",
917
  },
918
 
919
  { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
920
    "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));",
921
  },
922
 
923
  { "n", "n", "shll <REG_N>", "0100nnnn00000000",
924
    "SET_SR_T (R[n] < 0);",
925
    "R[n] <<= 1;",
926
  },
927
 
928
  { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
929
    "R[n] <<= 2;",
930
  },
931
  { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
932
    "R[n] <<= 8;",
933
  },
934
  { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
935
    "R[n] <<= 16;",
936
  },
937
 
938
  { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
939
    "SET_SR_T (R[n] & 1);",
940
    "R[n] = UR[n] >> 1;",
941
  },
942
 
943
  { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
944
    "R[n] = UR[n] >> 2;",
945
  },
946
  { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
947
    "R[n] = UR[n] >> 8;",
948
  },
949
  { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
950
    "R[n] = UR[n] >> 16;",
951
  },
952
 
953
  { "", "", "sleep", "0000000000011011",
954
    "nip = PC;",
955
    "trap (0xc3, R0, memory, maskl, maskw, endianw);",
956
  },
957
 
958
  { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
959
    "R[n] = CREG (m);",
960
  },
961
 
962
#if 0
963
  { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
964
    "R[n] = SGR;",
965
  },
966
  { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
967
    "R[n] = DBR;",
968
  },
969
#endif
970
  { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
971
    "MA (1);",
972
    "R[n] -= 4;",
973
    "WLAT (R[n], CREG (m));",
974
  },
975
#if 0
976
  { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
977
    "MA (1);",
978
    "R[n] -= 4;",
979
    "WLAT (R[n], SGR);",
980
  },
981
  { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
982
    "MA (1);",
983
    "R[n] -= 4;",
984
    "WLAT (R[n], DBR);",
985
  },
986
#endif
987
 
988
  { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
989
    "R[n] = SREG (m);",
990
  },
991
  { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
992
    "MA (1);",
993
    "R[n] -= 4;",
994
    "WLAT (R[n], SREG (m));",
995
  },
996
 
997
  { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
998
    "R[n] -= R[m];",
999
  },
1000
 
1001
  { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1002
    "ult = R[n] - T;",
1003
    "SET_SR_T (ult > R[n]);",
1004
    "R[n] = ult - R[m];",
1005
    "SET_SR_T (T || (R[n] > ult));",
1006
  },
1007
 
1008
  { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1009
    "ult = R[n] - R[m];",
1010
    "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1011
    "R[n] = ult;",
1012
  },
1013
 
1014
  { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1015
    "R[n] = ((R[m] & 0xffff0000)",
1016
    "        | ((R[m] << 8) & 0xff00)",
1017
    "        | ((R[m] >> 8) & 0x00ff));",
1018
  },
1019
  { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1020
    "R[n] = (((R[m] << 16) & 0xffff0000)",
1021
    "        | ((R[m] >> 16) & 0x00ffff));",
1022
  },
1023
 
1024
  { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1025
    "MA (1);",
1026
    "ult = RBAT(R[n]);",
1027
    "SET_SR_T (ult == 0);",
1028
    "WBAT(R[n],ult|0x80);",
1029
  },
1030
 
1031
  { "0", "", "trapa #<imm>", "11000011i8*1....",
1032
#if 0
1033
    /* SH-[12] */
1034
    "long imm = 0xff & i;",
1035
    "if (i==0xc3)",
1036
    "  PC-=2;",
1037
    "if (i<20||i==34||i==0xc3)",
1038
    "  trap(i,R,memory,maskl,maskw,endianw);",
1039
    "else {",
1040
    "  R[15]-=4;",
1041
    "  WLAT(R[15],GET_SR());",
1042
    "  R[15]-=4;",
1043
    "  WLAT(R[15],PC+2);",
1044
    "  PC=RLAT(VBR+(imm<<2))-2;",
1045
    "}",
1046
#else
1047
    "if (i == 0xc3)",
1048
    "  {",
1049
    "    nip = PC;",
1050
    "    trap (i, R, memory, maskl, maskw,endianw);",
1051
    "  }",
1052
    "else if (i < 20 || i==34 || i==0xc3)",
1053
    "  trap (i, R, memory, maskl, maskw,endianw);",
1054
    "else if (!SR_BL) {",
1055
    "  /* FIXME: TRA = (imm << 2); */",
1056
    "  SSR = GET_SR();",
1057
    "  SPC = PH2T (PC + 2);",
1058
    "  SET_SR (GET_SR() | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1059
    "  /* FIXME: EXPEVT = 0x00000160; */",
1060
    "  SET_NIP (PT2H (VBR + 0x00000100));",
1061
    "}",
1062
#endif
1063
  },
1064
 
1065
  { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1066
    "SET_SR_T ((R[n] & R[m]) == 0);",
1067
  },
1068
  { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1069
    "SET_SR_T ((R0 & i) == 0);",
1070
  },
1071
  { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1072
    "MA (1);",
1073
    "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1074
  },
1075
 
1076
  { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1077
    "R0 ^= i;",
1078
  },
1079
  { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1080
    "R[n] ^= R[m];",
1081
  },
1082
  { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1083
    "MA (1);",
1084
    "ult = RBAT (GBR+R0);",
1085
    "ult ^= i;",
1086
    "WBAT (GBR + R0, ult);",
1087
  },
1088
 
1089
  { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1090
    "R[n] = (((R[n] >> 16) & 0xffff)",
1091
    "        | ((R[m] << 16) & 0xffff0000));",
1092
  },
1093
 
1094
#if 0
1095
  { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1096
    "divl(0,R[n],R[m]);",
1097
  },
1098
  { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1099
    "divl(0,R[n],R[m]);",
1100
  },
1101
#endif
1102
 
1103
  {0, 0}};
1104
 
1105
op movsxy_tab[] =
1106
{
1107
/* If this is disabled, the simulator speeds up by about 12% on a
1108
   450 MHz PIII - 9% with ACE_FAST.
1109
   Maybe we should have separate simulator loops?  */
1110
#if 1
1111
  { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1112
    "MA (1);",
1113
    "R[n] -= 2;",
1114
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1115
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1116
  },
1117
  { "", "n",  "movs.w @<REG_N>,<DSP_REG_M>",  "111101NNMMMM0100",
1118
    "MA (1);",
1119
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1120
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1121
  },
1122
  { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1123
    "MA (1);",
1124
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1125
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1126
    "R[n] += 2;",
1127
  },
1128
  { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1129
    "MA (1);",
1130
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1131
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1132
    "R[n] += R[8];",
1133
  },
1134
  { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1135
    "MA (1);",
1136
    "R[n] -= 2;",
1137
    "DSP_R (m) = RSWAT (R[n]);",
1138
  },
1139
  { "", "n",  "movs.w @<REG_N>,<DSP_GRD_M>",  "111101NNGGGG0100",
1140
    "MA (1);",
1141
    "DSP_R (m) = RSWAT (R[n]);",
1142
  },
1143
  { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1144
    "MA (1);",
1145
    "DSP_R (m) = RSWAT (R[n]);",
1146
    "R[n] += 2;",
1147
  },
1148
  { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1149
    "MA (1);",
1150
    "DSP_R (m) = RSWAT (R[n]);",
1151
    "R[n] += R[8];",
1152
  },
1153
  { "n", "n", "<DSP_REG_M>,movs.w @-<REG_N>", "111101NNMMMM0001",
1154
    "MA (1);",
1155
    "R[n] -= 2;",
1156
    "WWAT (R[n], DSP_R (m) >> 16);",
1157
  },
1158
  { "", "n",  "movs.w <DSP_REG_M>,@<REG_N>",  "111101NNMMMM0101",
1159
    "MA (1);",
1160
    "WWAT (R[n], DSP_R (m) >> 16);",
1161
  },
1162
  { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1163
    "MA (1);",
1164
    "WWAT (R[n], DSP_R (m) >> 16);",
1165
    "R[n] += 2;",
1166
  },
1167
  { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1168
    "MA (1);",
1169
    "WWAT (R[n], DSP_R (m) >> 16);",
1170
    "R[n] += R[8];",
1171
  },
1172
  { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1173
    "MA (1);",
1174
    "R[n] -= 2;",
1175
    "WWAT (R[n], SEXT (DSP_R (m)));",
1176
  },
1177
  { "", "n",  "movs.w <DSP_GRD_M>,@<REG_N>",  "111101NNGGGG0101",
1178
    "MA (1);",
1179
    "WWAT (R[n], SEXT (DSP_R (m)));",
1180
  },
1181
  { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1182
    "MA (1);",
1183
    "WWAT (R[n], SEXT (DSP_R (m)));",
1184
    "R[n] += 2;",
1185
  },
1186
  { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1187
    "MA (1);",
1188
    "WWAT (R[n], SEXT (DSP_R (m)));",
1189
    "R[n] += R[8];",
1190
  },
1191
  { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1192
    "MA (1);",
1193
    "R[n] -= 4;",
1194
    "DSP_R (m) = RLAT (R[n]);",
1195
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1196
  },
1197
  { "", "n",  "movs.l @<REG_N>,<DSP_REG_M>",  "111101NNMMMM0110",
1198
    "MA (1);",
1199
    "DSP_R (m) = RLAT (R[n]);",
1200
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1201
  },
1202
  { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1203
    "MA (1);",
1204
    "DSP_R (m) = RLAT (R[n]);",
1205
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1206
    "R[n] += 4;",
1207
  },
1208
  { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1209
    "MA (1);",
1210
    "DSP_R (m) = RLAT (R[n]);",
1211
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1212
    "R[n] += R[8];",
1213
  },
1214
  { "n", "n", "<DSP_REG_M>,movs.l @-<REG_N>", "111101NNMMMM0011",
1215
    "MA (1);",
1216
    "R[n] -= 4;",
1217
    "WLAT (R[n], DSP_R (m));",
1218
  },
1219
  { "", "n",  "movs.l <DSP_REG_M>,@<REG_N>",  "111101NNMMMM0111",
1220
    "MA (1);",
1221
    "WLAT (R[n], DSP_R (m));",
1222
  },
1223
  { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1224
    "MA (1);",
1225
    "WLAT (R[n], DSP_R (m));",
1226
    "R[n] += 4;",
1227
  },
1228
  { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1229
    "MA (1);",
1230
    "WLAT (R[n], DSP_R (m));",
1231
    "R[n] += R[8];",
1232
  },
1233
  { "n", "n", "<DSP_GRD_M>,movs.l @-<REG_N>", "111101NNGGGG0011",
1234
    "MA (1);",
1235
    "R[n] -= 4;",
1236
    "WLAT (R[n], SEXT (DSP_R (m)));",
1237
  },
1238
  { "", "n",  "movs.l <DSP_GRD_M>,@<REG_N>",  "111101NNGGGG0111",
1239
    "MA (1);",
1240
    "WLAT (R[n], SEXT (DSP_R (m)));",
1241
  },
1242
  { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1243
    "MA (1);",
1244
    "WLAT (R[n], SEXT (DSP_R (m)));",
1245
    "R[n] += 4;",
1246
  },
1247
  { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1248
    "MA (1);",
1249
    "WLAT (R[n], SEXT (DSP_R (m)));",
1250
    "R[n] += R[8];",
1251
  },
1252
  { "", "n", "movx.w @<REG_x>,<DSP_XX>",   "111100xxXX000100",
1253
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1254
    "iword &= 0xfd53; goto top;",
1255
  },
1256
  { "n", "n", "movx.w @<REG_x>+,<DSP_XX>", "111100xxXX001000",
1257
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1258
    "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1259
    "iword &= 0xfd53; goto top;",
1260
  },
1261
  { "n", "n8","movx.w @<REG_x>+REG_8,<DSP_XX>", "111100xxXX001000",
1262
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1263
    "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1264
    "iword &= 0xfd53; goto top;",
1265
  },
1266
  { "", "n", "movx.w <DSP_Aa>,@<REG_x>",   "111100xxaa100100",
1267
    "WWAT (R[n], DSP_R (m) >> 16);",
1268
    "iword &= 0xfd53; goto top;",
1269
  },
1270
  { "n", "n", "movx.w <DSP_Aa>,@<REG_x>+", "111100xxaa101000",
1271
    "WWAT (R[n], DSP_R (m) >> 16);",
1272
    "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1273
    "iword &= 0xfd53; goto top;",
1274
  },
1275
  { "n", "n8","movx.w <DSP_Aa>,@<REG_x>+REG_8","111100xxaa101000",
1276
    "WWAT (R[n], DSP_R (m) >> 16);",
1277
    "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1278
    "iword &= 0xfd53; goto top;",
1279
  },
1280
  { "", "n", "movy.w @<REG_y>,<DSP_YY>",   "111100yyYY000001",
1281
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1282
  },
1283
  { "n", "n", "movy.w @<REG_x>+,<DSP_YY>", "111100yyYY000010",
1284
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1285
    "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1286
  },
1287
  { "n", "n9","movy.w @<REG_x>+REG_9,<DSP_YY>", "111100yyYY000010",
1288
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1289
    "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1290
  },
1291
  { "", "n", "movy.w <DSP_Aa>,@<REG_x>",   "111100yyAA010001",
1292
    "WWAT (R[n], DSP_R (m) >> 16);",
1293
  },
1294
  { "n", "n", "movy.w <DSP_Aa>,@<REG_x>+", "111100yyAA010010",
1295
    "WWAT (R[n], DSP_R (m) >> 16);",
1296
    "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1297
  },
1298
  { "n", "n9", "movy.w <DSP_Aa>,@<REG_x>+REG_9", "111100yyAA010010",
1299
    "WWAT (R[n], DSP_R (m) >> 16);",
1300
    "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1301
  },
1302
  { "", "", "nopx nopy", "1111000000000000",
1303
    "/* nop */",
1304
  },
1305
  { "", "", "ppi", "1111100000000000",
1306
    "ppi_insn (RIAT (nip));",
1307
    "nip += 2;",
1308
    "iword &= 0xf7ff; goto top;",
1309
  },
1310
#endif
1311
  {0, 0}};
1312
 
1313
op ppi_tab[] =
1314
{
1315
  { "","", "pshl #<imm>,dz",    "00000iiim16.zzzz",
1316
    "int Sz = DSP_R (z) & 0xffff0000;",
1317
    "",
1318
    "if (i < 16)",
1319
    "  res = Sz << i;",
1320
    "else if (i >= 128 - 16)",
1321
    "  res = Sz >> 128 - i;",
1322
    "else",
1323
    "  {",
1324
    "    RAISE_EXCEPTION (SIGILL);",
1325
    "    return;",
1326
    "  }",
1327
    "res &= 0xffff0000;",
1328
    "res_grd = 0;",
1329
    "goto logical;",
1330
  },
1331
  { "","", "psha #<imm>,dz",    "00010iiim32.zzzz",
1332
    "int Sz = DSP_R (z);",
1333
    "int Sz_grd = GET_DSP_GRD (z);",
1334
    "",
1335
    "if (i < 32)",
1336
    "  {",
1337
    "    if (i == 32)",
1338
    "      {",
1339
    "        res = 0;",
1340
    "        res_grd = Sz;",
1341
    "      }",
1342
    "    else",
1343
    "      {",
1344
    "        res = Sz << i;",
1345
    "        res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1346
    "      }",
1347
    "    res_grd = SEXT (res_grd);",
1348
    "    carry = res_grd & 1;",
1349
    "  }",
1350
    "else if (i >= 96)",
1351
    "  {",
1352
    "    i = 128 - i;",
1353
    "    if (i == 32)",
1354
    "      {",
1355
    "        res_grd = SIGN32 (Sz_grd);",
1356
    "        res = Sz_grd;",
1357
    "      }",
1358
    "    else",
1359
    "      {",
1360
    "        res = Sz >> i | Sz_grd << 32 - i;",
1361
    "        res_grd = Sz_grd >> i;",
1362
    "      }",
1363
    "    carry = Sz >> (i - 1) & 1;",
1364
    "  }",
1365
    "else",
1366
    "  {",
1367
    "    RAISE_EXCEPTION (SIGILL);",
1368
    "    return;",
1369
    "  }",
1370
    "COMPUTE_OVERFLOW;",
1371
    "greater_equal = 0;",
1372
  },
1373
  { "","", "pmuls Se,Sf,Dg",    "0100eeffxxyygguu",
1374
    "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1375
    "if (res == 0x80000000)",
1376
    "  res = 0x7fffffff;",
1377
    "DSP_R (g) = res;",
1378
    "DSP_GRD (g) = SIGN32 (res);",
1379
    "return;",
1380
  },
1381
  { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg",      "0110eeffxxyygguu",
1382
    "int Sx = DSP_R (x);",
1383
    "int Sx_grd = GET_DSP_GRD (x);",
1384
    "int Sy = DSP_R (y);",
1385
    "int Sy_grd = SIGN32 (Sy);",
1386
    "",
1387
    "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1388
    "if (res == 0x80000000)",
1389
    "  res = 0x7fffffff;",
1390
    "DSP_R (g) = res;",
1391
    "DSP_GRD (g) = SIGN32 (res);",
1392
    "",
1393
    "z = u;",
1394
    "res = Sx - Sy;",
1395
    "carry = (unsigned) res > (unsigned) Sx;",
1396
    "res_grd = Sx_grd - Sy_grd - carry;",
1397
    "COMPUTE_OVERFLOW;",
1398
    "ADD_SUB_GE;",
1399
  },
1400
  { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg",      "0111eeffxxyygguu",
1401
    "int Sx = DSP_R (x);",
1402
    "int Sx_grd = GET_DSP_GRD (x);",
1403
    "int Sy = DSP_R (y);",
1404
    "int Sy_grd = SIGN32 (Sy);",
1405
    "",
1406
    "res = (DSP_R (e)) >> 16 * (DSP_R (f) >> 16) * 2;",
1407
    "if (res == 0x80000000)",
1408
    "  res = 0x7fffffff;",
1409
    "DSP_R (g) = res;",
1410
    "DSP_GRD (g) = SIGN32 (res);",
1411
    "",
1412
    "z = u;",
1413
    "res = Sx + Sy;",
1414
    "carry = (unsigned) res < (unsigned) Sx;",
1415
    "res_grd = Sx_grd + Sy_grd + carry;",
1416
    "COMPUTE_OVERFLOW;",
1417
  },
1418
  { "","", "psubc Sx,Sy,Dz",            "10100000xxyyzzzz",
1419
    "int Sx = DSP_R (x);",
1420
    "int Sx_grd = GET_DSP_GRD (x);",
1421
    "int Sy = DSP_R (y);",
1422
    "int Sy_grd = SIGN32 (Sy);",
1423
    "",
1424
    "res = Sx - Sy - (DSR & 1);",
1425
    "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1426
    "res_grd = Sx_grd + Sy_grd + carry;",
1427
    "COMPUTE_OVERFLOW;",
1428
    "ADD_SUB_GE;",
1429
    "DSR &= ~0xf1;\n",
1430
    "if (res || res_grd)\n",
1431
    "  DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1432
    "else\n",
1433
    "  DSR |= DSR_MASK_Z | overflow;\n",
1434
    "DSR |= carry;\n",
1435
    "goto assign_z;\n",
1436
  },
1437
  { "","", "paddc Sx,Sy,Dz",    "10110000xxyyzzzz",
1438
    "int Sx = DSP_R (x);",
1439
    "int Sx_grd = GET_DSP_GRD (x);",
1440
    "int Sy = DSP_R (y);",
1441
    "int Sy_grd = SIGN32 (Sy);",
1442
    "",
1443
    "res = Sx + Sy + (DSR & 1);",
1444
    "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1445
    "res_grd = Sx_grd + Sy_grd + carry;",
1446
    "COMPUTE_OVERFLOW;",
1447
    "ADD_SUB_GE;",
1448
    "DSR &= ~0xf1;\n",
1449
    "if (res || res_grd)\n",
1450
    "  DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1451
    "else\n",
1452
    "  DSR |= DSR_MASK_Z | overflow;\n",
1453
    "DSR |= carry;\n",
1454
    "goto assign_z;\n",
1455
  },
1456
  { "","", "pcmp Sx,Sy",        "10000100xxyy....",
1457
    "int Sx = DSP_R (x);",
1458
    "int Sx_grd = GET_DSP_GRD (x);",
1459
    "int Sy = DSP_R (y);",
1460
    "int Sy_grd = SIGN32 (Sy);",
1461
    "",
1462
    "z = 17; /* Ignore result.  */",
1463
    "res = Sx - Sy;",
1464
    "carry = (unsigned) res > (unsigned) Sx;",
1465
    "res_grd = Sx_grd - Sy_grd - carry;",
1466
    "COMPUTE_OVERFLOW;",
1467
    "ADD_SUB_GE;",
1468
  },
1469
  { "","", "pwsb Sx,Sy,Dz",     "10100100xxyyzzzz",
1470
  },
1471
  { "","", "pwad Sx,Sy,Dz",     "10110100xxyyzzzz",
1472
  },
1473
  { "","", "pabs Sx,Dz",        "10001000xx..zzzz",
1474
    "res = DSP_R (x);",
1475
    "res_grd = GET_DSP_GRD (x);",
1476
    "if (res >= 0)",
1477
    "  carry = 0;",
1478
    "else",
1479
    "  {",
1480
    "    res = -res;",
1481
    "    carry = (res != 0); /* The manual has a bug here.  */",
1482
    "    res_grd = -res_grd - carry;",
1483
    "  }",
1484
    "COMPUTE_OVERFLOW;",
1485
    "/* ??? The re-computing of overflow after",
1486
    "   saturation processing is specific to pabs.  */",
1487
    "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
1488
    "ADD_SUB_GE;",
1489
  },
1490
  { "","", "prnd Sx,Dz",        "10011000xx..zzzz",
1491
    "int Sx = DSP_R (x);",
1492
    "int Sx_grd = GET_DSP_GRD (x);",
1493
    "",
1494
    "res = Sx + 0x8000;",
1495
    "carry = (unsigned) res < (unsigned) Sx;",
1496
    "res_grd = Sx_grd + carry;",
1497
    "COMPUTE_OVERFLOW;",
1498
    "ADD_SUB_GE;",
1499
  },
1500
  { "","", "pabs Sy,Dz",        "10101000..yyzzzz",
1501
    "res = DSP_R (y);",
1502
    "res_grd = 0;",
1503
    "overflow = 0;",
1504
    "greater_equal = DSR_MASK_G;",
1505
    "if (res >= 0)",
1506
    "  carry = 0;",
1507
    "else",
1508
    "  {",
1509
    "    res = -res;",
1510
    "    carry = 1;",
1511
    "    if (res < 0)",
1512
    "      {",
1513
    "        if (S)",
1514
    "          res = 0x7fffffff;",
1515
    "        else",
1516
    "          {",
1517
    "            overflow = DSR_MASK_V;",
1518
    "            greater_equal = 0;",
1519
    "          }",
1520
    "      }",
1521
    "  }",
1522
  },
1523
  { "","", "prnd Sy,Dz",        "10111000..yyzzzz",
1524
    "int Sy = DSP_R (y);",
1525
    "int Sy_grd = SIGN32 (Sy);",
1526
    "",
1527
    "res = Sy + 0x8000;",
1528
    "carry = (unsigned) res < (unsigned) Sy;",
1529
    "res_grd = Sy_grd + carry;",
1530
    "COMPUTE_OVERFLOW;",
1531
    "ADD_SUB_GE;",
1532
  },
1533
  { "","", "(if cc) pshl Sx,Sy,Dz",     "100000ccxxyyzzzz",
1534
    "int Sx = DSP_R (x) & 0xffff0000;",
1535
    "int Sy = DSP_R (y) >> 16 & 0x7f;",
1536
    "",
1537
    "if (Sy < 16)",
1538
    "  res = Sx << Sy;",
1539
    "else if (Sy >= 128 - 16)",
1540
    "  res = Sx >> 128 - Sy;",
1541
    "else",
1542
    "  {",
1543
    "    RAISE_EXCEPTION (SIGILL);",
1544
    "    return;",
1545
    "  }",
1546
    "goto cond_logical;",
1547
  },
1548
  { "","", "(if cc) psha Sx,Sy,Dz",     "100100ccxxyyzzzz",
1549
    "int Sx = DSP_R (x);",
1550
    "int Sx_grd = GET_DSP_GRD (x);",
1551
    "int Sy = DSP_R (y) >> 16 & 0x7f;",
1552
    "",
1553
    "if (Sy < 32)",
1554
    "  {",
1555
    "    if (Sy == 32)",
1556
    "      {",
1557
    "        res = 0;",
1558
    "        res_grd = Sx;",
1559
    "      }",
1560
    "    else",
1561
    "      {",
1562
    "        res = Sx << Sy;",
1563
    "        res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
1564
    "      }",
1565
    "    res_grd = SEXT (res_grd);",
1566
    "    carry = res_grd & 1;",
1567
    "  }",
1568
    "else if (Sy >= 96)",
1569
    "  {",
1570
    "    Sy = 128 - Sy;",
1571
    "    if (Sy == 32)",
1572
    "      {",
1573
    "        res_grd = SIGN32 (Sx_grd);",
1574
    "        res = Sx_grd;",
1575
    "      }",
1576
    "    else",
1577
    "      {",
1578
    "        res = Sx >> Sy | Sx_grd << 32 - Sy;",
1579
    "        res_grd = Sx_grd >> Sy;",
1580
    "      }",
1581
    "    carry = Sx >> (Sy - 1) & 1;",
1582
    "  }",
1583
    "else",
1584
    "  {",
1585
    "    RAISE_EXCEPTION (SIGILL);",
1586
    "    return;",
1587
    "  }",
1588
    "COMPUTE_OVERFLOW;",
1589
    "greater_equal = 0;",
1590
  },
1591
  { "","", "(if cc) psub Sx,Sy,Dz",     "101000ccxxyyzzzz",
1592
    "int Sx = DSP_R (x);",
1593
    "int Sx_grd = GET_DSP_GRD (x);",
1594
    "int Sy = DSP_R (y);",
1595
    "int Sy_grd = SIGN32 (Sy);",
1596
    "",
1597
    "res = Sx - Sy;",
1598
    "carry = (unsigned) res > (unsigned) Sx;",
1599
    "res_grd = Sx_grd - Sy_grd - carry;",
1600
    "COMPUTE_OVERFLOW;",
1601
    "ADD_SUB_GE;",
1602
  },
1603
  { "","", "(if cc) padd Sx,Sy,Dz",     "101100ccxxyyzzzz",
1604
    "int Sx = DSP_R (x);",
1605
    "int Sx_grd = GET_DSP_GRD (x);",
1606
    "int Sy = DSP_R (y);",
1607
    "int Sy_grd = SIGN32 (Sy);",
1608
    "",
1609
    "res = Sx + Sy;",
1610
    "carry = (unsigned) res < (unsigned) Sx;",
1611
    "res_grd = Sx_grd + Sy_grd + carry;",
1612
    "COMPUTE_OVERFLOW;",
1613
    "ADD_SUB_GE;",
1614
  },
1615
  { "","", "(if cc) pand Sx,Sy,Dz",     "100101ccxxyyzzzz",
1616
    "res = DSP_R (x) & DSP_R (y);",
1617
  "cond_logical:",
1618
    "res &= 0xffff0000;",
1619
    "res_grd = 0;",
1620
    "if (iword & 0x200)\n",
1621
    "  goto assign_z;\n",
1622
  "logical:",
1623
    "carry = 0;",
1624
    "overflow = 0;",
1625
    "greater_equal = 0;",
1626
    "DSR &= ~0xf1;\n",
1627
    "if (res)\n",
1628
    "  DSR |= res >> 26 & DSR_MASK_N;\n",
1629
    "else\n",
1630
    "  DSR |= DSR_MASK_Z;\n",
1631
    "goto assign_dc;\n",
1632
  },
1633
  { "","", "(if cc) pxor Sx,Sy,Dz",     "101001ccxxyyzzzz",
1634
    "res = DSP_R (x) ^ DSP_R (y);",
1635
    "goto cond_logical;",
1636
  },
1637
  { "","", "(if cc) por Sx,Sy,Dz",      "101101ccxxyyzzzz",
1638
    "res = DSP_R (x) | DSP_R (y);",
1639
    "goto cond_logical;",
1640
  },
1641
  { "","", "(if cc) pdec Sx,Dz",        "100010ccxx..zzzz",
1642
    "int Sx = DSP_R (x);",
1643
    "int Sx_grd = GET_DSP_GRD (x);",
1644
    "",
1645
    "res = Sx - 0x10000;",
1646
    "carry = res > Sx;",
1647
    "res_grd = Sx_grd - carry;",
1648
    "COMPUTE_OVERFLOW;",
1649
    "ADD_SUB_GE;",
1650
    "res &= 0xffff0000;",
1651
  },
1652
  { "","", "(if cc) pinc Sx,Dz",        "100110ccxx..zzzz",
1653
    "int Sx = DSP_R (x);",
1654
    "int Sx_grd = GET_DSP_GRD (x);",
1655
    "",
1656
    "res = Sx + 0x10000;",
1657
    "carry = res < Sx;",
1658
    "res_grd = Sx_grd + carry;",
1659
    "COMPUTE_OVERFLOW;",
1660
    "ADD_SUB_GE;",
1661
    "res &= 0xffff0000;",
1662
  },
1663
  { "","", "(if cc) pdec Sy,Dz",        "101010cc..yyzzzz",
1664
    "int Sy = DSP_R (y);",
1665
    "int Sy_grd = SIGN32 (Sy);",
1666
    "",
1667
    "res = Sy - 0x10000;",
1668
    "carry = res > Sy;",
1669
    "res_grd = Sy_grd - carry;",
1670
    "COMPUTE_OVERFLOW;",
1671
    "ADD_SUB_GE;",
1672
    "res &= 0xffff0000;",
1673
  },
1674
  { "","", "(if cc) pinc Sy,Dz",        "101110cc..yyzzzz",
1675
    "int Sy = DSP_R (y);",
1676
    "int Sy_grd = SIGN32 (Sy);",
1677
    "",
1678
    "res = Sy + 0x10000;",
1679
    "carry = res < Sy;",
1680
    "res_grd = Sy_grd + carry;",
1681
    "COMPUTE_OVERFLOW;",
1682
    "ADD_SUB_GE;",
1683
    "res &= 0xffff0000;",
1684
  },
1685
  { "","", "(if cc) pclr Dz",           "100011cc....zzzz",
1686
    "res = 0;",
1687
    "res_grd = 0;",
1688
    "carry = 0;",
1689
    "overflow = 0;",
1690
    "greater_equal = 1;",
1691
  },
1692
  { "","", "(if cc) pdmsb Sx,Dz",       "100111ccxx..zzzz",
1693
    "unsigned Sx = DSP_R (x);",
1694
    "int Sx_grd = GET_DSP_GRD (x);",
1695
    "int i = 16;",
1696
    "",
1697
    "if (Sx_grd < 0)",
1698
    "  {",
1699
    "    Sx_grd = ~Sx_grd;",
1700
    "    Sx = ~Sx;",
1701
    "  }",
1702
    "if (Sx_grd)",
1703
    "  {",
1704
    "    Sx = Sx_grd;",
1705
    "    res = -2;",
1706
    "  }",
1707
    "else if (Sx)",
1708
    "  res = 30;",
1709
    "else",
1710
    "  res = 31;",
1711
    "do",
1712
    "  {",
1713
    "    if (Sx & ~0 << i)",
1714
    "      {",
1715
    "        res -= i;",
1716
    "        Sx >>= i;",
1717
    "      }",
1718
    "  }",
1719
    "while (i >>= 1);",
1720
    "res <<= 16;",
1721
    "res_grd = SIGN32 (res);",
1722
    "carry = 0;",
1723
    "overflow = 0;",
1724
    "ADD_SUB_GE;",
1725
  },
1726
  { "","", "(if cc) pdmsb Sy,Dz",       "101111cc..yyzzzz",
1727
    "unsigned Sy = DSP_R (y);",
1728
    "int i;",
1729
    "",
1730
    "if (Sy < 0)",
1731
    "  Sy = ~Sy;",
1732
    "Sy <<= 1;",
1733
    "res = 31;",
1734
    "do",
1735
    "  {",
1736
    "    if (Sy & ~0 << i)",
1737
    "      {",
1738
    "        res -= i;",
1739
    "        Sy >>= i;",
1740
    "      }",
1741
    "  }",
1742
    "while (i >>= 1);",
1743
    "res <<= 16;",
1744
    "res_grd = SIGN32 (res);",
1745
    "carry = 0;",
1746
    "overflow = 0;",
1747
    "ADD_SUB_GE;",
1748
  },
1749
  { "","", "(if cc) pneg Sx,Dz",        "110010ccxx..zzzz",
1750
    "int Sx = DSP_R (x);",
1751
    "int Sx_grd = GET_DSP_GRD (x);",
1752
    "",
1753
    "res = 0 - Sx;",
1754
    "carry = res != 0;",
1755
    "res_grd = 0 - Sx_grd - carry;",
1756
    "COMPUTE_OVERFLOW;",
1757
    "ADD_SUB_GE;",
1758
  },
1759
  { "","", "(if cc) pcopy Sx,Dz",       "110110ccxx..zzzz",
1760
    "res = DSP_R (x);",
1761
    "res_grd = GET_DSP_GRD (x);",
1762
    "carry = 0;",
1763
    "COMPUTE_OVERFLOW;",
1764
    "ADD_SUB_GE;",
1765
  },
1766
  { "","", "(if cc) pneg Sy,Dz",        "111010cc..yyzzzz",
1767
    "int Sy = DSP_R (y);",
1768
    "int Sy_grd = SIGN32 (Sy);",
1769
    "",
1770
    "res = 0 - Sy;",
1771
    "carry = res != 0;",
1772
    "res_grd = 0 - Sy_grd - carry;",
1773
    "COMPUTE_OVERFLOW;",
1774
    "ADD_SUB_GE;",
1775
  },
1776
  { "","", "(if cc) pcopy Sy,Dz",       "111110cc..yyzzzz",
1777
    "res = DSP_R (y);",
1778
    "res_grd = SIGN32 (res);",
1779
    "carry = 0;",
1780
    "COMPUTE_OVERFLOW;",
1781
    "ADD_SUB_GE;",
1782
  },
1783
  { "","", "(if cc) psts MACH,Dz",      "110011cc....zzzz",
1784
    "res = MACH;",
1785
    "res_grd = SIGN32 (res);",
1786
    "goto assign_z;",
1787
  },
1788
  { "","", "(if cc) psts MACL,Dz",      "110111cc....zzzz",
1789
    "res = MACL;",
1790
    "res_grd = SIGN32 (res);",
1791
    "goto assign_z;",
1792
  },
1793
  { "","", "(if cc) plds Dz,MACH",      "111011cc....zzzz",
1794
    "if (0xa05f >> z & 1)",
1795
    "  RAISE_EXCEPTION (SIGILL);",
1796
    "else",
1797
    "  MACH = DSP_R (z);",
1798
    "return;",
1799
  },
1800
  { "","", "(if cc) plds Dz,MACL",      "111111cc....zzzz",
1801
    "if (0xa05f >> z & 1)",
1802
    "  RAISE_EXCEPTION (SIGILL);",
1803
    "else",
1804
    "  MACL = DSP_R (z) = res;",
1805
    "return;",
1806
  },
1807
  {0, 0}
1808
};
1809
 
1810
/* Tables of things to put into enums for sh-opc.h */
1811
static char *nibble_type_list[] =
1812
{
1813
  "HEX_0",
1814
  "HEX_1",
1815
  "HEX_2",
1816
  "HEX_3",
1817
  "HEX_4",
1818
  "HEX_5",
1819
  "HEX_6",
1820
  "HEX_7",
1821
  "HEX_8",
1822
  "HEX_9",
1823
  "HEX_A",
1824
  "HEX_B",
1825
  "HEX_C",
1826
  "HEX_D",
1827
  "HEX_E",
1828
  "HEX_F",
1829
  "REG_N",
1830
  "REG_M",
1831
  "BRANCH_12",
1832
  "BRANCH_8",
1833
  "DISP_8",
1834
  "DISP_4",
1835
  "IMM_4",
1836
  "IMM_4BY2",
1837
  "IMM_4BY4",
1838
  "PCRELIMM_8BY2",
1839
  "PCRELIMM_8BY4",
1840
  "IMM_8",
1841
  "IMM_8BY2",
1842
  "IMM_8BY4",
1843
 
1844
};
1845
static
1846
char *arg_type_list[] =
1847
{
1848
  "A_END",
1849
  "A_BDISP12",
1850
  "A_BDISP8",
1851
  "A_DEC_M",
1852
  "A_DEC_N",
1853
  "A_DISP_GBR",
1854
  "A_DISP_PC",
1855
  "A_DISP_REG_M",
1856
  "A_DISP_REG_N",
1857
  "A_GBR",
1858
  "A_IMM",
1859
  "A_INC_M",
1860
  "A_INC_N",
1861
  "A_IND_M",
1862
  "A_IND_N",
1863
  "A_IND_R0_REG_M",
1864
  "A_IND_R0_REG_N",
1865
  "A_MACH",
1866
  "A_MACL",
1867
  "A_PR",
1868
  "A_R0",
1869
  "A_R0_GBR",
1870
  "A_REG_M",
1871
  "A_REG_N",
1872
  "A_SR",
1873
  "A_VBR",
1874
  "A_SSR",
1875
  "A_SPC",
1876
  0,
1877
};
1878
 
1879
static void
1880
make_enum_list (name, s)
1881
     char *name;
1882
     char **s;
1883
{
1884
  int i = 1;
1885
  printf ("typedef enum {\n");
1886
  while (*s)
1887
    {
1888
      printf ("\t%s,\n", *s);
1889
      s++;
1890
      i++;
1891
    }
1892
  printf ("} %s;\n", name);
1893
}
1894
 
1895
static int
1896
qfunc (a, b)
1897
     op *a;
1898
     op *b;
1899
{
1900
  char bufa[9];
1901
  char bufb[9];
1902
  int diff;
1903
 
1904
  memcpy (bufa, a->code, 4);
1905
  memcpy (bufa + 4, a->code + 12, 4);
1906
  bufa[8] = 0;
1907
 
1908
  memcpy (bufb, b->code, 4);
1909
  memcpy (bufb + 4, b->code + 12, 4);
1910
  bufb[8] = 0;
1911
  diff = strcmp (bufa, bufb);
1912
  /* Stabilize the sort, so that later entries can override more general
1913
     preceding entries.  */
1914
  return diff ? diff : a - b;
1915
}
1916
 
1917
static void
1918
sorttab ()
1919
{
1920
  op *p = tab;
1921
  int len = 0;
1922
 
1923
  while (p->name)
1924
    {
1925
      p++;
1926
      len++;
1927
    }
1928
  qsort (tab, len, sizeof (*p), qfunc);
1929
}
1930
 
1931
static void
1932
gengastab ()
1933
{
1934
  op *p;
1935
  sorttab ();
1936
  for (p = tab; p->name; p++)
1937
    {
1938
      printf ("%s %-30s\n", p->code, p->name);
1939
    }
1940
 
1941
 
1942
}
1943
 
1944
/* Convert a string of 4 binary digits into an int */
1945
 
1946
static
1947
int
1948
bton (s)
1949
     char *s;
1950
 
1951
{
1952
  int n = 0;
1953
  int v = 8;
1954
  while (v)
1955
    {
1956
      if (*s == '1')
1957
        n |= v;
1958
      v >>= 1;
1959
      s++;
1960
    }
1961
  return n;
1962
}
1963
 
1964
static unsigned char table[1 << 16];
1965
 
1966
/* Take an opcode expand all varying fields in it out and fill all the
1967
  right entries in 'table' with the opcode index*/
1968
 
1969
static void
1970
expand_opcode (shift, val, i, s)
1971
     int shift;
1972
     int val;
1973
     int i;
1974
     char *s;
1975
{
1976
  int j;
1977
 
1978
  if (*s == 0)
1979
    {
1980
      table[val] = i;
1981
    }
1982
  else
1983
    {
1984
      switch (s[0])
1985
        {
1986
 
1987
        case '0':
1988
        case '1':
1989
          {
1990
            int m, mv;
1991
 
1992
            val |= bton (s) << shift;
1993
            if (s[2] == '0' || s[2] == '1')
1994
              expand_opcode (shift - 4, val, i, s + 4);
1995
            else if (s[2] == 'N')
1996
              for (j = 0; j < 4; j++)
1997
                expand_opcode (shift - 4, val | (j << shift), i, s + 4);
1998
            else if (s[2] == 'x')
1999
              for (j = 0; j < 4; j += 2)
2000
                for (m = 0; m < 32; m++)
2001
                  {
2002
                    /* Ignore illegal nopy */
2003
                    if ((m & 7) == 0 && m != 0)
2004
                      continue;
2005
                    mv = m & 3 | (m & 4) << 2 | (m & 8) << 3 | (m & 16) << 4;
2006
                    expand_opcode (shift - 4, val | mv | (j << shift), i,
2007
                                   s + 4);
2008
                  }
2009
            else if (s[2] == 'y')
2010
              for (j = 0; j < 2; j++)
2011
                expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2012
            break;
2013
          }
2014
        case 'n':
2015
        case 'm':
2016
          for (j = 0; j < 16; j++)
2017
            {
2018
              expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2019
 
2020
            }
2021
          break;
2022
        case 'M':
2023
          /* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */
2024
          for (j = 5; j < 16; j++)
2025
            if (j != 6)
2026
              expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2027
          break;
2028
        case 'G':
2029
          /* A1G, A0G: */
2030
          for (j = 13; j <= 15; j +=2)
2031
            expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2032
          break;
2033
        case 's':
2034
          /* System registers mach, macl, pr: */
2035
          for (j = 0; j < 3; j++)
2036
            expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2037
          /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2038
          for (j = 5; j < 12; j++)
2039
            expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2040
          break;
2041
        case 'X':
2042
        case 'a':
2043
          val |= bton (s) << shift;
2044
          for (j = 0; j < 16; j += 8)
2045
            expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2046
          break;
2047
        case 'Y':
2048
        case 'A':
2049
          val |= bton (s) << shift;
2050
          for (j = 0; j < 8; j += 4)
2051
            expand_opcode (shift - 4, val | (j << shift), i, s + 4);
2052
          break;
2053
 
2054
        default:
2055
          for (j = 0; j < (1 << (shift + 4)); j++)
2056
            {
2057
              table[val | j] = i;
2058
            }
2059
        }
2060
    }
2061
}
2062
 
2063
/* Print the jump table used to index an opcode into a switch
2064
   statement entry. */
2065
 
2066
static void
2067
dumptable (name, size, start)
2068
     char *name;
2069
     int size;
2070
     int start;
2071
{
2072
  int lump = 256;
2073
  int online = 16;
2074
 
2075
  int i = start;
2076
 
2077
  printf ("unsigned char %s[%d]={\n", name, size);
2078
  while (i < start + size)
2079
    {
2080
      int j = 0;
2081
 
2082
      printf ("/* 0x%x */\n", i);
2083
 
2084
      while (j < lump)
2085
        {
2086
          int k = 0;
2087
          while (k < online)
2088
            {
2089
              printf ("%2d", table[i + j + k]);
2090
              if (j + k < lump)
2091
                printf (",");
2092
 
2093
              k++;
2094
            }
2095
          j += k;
2096
          printf ("\n");
2097
        }
2098
      i += j;
2099
    }
2100
  printf ("};\n");
2101
}
2102
 
2103
 
2104
static void
2105
filltable (p)
2106
     op *p;
2107
{
2108
  static int index = 1;
2109
 
2110
  sorttab ();
2111
  for (; p->name; p++)
2112
    {
2113
      p->index = index++;
2114
      expand_opcode (12, 0, p->index, p->code);
2115
    }
2116
}
2117
 
2118
/* Table already contais all the switch case tags for 16-bit opcode double
2119
   data transfer (ddt) insns, and the switch case tag for processing parallel
2120
   processing insns (ppi) for code 0xf800 (ppi nopx nopy).  Copy the
2121
   latter tag to represent all combinations of ppi with ddt.  */
2122
static void
2123
ppi_moves ()
2124
{
2125
  int i;
2126
 
2127
  for (i = 0xf000; i < 0xf400; i++)
2128
    if (table[i])
2129
      table[i + 0x800] = table[0xf800];
2130
}
2131
 
2132
static void
2133
gensim_caselist (p)
2134
     op *p;
2135
{
2136
  for (; p->name; p++)
2137
    {
2138
      int j;
2139
      int sextbit = -1;
2140
      int needm = 0;
2141
      int needn = 0;
2142
 
2143
      char *s = p->code;
2144
 
2145
      printf ("  /* %s %s */\n", p->name, p->code);
2146
      printf ("  case %d:      \n", p->index);
2147
 
2148
      printf ("    {\n");
2149
      while (*s)
2150
        {
2151
          switch (*s)
2152
            {
2153
            case '0':
2154
            case '1':
2155
              s += 2;
2156
              break;
2157
            case '.':
2158
              s += 4;
2159
              break;
2160
            case 'n':
2161
              printf ("      int n = (iword >>8) & 0xf;\n");
2162
              needn = 1;
2163
              s += 4;
2164
              break;
2165
            case 'N':
2166
              printf ("      int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2167
              s += 2;
2168
              break;
2169
            case 'x':
2170
              printf ("      int n = ((iword >> 9) & 1) + 4;\n");
2171
              needn = 1;
2172
              s += 2;
2173
              break;
2174
            case 'y':
2175
              printf ("      int n = ((iword >> 8) & 1) + 4;\n");
2176
              needn = 1;
2177
              s += 2;
2178
              break;
2179
            case 'm':
2180
              needm = 1;
2181
            case 's':
2182
            case 'M':
2183
            case 'G':
2184
              printf ("      int m = (iword >>4) & 0xf;\n");
2185
              s += 4;
2186
              break;
2187
            case 'X':
2188
              printf ("      int m = ((iword >> 7) & 1) + 8;\n");
2189
              s += 2;
2190
              break;
2191
            case 'a':
2192
              printf ("      int m = 7 - ((iword >> 6) & 2);\n");
2193
              s += 2;
2194
              break;
2195
            case 'Y':
2196
              printf ("      int m = ((iword >> 6) & 1) + 10;\n");
2197
              s += 2;
2198
              break;
2199
            case 'A':
2200
              printf ("      int m = 7 - ((iword >> 5) & 2);\n");
2201
              s += 2;
2202
              break;
2203
 
2204
            case 'i':
2205
              printf ("      int i = (iword & 0x");
2206
 
2207
              switch (s[1])
2208
                {
2209
                case '4':
2210
                  printf ("f");
2211
                  break;
2212
                case '8':
2213
                  printf ("ff");
2214
                  break;
2215
                case '1':
2216
                  sextbit = 12;
2217
 
2218
                  printf ("fff");
2219
                  break;
2220
                }
2221
              printf (")");
2222
 
2223
              switch (s[3])
2224
                {
2225
                case '1':
2226
                  break;
2227
                case '2':
2228
                  printf ("<<1");
2229
                  break;
2230
                case '4':
2231
                  printf ("<<2");
2232
                  break;
2233
                }
2234
              printf (";\n");
2235
              s += 4;
2236
            }
2237
        }
2238
      if (sextbit > 0)
2239
        {
2240
          printf ("      i = (i ^ (1<<%d))-(1<<%d);\n",
2241
                  sextbit - 1, sextbit - 1);
2242
        }
2243
 
2244
      if (needm && needn)
2245
        printf ("      TB(m,n);\n");
2246
      else if (needm)
2247
        printf ("      TL(m);\n");
2248
      else if (needn)
2249
        printf ("      TL(n);\n");
2250
 
2251
      {
2252
        /* Do the refs */
2253
        char *r;
2254
        for (r = p->refs; *r; r++)
2255
          {
2256
            if (*r == '0') printf("      CREF(0);\n");
2257
            if (*r == '8') printf("      CREF(8);\n");
2258
            if (*r == '9') printf("      CREF(9);\n");
2259
            if (*r == 'n') printf("      CREF(n);\n");
2260
            if (*r == 'm') printf("      CREF(m);\n");
2261
          }
2262
      }
2263
 
2264
      printf ("      {\n");
2265
      for (j = 0; j < MAX_NR_STUFF; j++)
2266
        {
2267
          if (p->stuff[j])
2268
            {
2269
              printf ("        %s\n", p->stuff[j]);
2270
            }
2271
        }
2272
      printf ("      }\n");
2273
 
2274
      {
2275
        /* Do the defs */
2276
        char *r;
2277
        for (r = p->defs; *r; r++)
2278
          {
2279
            if (*r == '0') printf("      CDEF(0);\n");
2280
            if (*r == 'n') printf("      CDEF(n);\n");
2281
            if (*r == 'm') printf("      CDEF(m);\n");
2282
          }
2283
      }
2284
 
2285
      printf ("      break;\n");
2286
      printf ("    }\n");
2287
    }
2288
}
2289
 
2290
static void
2291
gensim ()
2292
{
2293
  printf ("{\n");
2294
  printf ("  switch (jump_table[iword]) {\n");
2295
 
2296
  gensim_caselist (tab);
2297
  gensim_caselist (movsxy_tab);
2298
 
2299
  printf ("  default:\n");
2300
  printf ("    {\n");
2301
  printf ("      RAISE_EXCEPTION (SIGILL);\n");
2302
  printf ("    }\n");
2303
  printf ("  }\n");
2304
  printf ("}\n");
2305
}
2306
 
2307
static void
2308
gendefines ()
2309
{
2310
  op *p;
2311
  filltable (tab);
2312
  for (p = tab; p->name; p++)
2313
    {
2314
      char *s = p->name;
2315
      printf ("#define OPC_");
2316
      while (*s) {
2317
        if (isupper(*s))
2318
          *s = tolower(*s);
2319
        if (isalpha(*s)) printf("%c", *s);
2320
        if (*s == ' ') printf("_");
2321
        if (*s == '@') printf("ind_");
2322
        if (*s == ',') printf("_");
2323
        s++;
2324
      }
2325
      printf(" %d\n",p->index);
2326
    }
2327
}
2328
 
2329
static int ppi_index;
2330
 
2331
/* Take an ppi code, expand all varying fields in it and fill all the
2332
   right entries in 'table' with the opcode index.  */
2333
 
2334
static void
2335
expand_ppi_code (val, i, s)
2336
     int val;
2337
     int i;
2338
     char *s;
2339
{
2340
  int j;
2341
 
2342
  for (;;)
2343
    {
2344
      switch (s[0])
2345
        {
2346
        /* The last eight bits are disregarded for the switch table.  */
2347
        case 'm':
2348
        case 'x':
2349
        case '.':
2350
          table[val] = i;
2351
          return;
2352
        case '0':
2353
          val += val;
2354
          s++;
2355
          break;
2356
        case '1':
2357
          val += val + 1;
2358
          s++;
2359
          break;
2360
        case 'i':
2361
        case 'e': case 'f':
2362
          val += val;
2363
          s++;
2364
          expand_ppi_code (val, i, s);
2365
          val++;
2366
          break;
2367
        case 'c':
2368
          val <<= 2;
2369
          s += 2;
2370
          val++;
2371
          expand_ppi_code (val, ppi_index++, s);
2372
          val++;
2373
          expand_ppi_code (val, i, s);
2374
          val++;
2375
          break;
2376
        }
2377
    }
2378
}
2379
 
2380
static void
2381
ppi_filltable ()
2382
{
2383
  op *p;
2384
  ppi_index = 1;
2385
 
2386
  for (p = ppi_tab; p->name; p++)
2387
    {
2388
      p->index = ppi_index++;
2389
      expand_ppi_code (0, p->index, p->code);
2390
    }
2391
}
2392
 
2393
static void
2394
ppi_gensim ()
2395
{
2396
  op *p = ppi_tab;
2397
 
2398
  printf ("#define DSR_MASK_G 0x80\n");
2399
  printf ("#define DSR_MASK_Z 0x40\n");
2400
  printf ("#define DSR_MASK_N 0x20\n");
2401
  printf ("#define DSR_MASK_V 0x10\n");
2402
  printf ("\n");
2403
  printf ("#define COMPUTE_OVERFLOW do {\\\n");
2404
  printf ("  overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
2405
  printf ("  if (overflow && S) \\\n");
2406
  printf ("    { \\\n");
2407
  printf ("      if (res_grd & 0x80) \\\n");
2408
  printf ("        { \\\n");
2409
  printf ("          res = 0x80000000; \\\n");
2410
  printf ("          res_grd |=  0xff; \\\n");
2411
  printf ("        } \\\n");
2412
  printf ("      else \\\n");
2413
  printf ("        { \\\n");
2414
  printf ("          res = 0x7fffffff; \\\n");
2415
  printf ("          res_grd &= ~0xff; \\\n");
2416
  printf ("        } \\\n");
2417
  printf ("      overflow = 0; \\\n");
2418
  printf ("    } \\\n");
2419
  printf ("} while (0)\n");
2420
  printf ("\n");
2421
  printf ("#define ADD_SUB_GE \\\n");
2422
  printf ("  (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
2423
  printf ("\n");
2424
  printf ("static void\n");
2425
  printf ("ppi_insn (iword)\n");
2426
  printf ("     int iword;\n");
2427
  printf ("{\n");
2428
  printf ("  static char e_tab[] = { 8,  9, 10,  5};\n");
2429
  printf ("  static char f_tab[] = {10, 11,  8,  5};\n");
2430
  printf ("  static char x_tab[] = { 8,  9,  7,  5};\n");
2431
  printf ("  static char y_tab[] = {10, 11, 12, 14};\n");
2432
  printf ("  static char g_tab[] = {12, 14,  7,  5};\n");
2433
  printf ("  static char u_tab[] = { 8, 10,  7,  5};\n");
2434
  printf ("\n");
2435
  printf ("  int z;\n");
2436
  printf ("  int res, res_grd;\n");
2437
  printf ("  int carry, overflow, greater_equal;\n");
2438
  printf ("\n");
2439
  printf ("  switch (ppi_table[iword >> 8]) {\n");
2440
 
2441
  for (; p->name; p++)
2442
    {
2443
      int shift, j;
2444
      int cond = 0;
2445
      int havedecl = 0;
2446
 
2447
      char *s = p->code;
2448
 
2449
      printf ("  /* %s %s */\n", p->name, p->code);
2450
      printf ("  case %d:      \n", p->index);
2451
 
2452
      printf ("    {\n");
2453
      for (shift = 16; *s; )
2454
        {
2455
          switch (*s)
2456
            {
2457
            case 'i':
2458
              printf ("      int i = (iword >> 4) & 0x7f;\n");
2459
              s += 6;
2460
              break;
2461
            case 'e':
2462
            case 'f':
2463
            case 'x':
2464
            case 'y':
2465
            case 'g':
2466
            case 'u':
2467
              shift -= 2;
2468
              printf ("      int %c = %c_tab[(iword >> %d) & 3];\n",
2469
                      *s, *s, shift);
2470
              havedecl = 1;
2471
              s += 2;
2472
              break;
2473
            case 'c':
2474
              printf ("      if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
2475
              printf ("\tbreak;\n");
2476
              printf ("    }\n");
2477
              printf ("  case %d:      \n", p->index + 1);
2478
              printf ("    {\n");
2479
              cond = 1;
2480
            case '0':
2481
            case '1':
2482
            case '.':
2483
              shift -= 2;
2484
              s += 2;
2485
              break;
2486
            case 'z':
2487
              if (havedecl)
2488
                printf ("\n");
2489
              printf ("      z = iword & 0xf;\n");
2490
              havedecl = 2;
2491
              s += 4;
2492
              break;
2493
            }
2494
        }
2495
      if (havedecl == 1)
2496
        printf ("\n");
2497
      else if (havedecl == 2)
2498
        printf ("      {\n");
2499
      for (j = 0; j < MAX_NR_STUFF; j++)
2500
        {
2501
          if (p->stuff[j])
2502
            {
2503
              printf ("      %s%s\n",
2504
                      (havedecl == 2 ? "  " : ""),
2505
                      p->stuff[j]);
2506
            }
2507
        }
2508
      if (havedecl == 2)
2509
        printf ("      }\n");
2510
      if (cond)
2511
        {
2512
          printf ("      if (iword & 0x200)\n");
2513
          printf ("        goto assign_z;\n");
2514
        }
2515
      printf ("      break;\n");
2516
      printf ("    }\n");
2517
    }
2518
 
2519
  printf ("  default:\n");
2520
  printf ("    {\n");
2521
  printf ("      RAISE_EXCEPTION (SIGILL);\n");
2522
  printf ("      return;\n");
2523
  printf ("    }\n");
2524
  printf ("  }\n");
2525
  printf ("  DSR &= ~0xf1;\n");
2526
  printf ("  if (res || res_grd)\n");
2527
  printf ("    DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
2528
  printf ("  else\n");
2529
  printf ("    DSR |= DSR_MASK_Z | overflow;\n");
2530
  printf (" assign_dc:\n");
2531
  printf ("  switch (DSR >> 1 & 7)\n");
2532
  printf ("    {\n");
2533
  printf ("    case 0: /* Carry Mode */\n");
2534
  printf ("      DSR |= carry;\n");
2535
  printf ("    case 1: /* Negative Value Mode */\n");
2536
  printf ("      DSR |= res_grd >> 7 & 1;\n");
2537
  printf ("    case 2: /* Zero Value Mode */\n");
2538
  printf ("      DSR |= DSR >> 6 & 1;\n");
2539
  printf ("    case 3: /* Overflow mode\n");
2540
  printf ("      DSR |= overflow >> 4;\n");
2541
  printf ("    case 4: /* Signed Greater Than Mode */\n");
2542
  printf ("      DSR |= DSR >> 7 & 1;\n");
2543
  printf ("    case 4: /* Signed Greater Than Or Equal Mode */\n");
2544
  printf ("      DSR |= greater_equal >> 7;\n");
2545
  printf ("    }\n");
2546
  printf (" assign_z:\n");
2547
  printf ("  if (0xa05f >> z & 1)\n");
2548
  printf ("    {\n");
2549
  printf ("      RAISE_EXCEPTION (SIGILL);\n");
2550
  printf ("      return;\n");
2551
  printf ("    }\n");
2552
  printf ("  DSP_R (z) = res;\n");
2553
  printf ("  DSP_GRD (z) = res_grd;\n");
2554
  printf ("}\n");
2555
}
2556
 
2557
int
2558
main (ac, av)
2559
     int ac;
2560
     char **av;
2561
{
2562
  /* verify the table before anything else */
2563
  {
2564
    op *p;
2565
    for (p = tab; p->name; p++)
2566
      {
2567
        /* check that the code field contains 16 bits */
2568
        if (strlen (p->code) != 16)
2569
          {
2570
            fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
2571
                     p->code, strlen (p->code), p->name);
2572
            abort ();
2573
          }
2574
      }
2575
  }
2576
 
2577
  /* now generate the requested data */
2578
  if (ac > 1)
2579
    {
2580
      if (strcmp (av[1], "-t") == 0)
2581
        {
2582
          gengastab ();
2583
        }
2584
      else if (strcmp (av[1], "-d") == 0)
2585
        {
2586
          gendefines ();
2587
        }
2588
      else if (strcmp (av[1], "-s") == 0)
2589
        {
2590
          filltable (tab);
2591
          dumptable ("sh_jump_table", 1 << 16, 0);
2592
 
2593
          memset (table, 0, sizeof table);
2594
          filltable (movsxy_tab);
2595
          ppi_moves ();
2596
          dumptable ("sh_dsp_table", 1 << 12, 0xf000);
2597
 
2598
          memset (table, 0, sizeof table);
2599
          ppi_filltable ();
2600
          dumptable ("ppi_table", 1 << 8, 0);
2601
        }
2602
      else if (strcmp (av[1], "-x") == 0)
2603
        {
2604
          filltable (tab);
2605
          filltable (movsxy_tab);
2606
          gensim ();
2607
        }
2608
      else if (strcmp (av[1], "-p") == 0)
2609
        {
2610
          ppi_filltable ();
2611
          ppi_gensim ();
2612
        }
2613
    }
2614
  else
2615
    fprintf (stderr, "Opcode table generation no longer supported.\n");
2616
  return 0;
2617
}

powered by: WebSVN 2.1.0

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