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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [sim/] [sh/] [gencode.c] - Blame information for rev 840

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Simulator/Opcode generator for the Renesas
2
   (formerly Hitachi) / SuperH Inc. Super-H architecture.
3
 
4
   Written by Steve Chamberlain of Cygnus Support.
5
   sac@cygnus.com
6
 
7
   This file is part of SH sim.
8
 
9
 
10
                THIS SOFTWARE IS NOT COPYRIGHTED
11
 
12
   Cygnus offers the following for use in the public domain.  Cygnus
13
   makes no warranty with regard to the software or it's performance
14
   and the user accepts the software "AS IS" with all faults.
15
 
16
   CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
17
   THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19
 
20
*/
21
 
22
/* This program generates the opcode table for the assembler and
23
   the simulator code.
24
 
25
   -t           prints a pretty table for the assembler manual
26
   -s           generates the simulator code jump table
27
   -d           generates a define table
28
   -x           generates the simulator code switch statement
29
   default      used to generate the opcode tables
30
 
31
*/
32
 
33
#include <stdio.h>
34
 
35
#define MAX_NR_STUFF 42
36
 
37
typedef struct
38
{
39
  char *defs;
40
  char *refs;
41
  char *name;
42
  char *code;
43
  char *stuff[MAX_NR_STUFF];
44
  int index;
45
} op;
46
 
47
 
48
op tab[] =
49
{
50
 
51
  { "n", "", "add #<imm>,<REG_N>", "0111nnnni8*1....",
52
    "R[n] += SEXT (i);",
53
    "if (i == 0) {",
54
    "  UNDEF(n); /* see #ifdef PARANOID */",
55
    "  break;",
56
    "}",
57
  },
58
  { "n", "mn", "add <REG_M>,<REG_N>", "0011nnnnmmmm1100",
59
    "R[n] += R[m];",
60
  },
61
 
62
  { "n", "mn", "addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
63
    "ult = R[n] + T;",
64
    "SET_SR_T (ult < R[n]);",
65
    "R[n] = ult + R[m];",
66
    "SET_SR_T (T || (R[n] < ult));",
67
  },
68
 
69
  { "n", "mn", "addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
70
    "ult = R[n] + R[m];",
71
    "SET_SR_T ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
72
    "R[n] = ult;",
73
  },
74
 
75
  { "0", "0", "and #<imm>,R0", "11001001i8*1....",
76
    "R0 &= i;",
77
  },
78
  { "n", "nm", "and <REG_M>,<REG_N>", "0010nnnnmmmm1001",
79
    "R[n] &= R[m];",
80
  },
81
  { "", "0", "and.b #<imm>,@(R0,GBR)", "11001101i8*1....",
82
    "MA (1);",
83
    "WBAT (GBR + R0, RBAT (GBR + R0) & i);",
84
  },
85
 
86
  { "", "", "bf <bdisp8>", "10001011i8p1....",
87
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
88
    "if (!T) {",
89
    "  SET_NIP (PC + 4 + (SEXT (i) * 2));",
90
    "  cycles += 2;",
91
    "}",
92
  },
93
 
94
  { "", "", "bf.s <bdisp8>", "10001111i8p1....",
95
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
96
    "if (!T) {",
97
    "  SET_NIP (PC + 4 + (SEXT (i) * 2));",
98
    "  cycles += 2;",
99
    "  Delay_Slot (PC + 2);",
100
    "}",
101
  },
102
 
103
  { "", "n", "bit32 #imm3,@(disp12,<REG_N>)", "0011nnnni8*11001",
104
    "/* 32-bit logical bit-manipulation instructions.  */",
105
    "int word2 = RIAT (nip);",
106
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
107
    "i >>= 4;   /* BOGUS: Using only three bits of 'i'.  */",
108
    "/* MSB of 'i' must be zero.  */",
109
    "if (i > 7)",
110
    "  RAISE_EXCEPTION (SIGILL);",
111
    "MA (1);",
112
    "do_blog_insn (1 << i, (word2 & 0xfff) + R[n], ",
113
    "              (word2 >> 12) & 0xf, memory, maskb);",
114
    "SET_NIP (nip + 2); /* Consume 2 more bytes.  */",
115
  },
116
  { "", "", "bra <bdisp12>", "1010i12.........",
117
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
118
    "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
119
    "cycles += 2;",
120
    "Delay_Slot (PC + 2);",
121
  },
122
 
123
  { "", "n", "braf <REG_N>", "0000nnnn00100011",
124
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
125
    "SET_NIP (PC + 4 + R[n]);",
126
    "cycles += 2;",
127
    "Delay_Slot (PC + 2);",
128
  },
129
 
130
  { "", "", "bsr <bdisp12>", "1011i12.........",
131
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
132
    "PR = PH2T (PC + 4);",
133
    "SET_NIP (PC + 4 + (SEXT12 (i) * 2));",
134
    "cycles += 2;",
135
    "Delay_Slot (PC + 2);",
136
  },
137
 
138
  { "", "n", "bsrf <REG_N>", "0000nnnn00000011",
139
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
140
    "PR = PH2T (PC) + 4;",
141
    "SET_NIP (PC + 4 + R[n]);",
142
    "cycles += 2;",
143
    "Delay_Slot (PC + 2);",
144
  },
145
 
146
  { "", "", "bt <bdisp8>", "10001001i8p1....",
147
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
148
    "if (T) {",
149
    "  SET_NIP (PC + 4 + (SEXT (i) * 2));",
150
    "  cycles += 2;",
151
    "}",
152
  },
153
 
154
  { "", "m", "bld/st #<imm>, <REG_M>", "10000111mmmmi4*1",
155
    "/* MSB of 'i' is true for load, false for store.  */",
156
    "if (i <= 7)",
157
    "  if (T)",
158
    "    R[m] |= (1 << i);",
159
    "  else",
160
    "    R[m] &= ~(1 << i);",
161
    "else",
162
    "  SET_SR_T ((R[m] & (1 << (i - 8))) != 0);",
163
  },
164
  { "m", "m", "bset/clr #<imm>, <REG_M>", "10000110mmmmi4*1",
165
    "/* MSB of 'i' is true for set, false for clear.  */",
166
    "if (i <= 7)",
167
    "  R[m] &= ~(1 << i);",
168
    "else",
169
    "  R[m] |= (1 << (i - 8));",
170
  },
171
  { "n", "n", "clips.b <REG_N>", "0100nnnn10010001",
172
    "if (R[n] < -128 || R[n] > 127) {",
173
    "  L (n);",
174
    "  SET_SR_CS (1);",
175
    "  if (R[n] > 127)",
176
    "    R[n] = 127;",
177
    "  else if (R[n] < -128)",
178
    "    R[n] = -128;",
179
    "}",
180
  },
181
  { "n", "n", "clips.w <REG_N>", "0100nnnn10010101",
182
    "if (R[n] < -32768 || R[n] > 32767) {",
183
    "  L (n);",
184
    "  SET_SR_CS (1);",
185
    "  if (R[n] > 32767)",
186
    "    R[n] = 32767;",
187
    "  else if (R[n] < -32768)",
188
    "    R[n] = -32768;",
189
    "}",
190
  },
191
  { "n", "n", "clipu.b <REG_N>", "0100nnnn10000001",
192
    "if (R[n] < -256 || R[n] > 255) {",
193
    "  L (n);",
194
    "  SET_SR_CS (1);",
195
    "  R[n] = 255;",
196
    "}",
197
  },
198
  { "n", "n", "clipu.w <REG_N>", "0100nnnn10000101",
199
    "if (R[n] < -65536 || R[n] > 65535) {",
200
    "  L (n);",
201
    "  SET_SR_CS (1);",
202
    "  R[n] = 65535;",
203
    "}",
204
  },
205
  { "n", "0n", "divs R0,<REG_N>", "0100nnnn10010100",
206
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
207
    "if (R0 == 0)",
208
    "  R[n] = 0x7fffffff;",
209
    "else if (R0 == -1 && R[n] == 0x80000000)",
210
    "  R[n] = 0x7fffffff;",
211
    "else R[n] /= R0;",
212
    "L (n);",
213
  },
214
  { "n", "0n", "divu R0,<REG_N>", "0100nnnn10000100",
215
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
216
    "if (R0 == 0)",
217
    "  R[n] = 0xffffffff;",
218
    "/* FIXME: The result may be implementation-defined if it is outside */",
219
    "/* the range of signed int (i.e. if R[n] was negative and R0 == 1).  */",
220
    "else R[n] = R[n] / (unsigned int) R0;",
221
    "L (n);",
222
  },
223
  { "n", "0n", "mulr R0,<REG_N>", "0100nnnn10000000",
224
    "R[n] = (R[n] * R0) & 0xffffffff;",
225
    "L (n);",
226
  },
227
  { "0", "n", "ldbank @<REG_N>,R0", "0100nnnn11100101",
228
    "int regn = (R[n] >> 2) & 0x1f;",
229
    "int bankn = (R[n] >> 7) & 0x1ff;",
230
    "if (regn > 19)",
231
    "  regn = 19;       /* FIXME what should happen? */",
232
    "R0 = saved_state.asregs.regstack[bankn].regs[regn];",
233
    "L (0);",
234
  },
235
  { "", "0n", "stbank R0,@<REG_N>", "0100nnnn11100001",
236
    "int regn = (R[n] >> 2) & 0x1f;",
237
    "int bankn = (R[n] >> 7) & 0x1ff;",
238
    "if (regn > 19)",
239
    "  regn = 19;       /* FIXME what should happen? */",
240
    "saved_state.asregs.regstack[bankn].regs[regn] = R0;",
241
  },
242
  { "", "", "resbank", "0000000001011011",
243
    "int i;",
244
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
245
    /* FIXME: cdef all */
246
    "if (BO) {  /* Bank Overflow */",
247
    /* FIXME: how do we know when to reset BO?  */
248
    "  for (i = 0; i <= 14; i++) {",
249
    "    R[i] = RLAT (R[15]);",
250
    "    MA (1);",
251
    "    R[15] += 4;",
252
    "  }",
253
    "  PR = RLAT (R[15]);",
254
    "  R[15] += 4;",
255
    "  MA (1);",
256
    "  GBR = RLAT (R[15]);",
257
    "  R[15] += 4;",
258
    "  MA (1);",
259
    "  MACH = RLAT (R[15]);",
260
    "  R[15] += 4;",
261
    "  MA (1);",
262
    "  MACL = RLAT (R[15]);",
263
    "  R[15] += 4;",
264
    "  MA (1);",
265
    "}",
266
    "else if (BANKN == 0)       /* Bank Underflow */",
267
    "  RAISE_EXCEPTION (SIGILL);",      /* FIXME: what exception? */
268
    "else {",
269
    "  SET_BANKN (BANKN - 1);",
270
    "  for (i = 0; i <= 14; i++)",
271
    "    R[i] = saved_state.asregs.regstack[BANKN].regs[i];",
272
    "  MACH = saved_state.asregs.regstack[BANKN].regs[15];",
273
    "  PR   = saved_state.asregs.regstack[BANKN].regs[17];",
274
    "  GBR  = saved_state.asregs.regstack[BANKN].regs[18];",
275
    "  MACL = saved_state.asregs.regstack[BANKN].regs[19];",
276
    "}",
277
  },
278
  { "f", "f-", "movml.l <REG_N>,@-R15", "0100nnnn11110001",
279
    "/* Push Rn...R0 (if n==15, push pr and R14...R0).  */",
280
    "do {",
281
    "  MA (1);",
282
    "  R[15] -= 4;",
283
    "  if (n == 15)",
284
    "    WLAT (R[15], PR);",
285
    "  else",
286
    "    WLAT (R[15], R[n]);",
287
    "} while (n-- > 0);",
288
  },
289
  { "f", "f+", "movml.l @R15+,<REG_N>", "0100nnnn11110101",
290
    "/* Pop R0...Rn (if n==15, pop R0...R14 and pr).  */",
291
    "int i = 0;\n",
292
    "do {",
293
    "  MA (1);",
294
    "  if (i == 15)",
295
    "    PR = RLAT (R[15]);",
296
    "  else",
297
    "    R[i] = RLAT (R[15]);",
298
    "  R[15] += 4;",
299
    "} while (i++ < n);",
300
  },
301
  { "f", "f-", "movmu.l <REG_N>,@-R15", "0100nnnn11110000",
302
    "/* Push pr, R14...Rn (if n==15, push pr).  */",    /* FIXME */
303
    "int i = 15;\n",
304
    "do {",
305
    "  MA (1);",
306
    "  R[15] -= 4;",
307
    "  if (i == 15)",
308
    "    WLAT (R[15], PR);",
309
    "  else",
310
    "    WLAT (R[15], R[i]);",
311
    "} while (i-- > n);",
312
  },
313
  { "f", "f+", "movmu.l @R15+,<REG_N>", "0100nnnn11110100",
314
    "/* Pop Rn...R14, pr (if n==15, pop pr).  */",      /* FIXME */
315
    "do {",
316
    "  MA (1);",
317
    "  if (n == 15)",
318
    "    PR = RLAT (R[15]);",
319
    "  else",
320
    "    R[n] = RLAT (R[15]);",
321
    "  R[15] += 4;",
322
    "} while (n++ < 15);",
323
  },
324
  { "", "", "nott", "0000000001101000",
325
    "SET_SR_T (T == 0);",
326
  },
327
 
328
  { "", "", "bt.s <bdisp8>", "10001101i8p1....",
329
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
330
    "if (T) {",
331
    "  SET_NIP (PC + 4 + (SEXT (i) * 2));",
332
    "  cycles += 2;",
333
    "  Delay_Slot (PC + 2);",
334
    "}",
335
  },
336
 
337
  { "", "", "clrmac", "0000000000101000",
338
    "MACH = 0;",
339
    "MACL = 0;",
340
  },
341
 
342
  { "", "", "clrs", "0000000001001000",
343
    "SET_SR_S (0);",
344
  },
345
 
346
  { "", "", "clrt", "0000000000001000",
347
    "SET_SR_T (0);",
348
  },
349
 
350
  /* sh4a */
351
  { "", "", "clrdmxy", "0000000010001000",
352
    "saved_state.asregs.cregs.named.sr &= ~(SR_MASK_DMX | SR_MASK_DMY);"
353
  },
354
 
355
  { "", "0", "cmp/eq #<imm>,R0", "10001000i8*1....",
356
    "SET_SR_T (R0 == SEXT (i));",
357
  },
358
  { "", "mn", "cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000",
359
    "SET_SR_T (R[n] == R[m]);",
360
  },
361
  { "", "mn", "cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011",
362
    "SET_SR_T (R[n] >= R[m]);",
363
  },
364
  { "", "mn", "cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111",
365
    "SET_SR_T (R[n] > R[m]);",
366
  },
367
  { "", "mn", "cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110",
368
    "SET_SR_T (UR[n] > UR[m]);",
369
  },
370
  { "", "mn", "cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010",
371
    "SET_SR_T (UR[n] >= UR[m]);",
372
  },
373
  { "", "n", "cmp/pl <REG_N>", "0100nnnn00010101",
374
    "SET_SR_T (R[n] > 0);",
375
  },
376
  { "", "n", "cmp/pz <REG_N>", "0100nnnn00010001",
377
    "SET_SR_T (R[n] >= 0);",
378
  },
379
  { "", "mn", "cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
380
    "ult = R[n] ^ R[m];",
381
    "SET_SR_T (((ult & 0xff000000) == 0)",
382
    "          | ((ult & 0xff0000) == 0)",
383
    "          | ((ult & 0xff00) == 0)",
384
    "          | ((ult & 0xff) == 0));",
385
  },
386
 
387
  { "", "mn", "div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111",
388
    "SET_SR_Q ((R[n] & sbit) != 0);",
389
    "SET_SR_M ((R[m] & sbit) != 0);",
390
    "SET_SR_T (M != Q);",
391
  },
392
 
393
  { "", "", "div0u", "0000000000011001",
394
    "SET_SR_M (0);",
395
    "SET_SR_Q (0);",
396
    "SET_SR_T (0);",
397
  },
398
 
399
  { "n", "nm", "div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100",
400
    "div1 (&R0, m, n/*, T*/);",
401
  },
402
 
403
  { "", "nm", "dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101",
404
    "dmul (1/*signed*/, R[n], R[m]);",
405
  },
406
 
407
  { "", "nm", "dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101",
408
    "dmul (0/*unsigned*/, R[n], R[m]);",
409
  },
410
 
411
  { "n", "n", "dt <REG_N>", "0100nnnn00010000",
412
    "R[n]--;",
413
    "SET_SR_T (R[n] == 0);",
414
  },
415
 
416
  { "n", "m", "exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110",
417
    "R[n] = SEXT (R[m]);",
418
  },
419
  { "n", "m", "exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111",
420
    "R[n] = SEXTW (R[m]);",
421
  },
422
 
423
  { "n", "m", "extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100",
424
    "R[n] = (R[m] & 0xff);",
425
  },
426
  { "n", "m", "extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101",
427
    "R[n] = (R[m] & 0xffff);",
428
  },
429
 
430
  /* sh2e */
431
  { "", "", "fabs <FREG_N>", "1111nnnn01011101",
432
    "FP_UNARY (n, fabs);",
433
    "/* FIXME: FR (n) &= 0x7fffffff; */",
434
  },
435
 
436
  /* sh2e */
437
  { "", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000",
438
    "FP_OP (n, +, m);",
439
  },
440
 
441
  /* sh2e */
442
  { "", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100",
443
    "FP_CMP (n, ==, m);",
444
  },
445
  /* sh2e */
446
  { "", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101",
447
    "FP_CMP (n, >, m);",
448
  },
449
 
450
  /* sh4 */
451
  { "", "", "fcnvds <DR_N>,FPUL", "1111nnnn10111101",
452
    "if (! FPSCR_PR || n & 1)",
453
    "  RAISE_EXCEPTION (SIGILL);",
454
    "else",
455
    "{",
456
    "  union",
457
    "  {",
458
    "    int i;",
459
    "    float f;",
460
    "  } u;",
461
    "  u.f = DR (n);",
462
    "  FPUL = u.i;",
463
    "}",
464
  },
465
 
466
  /* sh4 */
467
  { "", "", "fcnvsd FPUL,<DR_N>", "1111nnnn10101101",
468
    "if (! FPSCR_PR || n & 1)",
469
    "  RAISE_EXCEPTION (SIGILL);",
470
    "else",
471
    "{",
472
    "  union",
473
    "  {",
474
    "    int i;",
475
    "    float f;",
476
    "  } u;",
477
    "  u.i = FPUL;",
478
    "  SET_DR (n, u.f);",
479
    "}",
480
  },
481
 
482
  /* sh2e */
483
  { "", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011",
484
    "FP_OP (n, /, m);",
485
    "/* FIXME: check for DP and (n & 1) == 0?  */",
486
  },
487
 
488
  /* sh4 */
489
  { "", "", "fipr <FV_M>,<FV_N>", "1111vvVV11101101",
490
    "if (FPSCR_PR)",
491
    "  RAISE_EXCEPTION (SIGILL);",
492
    "else",
493
    "{",
494
    "  double fsum = 0;",
495
    "  if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
496
    "    RAISE_EXCEPTION (SIGILL);",
497
    "  /* FIXME: check for nans and infinities.  */",
498
    "  fsum += FR (v1+0) * FR (v2+0);",
499
    "  fsum += FR (v1+1) * FR (v2+1);",
500
    "  fsum += FR (v1+2) * FR (v2+2);",
501
    "  fsum += FR (v1+3) * FR (v2+3);",
502
    "  SET_FR (v1+3, fsum);",
503
    "}",
504
  },
505
 
506
  /* sh2e */
507
  { "", "", "fldi0 <FREG_N>", "1111nnnn10001101",
508
    "SET_FR (n, (float) 0.0);",
509
    "/* FIXME: check for DP and (n & 1) == 0?  */",
510
  },
511
 
512
  /* sh2e */
513
  { "", "", "fldi1 <FREG_N>", "1111nnnn10011101",
514
    "SET_FR (n, (float) 1.0);",
515
    "/* FIXME: check for DP and (n & 1) == 0?  */",
516
  },
517
 
518
  /* sh2e */
519
  { "", "", "flds <FREG_N>,FPUL", "1111nnnn00011101",
520
    "  union",
521
    "  {",
522
    "    int i;",
523
    "    float f;",
524
    "  } u;",
525
    "  u.f = FR (n);",
526
    "  FPUL = u.i;",
527
  },
528
 
529
  /* sh2e */
530
  { "", "", "float FPUL,<FREG_N>", "1111nnnn00101101",
531
    /* sh4 */
532
    "if (FPSCR_PR)",
533
    "  SET_DR (n, (double) FPUL);",
534
    "else",
535
    "{",
536
    "  SET_FR (n, (float) FPUL);",
537
    "}",
538
  },
539
 
540
  /* sh2e */
541
  { "", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110",
542
    "SET_FR (n, FR (m) * FR (0) + FR (n));",
543
    "/* FIXME: check for DP and (n & 1) == 0? */",
544
  },
545
 
546
  /* sh2e */
547
  { "", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100",
548
    /* sh4 */
549
    "if (FPSCR_SZ) {",
550
    "  int ni = XD_TO_XF (n);",
551
    "  int mi = XD_TO_XF (m);",
552
    "  SET_XF (ni + 0, XF (mi + 0));",
553
    "  SET_XF (ni + 1, XF (mi + 1));",
554
    "}",
555
    "else",
556
    "{",
557
    "  SET_FR (n, FR (m));",
558
    "}",
559
  },
560
  /* sh2e */
561
  { "", "n", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010",
562
    /* sh4 */
563
    "if (FPSCR_SZ) {",
564
    "  MA (2);",
565
    "  WDAT (R[n], m);",
566
    "}",
567
    "else",
568
    "{",
569
    "  MA (1);",
570
    "  WLAT (R[n], FI (m));",
571
    "}",
572
  },
573
  /* sh2e */
574
  { "", "m", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000",
575
    /* sh4 */
576
    "if (FPSCR_SZ) {",
577
    "  MA (2);",
578
    "  RDAT (R[m], n);",
579
    "}",
580
    "else",
581
    "{",
582
    "  MA (1);",
583
    "  SET_FI (n, RLAT (R[m]));",
584
    "}",
585
  },
586
  /* sh2a */
587
  { "", "n", "fmov.s @(disp12,<REG_N>), <FREG_M>", "0011nnnnmmmm0001",
588
    "/* and fmov.s <FREG_N>, @(disp12,<FREG_M>)",
589
    "   and mov.bwl <REG_N>, @(disp12,<REG_M>)",
590
    "   and mov.bwl @(disp12,<REG_N>),<REG_M>",
591
    "   and movu.bw @(disp12,<REG_N>),<REG_M>.  */",
592
    "int word2 = RIAT (nip);",
593
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
594
    "SET_NIP (nip + 2); /* Consume 2 more bytes.  */",
595
    "MA (1);",
596
    "do_long_move_insn (word2 & 0xf000, word2 & 0x0fff, m, n, &thislock);",
597
  },
598
  /* sh2e */
599
  { "m", "m", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001",
600
    /* sh4 */
601
    "if (FPSCR_SZ) {",
602
    "  MA (2);",
603
    "  RDAT (R[m], n);",
604
    "  R[m] += 8;",
605
    "}",
606
    "else",
607
    "{",
608
    "  MA (1);",
609
    "  SET_FI (n, RLAT (R[m]));",
610
    "  R[m] += 4;",
611
    "}",
612
  },
613
  /* sh2e */
614
  { "n", "n", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011",
615
    /* sh4 */
616
    "if (FPSCR_SZ) {",
617
    "  MA (2);",
618
    "  R[n] -= 8;",
619
    "  WDAT (R[n], m);",
620
    "}",
621
    "else",
622
    "{",
623
    "  MA (1);",
624
    "  R[n] -= 4;",
625
    "  WLAT (R[n], FI (m));",
626
    "}",
627
  },
628
  /* sh2e */
629
  { "", "0m", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110",
630
    /* sh4 */
631
    "if (FPSCR_SZ) {",
632
    "  MA (2);",
633
    "  RDAT (R[0]+R[m], n);",
634
    "}",
635
    "else",
636
    "{",
637
    "  MA (1);",
638
    "  SET_FI (n, RLAT (R[0] + R[m]));",
639
    "}",
640
  },
641
  /* sh2e */
642
  { "", "0n", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111",
643
    /* sh4 */
644
    "if (FPSCR_SZ) {",
645
    "  MA (2);",
646
    "  WDAT (R[0]+R[n], m);",
647
    "}",
648
    "else",
649
    "{",
650
    "  MA (1);",
651
    "  WLAT ((R[0]+R[n]), FI (m));",
652
    "}",
653
  },
654
 
655
  /* sh4:
656
     See fmov instructions above for move to/from extended fp registers.  */
657
 
658
  /* sh2e */
659
  { "", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010",
660
    "FP_OP (n, *, m);",
661
  },
662
 
663
  /* sh2e */
664
  { "", "", "fneg <FREG_N>", "1111nnnn01001101",
665
    "FP_UNARY (n, -);",
666
  },
667
 
668
  /* sh4a */
669
  { "", "", "fpchg", "1111011111111101",
670
    "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_PR);",
671
  },
672
 
673
  /* sh4 */
674
  { "", "", "frchg", "1111101111111101",
675
    "if (FPSCR_PR)",
676
    "  RAISE_EXCEPTION (SIGILL);",
677
    "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
678
    "  RAISE_EXCEPTION (SIGILL);",
679
    "else",
680
    "  SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_FR);",
681
  },
682
 
683
  /* sh4 */
684
  { "", "", "fsca", "1111eeee11111101",
685
    "if (FPSCR_PR)",
686
    "  RAISE_EXCEPTION (SIGILL);",
687
    "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
688
    "  RAISE_EXCEPTION (SIGILL);",
689
    "else",
690
    "  {",
691
    "    SET_FR (n, fsca_s (FPUL, &sin));",
692
    "    SET_FR (n+1, fsca_s (FPUL, &cos));",
693
    "  }",
694
  },
695
 
696
  /* sh4 */
697
  { "", "", "fschg", "1111001111111101",
698
    "SET_FPSCR (GET_FPSCR () ^ FPSCR_MASK_SZ);",
699
  },
700
 
701
  /* sh3e */
702
  { "", "", "fsqrt <FREG_N>", "1111nnnn01101101",
703
    "FP_UNARY (n, sqrt);",
704
  },
705
 
706
  /* sh4 */
707
  { "", "", "fsrra <FREG_N>", "1111nnnn01111101",
708
    "if (FPSCR_PR)",
709
    "  RAISE_EXCEPTION (SIGILL);",
710
    "else if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
711
    "  RAISE_EXCEPTION (SIGILL);",
712
    "else",
713
    "  SET_FR (n, fsrra_s (FR (n)));",
714
  },
715
 
716
  /* sh2e */
717
  { "", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001",
718
    "FP_OP (n, -, m);",
719
  },
720
 
721
  /* sh2e */
722
  { "", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101",
723
    /* sh4 */
724
    "if (FPSCR_PR) {",
725
    "  if (DR (n) != DR (n)) /* NaN */",
726
    "    FPUL = 0x80000000;",
727
    "  else",
728
    "    FPUL =  (int) DR (n);",
729
    "}",
730
    "else",
731
    "if (FR (n) != FR (n)) /* NaN */",
732
    "  FPUL = 0x80000000;",
733
    "else",
734
    "  FPUL = (int) FR (n);",
735
  },
736
 
737
  /* sh4 */
738
  { "", "", "ftrv <FV_N>", "1111vv0111111101",
739
    "if (FPSCR_PR)",
740
    "  RAISE_EXCEPTION (SIGILL);",
741
    "else",
742
    "{",
743
    "  if (saved_state.asregs.bfd_mach == bfd_mach_sh2a)",
744
    "    RAISE_EXCEPTION (SIGILL);",
745
    "  /* FIXME not implemented.  */",
746
    "  printf (\"ftrv xmtrx, FV%d\\n\", v1);",
747
    "}",
748
  },
749
 
750
  /* sh2e */
751
  { "", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101",
752
    "  union",
753
    "  {",
754
    "    int i;",
755
    "    float f;",
756
    "  } u;",
757
    "  u.i = FPUL;",
758
    "  SET_FR (n, u.f);",
759
  },
760
 
761
  { "", "n", "jmp @<REG_N>", "0100nnnn00101011",
762
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
763
    "SET_NIP (PT2H (R[n]));",
764
    "cycles += 2;",
765
    "Delay_Slot (PC + 2);",
766
  },
767
 
768
  { "", "n", "jsr @<REG_N>", "0100nnnn00001011",
769
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
770
    "PR = PH2T (PC + 4);",
771
    "if (~doprofile)",
772
    "  gotcall (PR, R[n]);",
773
    "SET_NIP (PT2H (R[n]));",
774
    "cycles += 2;",
775
    "Delay_Slot (PC + 2);",
776
  },
777
  { "", "n", "jsr/n @<REG_N>", "0100nnnn01001011",
778
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
779
    "PR = PH2T (PC + 2);",
780
    "if (~doprofile)",
781
    "  gotcall (PR, R[n]);",
782
    "SET_NIP (PT2H (R[n]));",
783
  },
784
  { "", "", "jsr/n @@(<disp>,TBR)", "10000011i8p4....",
785
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
786
    "PR = PH2T (PC + 2);",
787
    "if (~doprofile)",
788
    "  gotcall (PR, i + TBR);",
789
    "SET_NIP (PT2H (i + TBR));",
790
  },
791
 
792
  { "", "n", "ldc <REG_N>,<CREG_M>", "0100nnnnmmmm1110",
793
    "CREG (m) = R[n];",
794
    "/* FIXME: user mode */",
795
  },
796
  { "", "n", "ldc <REG_N>,SR", "0100nnnn00001110",
797
    "SET_SR (R[n]);",
798
    "/* FIXME: user mode */",
799
  },
800
  { "", "n", "ldc <REG_N>,MOD", "0100nnnn01011110",
801
    "SET_MOD (R[n]);",
802
  },
803
  { "", "n", "ldc <REG_N>,DBR", "0100nnnn11111010",
804
    "if (SR_MD)",
805
    "  DBR = R[n]; /* priv mode */",
806
    "else",
807
    "  RAISE_EXCEPTION (SIGILL); /* user mode */",
808
  },
809
  { "", "n", "ldc <REG_N>,SGR", "0100nnnn00111010",
810
    "if (SR_MD)",
811
    "  SGR = R[n]; /* priv mode */",
812
    "else",
813
    "  RAISE_EXCEPTION (SIGILL); /* user mode */",
814
  },
815
  { "", "n", "ldc <REG_N>,TBR", "0100nnnn01001010",
816
    "if (SR_MD)",       /* FIXME? */
817
    "  TBR = R[n]; /* priv mode */",
818
    "else",
819
    "  RAISE_EXCEPTION (SIGILL); /* user mode */",
820
  },
821
  { "n", "n", "ldc.l @<REG_N>+,<CREG_M>", "0100nnnnmmmm0111",
822
    "MA (1);",
823
    "CREG (m) = RLAT (R[n]);",
824
    "R[n] += 4;",
825
    "/* FIXME: user mode */",
826
  },
827
  { "n", "n", "ldc.l @<REG_N>+,SR", "0100nnnn00000111",
828
    "MA (1);",
829
    "SET_SR (RLAT (R[n]));",
830
    "R[n] += 4;",
831
    "/* FIXME: user mode */",
832
  },
833
  { "n", "n", "ldc.l @<REG_N>+,MOD", "0100nnnn01010111",
834
    "MA (1);",
835
    "SET_MOD (RLAT (R[n]));",
836
    "R[n] += 4;",
837
  },
838
  { "n", "n", "ldc.l @<REG_N>+,DBR", "0100nnnn11110110",
839
    "if (SR_MD)",
840
    "{ /* priv mode */",
841
    "  MA (1);",
842
    "  DBR = RLAT (R[n]);",
843
    "  R[n] += 4;",
844
    "}",
845
    "else",
846
    "  RAISE_EXCEPTION (SIGILL); /* user mode */",
847
  },
848
  { "n", "n", "ldc.l @<REG_N>+,SGR", "0100nnnn00110110",
849
    "if (SR_MD)",
850
    "{ /* priv mode */",
851
    "  MA (1);",
852
    "  SGR = RLAT (R[n]);",
853
    "  R[n] += 4;",
854
    "}",
855
    "else",
856
    "  RAISE_EXCEPTION (SIGILL); /* user mode */",
857
  },
858
 
859
  /* sh-dsp */
860
  { "", "", "ldre @(<disp>,PC)", "10001110i8p1....",
861
    "RE = SEXT (i) * 2 + 4 + PH2T (PC);",
862
  },
863
  { "", "", "ldrs @(<disp>,PC)", "10001100i8p1....",
864
    "RS = SEXT (i) * 2 + 4 + PH2T (PC);",
865
  },
866
 
867
  /* sh4a */
868
  { "", "n", "ldrc <REG_N>", "0100nnnn00110100",
869
    "SET_RC (R[n]);",
870
    "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
871
    "CHECK_INSN_PTR (insn_ptr);",
872
    "RE |= 1;",
873
  },
874
  { "", "", "ldrc #<imm>", "10001010i8*1....",
875
    "SET_RC (i);",
876
    "loop = get_loop_bounds_ext (RS, RE, memory, mem_end, maskw, endianw);",
877
    "CHECK_INSN_PTR (insn_ptr);",
878
    "RE |= 1;",
879
  },
880
 
881
  { "", "n", "lds <REG_N>,<SREG_M>", "0100nnnnssss1010",
882
    "SREG (m) = R[n];",
883
  },
884
  { "n", "n", "lds.l @<REG_N>+,<SREG_M>", "0100nnnnssss0110",
885
    "MA (1);",
886
    "SREG (m) = RLAT (R[n]);",
887
    "R[n] += 4;",
888
  },
889
  /* sh2e / sh-dsp (lds <REG_N>,DSR) */
890
  { "", "n", "lds <REG_N>,FPSCR", "0100nnnn01101010",
891
    "SET_FPSCR (R[n]);",
892
  },
893
  /* sh2e / sh-dsp (lds.l @<REG_N>+,DSR) */
894
  { "n", "n", "lds.l @<REG_N>+,FPSCR", "0100nnnn01100110",
895
    "MA (1);",
896
    "SET_FPSCR (RLAT (R[n]));",
897
    "R[n] += 4;",
898
  },
899
 
900
  { "", "", "ldtlb", "0000000000111000",
901
    "/* We don't implement cache or tlb, so this is a noop.  */",
902
  },
903
 
904
  { "nm", "nm", "mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111",
905
    "macl (&R0, memory, n, m);",
906
  },
907
 
908
  { "nm", "nm", "mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111",
909
    "macw (&R0, memory, n, m, endianw);",
910
  },
911
 
912
  { "n", "", "mov #<imm>,<REG_N>", "1110nnnni8*1....",
913
    "R[n] = SEXT (i);",
914
  },
915
  { "n", "", "movi20 #<imm20>,<REG_N>", "0000nnnni8*10000",
916
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
917
    "R[n] = ((i << 24) >> 12) | RIAT (nip);",
918
    "SET_NIP (nip + 2); /* Consume 2 more bytes.  */",
919
  },
920
  { "n", "", "movi20s #<imm20>,<REG_N>", "0000nnnni8*10001",
921
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
922
    "R[n] = ((((i & 0xf0) << 24) >> 12) | RIAT (nip)) << 8;",
923
    "SET_NIP (nip + 2); /* Consume 2 more bytes.  */",
924
  },
925
  { "n", "m", "mov <REG_M>,<REG_N>", "0110nnnnmmmm0011",
926
    "R[n] = R[m];",
927
  },
928
 
929
  { "0", "", "mov.b @(<disp>,GBR),R0", "11000100i8*1....",
930
    "MA (1);",
931
    "R0 = RSBAT (i + GBR);",
932
    "L (0);",
933
  },
934
  { "0", "m", "mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1",
935
    "MA (1);",
936
    "R0 = RSBAT (i + R[m]);",
937
    "L (0);",
938
  },
939
  { "n", "0m", "mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100",
940
    "MA (1);",
941
    "R[n] = RSBAT (R0 + R[m]);",
942
    "L (n);",
943
  },
944
  { "nm", "m", "mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100",
945
    "MA (1);",
946
    "R[n] = RSBAT (R[m]);",
947
    "R[m] += 1;",
948
    "L (n);",
949
  },
950
  { "0n", "n", "mov.b @-<REG_N>,R0", "0100nnnn11001011",
951
    "MA (1);",
952
    "R[n] -= 1;",
953
    "R0 = RSBAT (R[n]);",
954
    "L (0);",
955
  },
956
  { "", "mn", "mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000",
957
    "MA (1);",
958
    "WBAT (R[n], R[m]);",
959
  },
960
  { "", "0", "mov.b R0,@(<disp>,GBR)", "11000000i8*1....",
961
    "MA (1);",
962
    "WBAT (i + GBR, R0);",
963
  },
964
  { "", "m0", "mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1",
965
    "MA (1);",
966
    "WBAT (i + R[m], R0);",
967
  },
968
  { "", "mn0", "mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100",
969
    "MA (1);",
970
    "WBAT (R[n] + R0, R[m]);",
971
  },
972
  { "n", "nm", "mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100",
973
    /* Allow for the case where m == n.  */
974
    "int t = R[m];",
975
    "MA (1);",
976
    "R[n] -= 1;",
977
    "WBAT (R[n], t);",
978
  },
979
  { "n", "n0", "mov.b R0,@<REG_N>+", "0100nnnn10001011",
980
    "MA (1);",
981
    "WBAT (R[n], R0);",
982
    "R[n] += 1;",
983
  },
984
  { "n", "m", "mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000",
985
    "MA (1);",
986
    "R[n] = RSBAT (R[m]);",
987
    "L (n);",
988
  },
989
 
990
  { "0", "", "mov.l @(<disp>,GBR),R0", "11000110i8*4....",
991
    "MA (1);",
992
    "R0 = RLAT (i + GBR);",
993
    "L (0);",
994
  },
995
  { "n", "", "mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....",
996
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
997
    "MA (1);",
998
    "R[n] = RLAT ((PH2T (PC) & ~3) + 4 + i);",
999
    "L (n);",
1000
  },
1001
  { "n", "m", "mov.l @(<disp>,<REG_M>),<REG_N>", "0101nnnnmmmmi4*4",
1002
    "MA (1);",
1003
    "R[n] = RLAT (i + R[m]);",
1004
    "L (n);",
1005
  },
1006
  { "n", "m0", "mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110",
1007
    "MA (1);",
1008
    "R[n] = RLAT (R0 + R[m]);",
1009
    "L (n);",
1010
  },
1011
  { "nm", "m", "mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110",
1012
    "MA (1);",
1013
    "R[n] = RLAT (R[m]);",
1014
    "R[m] += 4;",
1015
    "L (n);",
1016
  },
1017
  { "0n", "n", "mov.l @-<REG_N>,R0", "0100nnnn11101011",
1018
    "MA (1);",
1019
    "R[n] -= 4;",
1020
    "R0 = RLAT (R[n]);",
1021
    "L (0);",
1022
  },
1023
  { "n", "m", "mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010",
1024
    "MA (1);",
1025
    "R[n] = RLAT (R[m]);",
1026
    "L (n);",
1027
  },
1028
  { "", "0", "mov.l R0,@(<disp>,GBR)", "11000010i8*4....",
1029
    "MA (1);",
1030
    "WLAT (i + GBR, R0);",
1031
  },
1032
  { "", "nm", "mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4",
1033
    "MA (1);",
1034
    "WLAT (i + R[n], R[m]);",
1035
  },
1036
  { "", "nm0", "mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110",
1037
    "MA (1);",
1038
    "WLAT (R0 + R[n], R[m]);",
1039
  },
1040
  { "n", "nm", "mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110",
1041
    /* Allow for the case where m == n.  */
1042
    "int t = R[m];",
1043
    "MA (1) ;",
1044
    "R[n] -= 4;",
1045
    "WLAT (R[n], t);",
1046
  },
1047
  { "n", "n0", "mov.l R0,@<REG_N>+", "0100nnnn10101011",
1048
    "MA (1) ;",
1049
    "WLAT (R[n], R0);",
1050
    "R[n] += 4;",
1051
  },
1052
  { "", "nm", "mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010",
1053
    "MA (1);",
1054
    "WLAT (R[n], R[m]);",
1055
  },
1056
 
1057
  { "0", "", "mov.w @(<disp>,GBR),R0", "11000101i8*2....",
1058
    "MA (1);",
1059
    "R0 = RSWAT (i + GBR);",
1060
    "L (0);",
1061
  },
1062
  { "n", "", "mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....",
1063
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1064
    "MA (1);",
1065
    "R[n] = RSWAT (PH2T (PC + 4 + i));",
1066
    "L (n);",
1067
  },
1068
  { "0", "m", "mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2",
1069
    "MA (1);",
1070
    "R0 = RSWAT (i + R[m]);",
1071
    "L (0);",
1072
  },
1073
  { "n", "m0", "mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101",
1074
    "MA (1);",
1075
    "R[n] = RSWAT (R0 + R[m]);",
1076
    "L (n);",
1077
  },
1078
  { "nm", "n", "mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101",
1079
    "MA (1);",
1080
    "R[n] = RSWAT (R[m]);",
1081
    "R[m] += 2;",
1082
    "L (n);",
1083
  },
1084
  { "0n", "n", "mov.w @-<REG_N>,R0", "0100nnnn11011011",
1085
    "MA (1);",
1086
    "R[n] -= 2;",
1087
    "R0 = RSWAT (R[n]);",
1088
    "L (0);",
1089
  },
1090
  { "n", "m", "mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001",
1091
    "MA (1);",
1092
    "R[n] = RSWAT (R[m]);",
1093
    "L (n);",
1094
  },
1095
  { "", "0", "mov.w R0,@(<disp>,GBR)", "11000001i8*2....",
1096
    "MA (1);",
1097
    "WWAT (i + GBR, R0);",
1098
  },
1099
  { "", "0m", "mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2",
1100
    "MA (1);",
1101
    "WWAT (i + R[m], R0);",
1102
  },
1103
  { "", "m0n", "mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101",
1104
    "MA (1);",
1105
    "WWAT (R0 + R[n], R[m]);",
1106
  },
1107
  { "n", "mn", "mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101",
1108
    /* Allow for the case where m == n.  */
1109
    "int t = R[m];",
1110
    "MA (1);",
1111
    "R[n] -= 2;",
1112
    "WWAT (R[n], t);",
1113
  },
1114
  { "n", "0n", "mov.w R0,@<REG_N>+", "0100nnnn10011011",
1115
    "MA (1);",
1116
    "WWAT (R[n], R0);",
1117
    "R[n] += 2;",
1118
  },
1119
  { "", "nm", "mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001",
1120
    "MA (1);",
1121
    "WWAT (R[n], R[m]);",
1122
  },
1123
 
1124
  { "0", "", "mova @(<disp>,PC),R0", "11000111i8p4....",
1125
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1126
    "R0 = ((i + 4 + PH2T (PC)) & ~0x3);",
1127
  },
1128
 
1129
  { "", "n0", "movca.l R0, @<REG_N>", "0000nnnn11000011",
1130
    "/* We don't simulate cache, so this insn is identical to mov.  */",
1131
    "MA (1);",
1132
    "WLAT (R[n], R[0]);",
1133
  },
1134
 
1135
  { "", "n0", "movco.l R0, @<REG_N>", "0000nnnn01110011",
1136
    "/* LDST -> T */",
1137
    "SET_SR_T (LDST);",
1138
    "/* if (T) R0 -> (Rn) */",
1139
    "if (T)",
1140
    "  WLAT (R[n], R[0]);",
1141
    "/* 0 -> LDST */",
1142
    "SET_LDST (0);",
1143
  },
1144
 
1145
  { "0", "n", "movli.l @<REG_N>, R0", "0000nnnn01100011",
1146
    "/* 1 -> LDST */",
1147
    "SET_LDST (1);",
1148
    "/* (Rn) -> R0 */",
1149
    "R[0] = RLAT (R[n]);",
1150
    "/* if (interrupt/exception) 0 -> LDST */",
1151
    "/* (we don't simulate asynchronous interrupts/exceptions) */",
1152
  },
1153
 
1154
  { "n", "", "movt <REG_N>", "0000nnnn00101001",
1155
    "R[n] = T;",
1156
  },
1157
  { "", "", "movrt <REG_N>", "0000nnnn00111001",
1158
    "R[n] = (T == 0);",
1159
  },
1160
  { "0", "n", "movua.l @<REG_N>,R0", "0100nnnn10101001",
1161
    "int regn = R[n];",
1162
    "int e = target_little_endian ? 3 : 0;",
1163
    "MA (1);",
1164
    "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1165
    "  (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1166
    "L (0);",
1167
  },
1168
  { "0n", "n", "movua.l @<REG_N>+,R0", "0100nnnn11101001",
1169
    "int regn = R[n];",
1170
    "int e = target_little_endian ? 3 : 0;",
1171
    "MA (1);",
1172
    "R[0] = (RBAT (regn + (0^e)) << 24) + (RBAT (regn + (1^e)) << 16) + ",
1173
    "  (RBAT (regn + (2^e)) << 8) + RBAT (regn + (3^e));",
1174
    "R[n] += 4;",
1175
    "L (0);",
1176
  },
1177
  { "", "mn", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1178
    "MACL = ((int) R[n]) * ((int) R[m]);",
1179
  },
1180
#if 0  /* FIXME: The above cast to int is not really portable.
1181
          It should be replaced by a SEXT32 macro.  */
1182
  { "", "nm", "mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111",
1183
    "MACL = R[n] * R[m];",
1184
  },
1185
#endif
1186
 
1187
  /* muls.w - see muls */
1188
  { "", "mn", "muls <REG_M>,<REG_N>", "0010nnnnmmmm1111",
1189
    "MACL = ((int) (short) R[n]) * ((int) (short) R[m]);",
1190
  },
1191
 
1192
  /* mulu.w - see mulu */
1193
  { "", "mn", "mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110",
1194
    "MACL = (((unsigned int) (unsigned short) R[n])",
1195
    "        * ((unsigned int) (unsigned short) R[m]));",
1196
  },
1197
 
1198
  { "n", "m", "neg <REG_M>,<REG_N>", "0110nnnnmmmm1011",
1199
    "R[n] = - R[m];",
1200
  },
1201
 
1202
  { "n", "m", "negc <REG_M>,<REG_N>", "0110nnnnmmmm1010",
1203
    "ult = -T;",
1204
    "SET_SR_T (ult > 0);",
1205
    "R[n] = ult - R[m];",
1206
    "SET_SR_T (T || (R[n] > ult));",
1207
  },
1208
 
1209
  { "", "", "nop", "0000000000001001",
1210
    "/* nop */",
1211
  },
1212
 
1213
  { "n", "m", "not <REG_M>,<REG_N>", "0110nnnnmmmm0111",
1214
    "R[n] = ~R[m];",
1215
  },
1216
 
1217
  /* sh4a */
1218
  { "", "n", "icbi @<REG_N>", "0000nnnn11100011",
1219
    "/* Except for the effect on the cache - which is not simulated -",
1220
    "   this is like a nop.  */",
1221
  },
1222
 
1223
  { "", "n", "ocbi @<REG_N>", "0000nnnn10010011",
1224
    "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop.  */",
1225
    "/* FIXME: Cache not implemented */",
1226
  },
1227
 
1228
  { "", "n", "ocbp @<REG_N>", "0000nnnn10100011",
1229
    "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop.  */",
1230
    "/* FIXME: Cache not implemented */",
1231
  },
1232
 
1233
  { "", "n", "ocbwb @<REG_N>", "0000nnnn10110011",
1234
    "RSBAT (R[n]); /* Take exceptions like byte load, otherwise noop.  */",
1235
    "/* FIXME: Cache not implemented */",
1236
  },
1237
 
1238
  { "0", "", "or #<imm>,R0", "11001011i8*1....",
1239
    "R0 |= i;",
1240
  },
1241
  { "n", "m", "or <REG_M>,<REG_N>", "0010nnnnmmmm1011",
1242
    "R[n] |= R[m];",
1243
  },
1244
  { "", "0", "or.b #<imm>,@(R0,GBR)", "11001111i8*1....",
1245
    "MA (1);",
1246
    "WBAT (R0 + GBR, (RBAT (R0 + GBR) | i));",
1247
  },
1248
 
1249
  { "", "n", "pref @<REG_N>", "0000nnnn10000011",
1250
    "/* Except for the effect on the cache - which is not simulated -",
1251
    "   this is like a nop.  */",
1252
  },
1253
 
1254
  /* sh4a */
1255
  { "", "n", "prefi @<REG_N>", "0000nnnn11010011",
1256
    "/* Except for the effect on the cache - which is not simulated -",
1257
    "   this is like a nop.  */",
1258
  },
1259
 
1260
  /* sh4a */
1261
  { "", "", "synco", "0000000010101011",
1262
    "/* Except for the effect on the pipeline - which is not simulated -",
1263
    "   this is like a nop.  */",
1264
  },
1265
 
1266
  { "n", "n", "rotcl <REG_N>", "0100nnnn00100100",
1267
    "ult = R[n] < 0;",
1268
    "R[n] = (R[n] << 1) | T;",
1269
    "SET_SR_T (ult);",
1270
  },
1271
 
1272
  { "n", "n", "rotcr <REG_N>", "0100nnnn00100101",
1273
    "ult = R[n] & 1;",
1274
    "R[n] = (UR[n] >> 1) | (T << 31);",
1275
    "SET_SR_T (ult);",
1276
  },
1277
 
1278
  { "n", "n", "rotl <REG_N>", "0100nnnn00000100",
1279
    "SET_SR_T (R[n] < 0);",
1280
    "R[n] <<= 1;",
1281
    "R[n] |= T;",
1282
  },
1283
 
1284
  { "n", "n", "rotr <REG_N>", "0100nnnn00000101",
1285
    "SET_SR_T (R[n] & 1);",
1286
    "R[n] = UR[n] >> 1;",
1287
    "R[n] |= (T << 31);",
1288
  },
1289
 
1290
  { "", "", "rte", "0000000000101011",
1291
#if 0
1292
    /* SH-[12] */
1293
    "int tmp = PC;",
1294
    "SET_NIP (PT2H (RLAT (R[15]) + 2));",
1295
    "R[15] += 4;",
1296
    "SET_SR (RLAT (R[15]) & 0x3f3);",
1297
    "R[15] += 4;",
1298
    "Delay_Slot (PC + 2);",
1299
#else
1300
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1301
    "SET_SR (SSR);",
1302
    "SET_NIP (PT2H (SPC));",
1303
    "cycles += 2;",
1304
    "Delay_Slot (PC + 2);",
1305
#endif
1306
  },
1307
 
1308
  { "", "", "rts", "0000000000001011",
1309
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1310
    "SET_NIP (PT2H (PR));",
1311
    "cycles += 2;",
1312
    "Delay_Slot (PC + 2);",
1313
  },
1314
  { "", "", "rts/n", "0000000001101011",
1315
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1316
    "SET_NIP (PT2H (PR));",
1317
  },
1318
  { "0", "n", "rtv/n <REG_N>", "0000nnnn01111011",
1319
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1320
    "R0 = R[n];",
1321
    "L (0);",
1322
    "SET_NIP (PT2H (PR));",
1323
  },
1324
 
1325
  /* sh4a */
1326
  { "", "", "setdmx", "0000000010011000",
1327
    "saved_state.asregs.cregs.named.sr |=  SR_MASK_DMX;"
1328
    "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMY;"
1329
  },
1330
 
1331
  /* sh4a */
1332
  { "", "", "setdmy", "0000000011001000",
1333
    "saved_state.asregs.cregs.named.sr |=  SR_MASK_DMY;"
1334
    "saved_state.asregs.cregs.named.sr &= ~SR_MASK_DMX;"
1335
  },
1336
 
1337
  /* sh-dsp */
1338
  { "", "n", "setrc <REG_N>", "0100nnnn00010100",
1339
    "SET_RC (R[n]);",
1340
  },
1341
  { "", "", "setrc #<imm>", "10000010i8*1....",
1342
    /* It would be more realistic to let loop_start point to some static
1343
       memory that contains an illegal opcode and then give a bus error when
1344
       the loop is eventually encountered, but it seems not only simpler,
1345
       but also more debugging-friendly to just catch the failure here.  */
1346
    "if (BUSERROR (RS | RE, maskw))",
1347
    "  RAISE_EXCEPTION (SIGILL);",
1348
    "else {",
1349
    "  SET_RC (i);",
1350
    "  loop = get_loop_bounds (RS, RE, memory, mem_end, maskw, endianw);",
1351
    "  CHECK_INSN_PTR (insn_ptr);",
1352
    "}",
1353
  },
1354
 
1355
  { "", "", "sets", "0000000001011000",
1356
    "SET_SR_S (1);",
1357
  },
1358
 
1359
  { "", "", "sett", "0000000000011000",
1360
    "SET_SR_T (1);",
1361
  },
1362
 
1363
  { "n", "mn", "shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
1364
    "R[n] = (R[m] < 0) ? (R[m]&0x1f ? R[n] >> ((-R[m])&0x1f) : R[n] >> 31) : (R[n] << (R[m] & 0x1f));",
1365
  },
1366
 
1367
  { "n", "n", "shal <REG_N>", "0100nnnn00100000",
1368
    "SET_SR_T (R[n] < 0);",
1369
    "R[n] <<= 1;",
1370
  },
1371
 
1372
  { "n", "n", "shar <REG_N>", "0100nnnn00100001",
1373
    "SET_SR_T (R[n] & 1);",
1374
    "R[n] = R[n] >> 1;",
1375
  },
1376
 
1377
  { "n", "mn", "shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1378
    "R[n] = (R[m] < 0) ? (R[m]&0x1f ? UR[n] >> ((-R[m])&0x1f) : 0): (R[n] << (R[m] & 0x1f));",
1379
  },
1380
 
1381
  { "n", "n", "shll <REG_N>", "0100nnnn00000000",
1382
    "SET_SR_T (R[n] < 0);",
1383
    "R[n] <<= 1;",
1384
  },
1385
 
1386
  { "n", "n", "shll2 <REG_N>", "0100nnnn00001000",
1387
    "R[n] <<= 2;",
1388
  },
1389
  { "n", "n", "shll8 <REG_N>", "0100nnnn00011000",
1390
    "R[n] <<= 8;",
1391
  },
1392
  { "n", "n", "shll16 <REG_N>", "0100nnnn00101000",
1393
    "R[n] <<= 16;",
1394
  },
1395
 
1396
  { "n", "n", "shlr <REG_N>", "0100nnnn00000001",
1397
    "SET_SR_T (R[n] & 1);",
1398
    "R[n] = UR[n] >> 1;",
1399
  },
1400
 
1401
  { "n", "n", "shlr2 <REG_N>", "0100nnnn00001001",
1402
    "R[n] = UR[n] >> 2;",
1403
  },
1404
  { "n", "n", "shlr8 <REG_N>", "0100nnnn00011001",
1405
    "R[n] = UR[n] >> 8;",
1406
  },
1407
  { "n", "n", "shlr16 <REG_N>", "0100nnnn00101001",
1408
    "R[n] = UR[n] >> 16;",
1409
  },
1410
 
1411
  { "", "", "sleep", "0000000000011011",
1412
    "nip += trap (0xc3, &R0, PC, memory, maskl, maskw, endianw);",
1413
  },
1414
 
1415
  { "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
1416
    "R[n] = CREG (m);",
1417
  },
1418
 
1419
  { "n", "", "stc SGR,<REG_N>", "0000nnnn00111010",
1420
    "if (SR_MD)",
1421
    "  R[n] = SGR; /* priv mode */",
1422
    "else",
1423
    "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1424
  },
1425
  { "n", "", "stc DBR,<REG_N>", "0000nnnn11111010",
1426
    "if (SR_MD)",
1427
    "  R[n] = DBR; /* priv mode */",
1428
    "else",
1429
    "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1430
  },
1431
  { "n", "", "stc TBR,<REG_N>", "0000nnnn01001010",
1432
    "if (SR_MD)",       /* FIXME? */
1433
    "  R[n] = TBR; /* priv mode */",
1434
    "else",
1435
    "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1436
  },
1437
  { "n", "n", "stc.l <CREG_M>,@-<REG_N>", "0100nnnnmmmm0011",
1438
    "MA (1);",
1439
    "R[n] -= 4;",
1440
    "WLAT (R[n], CREG (m));",
1441
  },
1442
  { "n", "n", "stc.l SGR,@-<REG_N>", "0100nnnn00110010",
1443
    "if (SR_MD)",
1444
    "{ /* priv mode */",
1445
    "  MA (1);",
1446
    "  R[n] -= 4;",
1447
    "  WLAT (R[n], SGR);",
1448
    "}",
1449
    "else",
1450
    "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1451
  },
1452
  { "n", "n", "stc.l DBR,@-<REG_N>", "0100nnnn11110010",
1453
    "if (SR_MD)",
1454
    "{ /* priv mode */",
1455
    "  MA (1);",
1456
    "  R[n] -= 4;",
1457
    "  WLAT (R[n], DBR);",
1458
    "}",
1459
    "else",
1460
    "  RAISE_EXCEPTION (SIGILL); /* user mode */",
1461
  },
1462
 
1463
  { "n", "", "sts <SREG_M>,<REG_N>", "0000nnnnssss1010",
1464
    "R[n] = SREG (m);",
1465
  },
1466
  { "n", "n", "sts.l <SREG_M>,@-<REG_N>", "0100nnnnssss0010",
1467
    "MA (1);",
1468
    "R[n] -= 4;",
1469
    "WLAT (R[n], SREG (m));",
1470
  },
1471
 
1472
  { "n", "nm", "sub <REG_M>,<REG_N>", "0011nnnnmmmm1000",
1473
    "R[n] -= R[m];",
1474
  },
1475
 
1476
  { "n", "nm", "subc <REG_M>,<REG_N>", "0011nnnnmmmm1010",
1477
    "ult = R[n] - T;",
1478
    "SET_SR_T (ult > R[n]);",
1479
    "R[n] = ult - R[m];",
1480
    "SET_SR_T (T || (R[n] > ult));",
1481
  },
1482
 
1483
  { "n", "nm", "subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
1484
    "ult = R[n] - R[m];",
1485
    "SET_SR_T (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31);",
1486
    "R[n] = ult;",
1487
  },
1488
 
1489
  { "n", "nm", "swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000",
1490
    "R[n] = ((R[m] & 0xffff0000)",
1491
    "        | ((R[m] << 8) & 0xff00)",
1492
    "        | ((R[m] >> 8) & 0x00ff));",
1493
  },
1494
  { "n", "nm", "swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001",
1495
    "R[n] = (((R[m] << 16) & 0xffff0000)",
1496
    "        | ((R[m] >> 16) & 0x00ffff));",
1497
  },
1498
 
1499
  { "", "n", "tas.b @<REG_N>", "0100nnnn00011011",
1500
    "MA (1);",
1501
    "ult = RBAT (R[n]);",
1502
    "SET_SR_T (ult == 0);",
1503
    "WBAT (R[n],ult|0x80);",
1504
  },
1505
 
1506
  { "0", "", "trapa #<imm>", "11000011i8*1....",
1507
    "long imm = 0xff & i;",
1508
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1509
    "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
1510
    "  nip += trap (i, &R0, PC, memory, maskl, maskw, endianw);",
1511
#if 0
1512
    "else {",
1513
    /* SH-[12] */
1514
    "  R[15] -= 4;",
1515
    "  WLAT (R[15], GET_SR ());",
1516
    "  R[15] -= 4;",
1517
    "  WLAT (R[15], PH2T (PC + 2));",
1518
#else
1519
    "else if (!SR_BL) {",
1520
    "  SSR = GET_SR ();",
1521
    "  SPC = PH2T (PC + 2);",
1522
    "  SET_SR (GET_SR () | SR_MASK_MD | SR_MASK_BL | SR_MASK_RB);",
1523
    "  /* FIXME: EXPEVT = 0x00000160; */",
1524
#endif
1525
    "  SET_NIP (PT2H (RLAT (VBR + (imm<<2))));",
1526
    "}",
1527
  },
1528
 
1529
  { "", "mn", "tst <REG_M>,<REG_N>", "0010nnnnmmmm1000",
1530
    "SET_SR_T ((R[n] & R[m]) == 0);",
1531
  },
1532
  { "", "0", "tst #<imm>,R0", "11001000i8*1....",
1533
    "SET_SR_T ((R0 & i) == 0);",
1534
  },
1535
  { "", "0", "tst.b #<imm>,@(R0,GBR)", "11001100i8*1....",
1536
    "MA (1);",
1537
    "SET_SR_T ((RBAT (GBR+R0) & i) == 0);",
1538
  },
1539
 
1540
  { "", "0", "xor #<imm>,R0", "11001010i8*1....",
1541
    "R0 ^= i;",
1542
  },
1543
  { "n", "mn", "xor <REG_M>,<REG_N>", "0010nnnnmmmm1010",
1544
    "R[n] ^= R[m];",
1545
  },
1546
  { "", "0", "xor.b #<imm>,@(R0,GBR)", "11001110i8*1....",
1547
    "MA (1);",
1548
    "ult = RBAT (GBR+R0);",
1549
    "ult ^= i;",
1550
    "WBAT (GBR + R0, ult);",
1551
  },
1552
 
1553
  { "n", "nm", "xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101",
1554
    "R[n] = (((R[n] >> 16) & 0xffff)",
1555
    "        | ((R[m] << 16) & 0xffff0000));",
1556
  },
1557
 
1558
#if 0
1559
  { "divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110",
1560
    "divl (0, R[n], R[m]);",
1561
  },
1562
  { "divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101",
1563
    "divl (0, R[n], R[m]);",
1564
  },
1565
#endif
1566
 
1567
  {0, 0}};
1568
 
1569
op movsxy_tab[] =
1570
{
1571
/* If this is disabled, the simulator speeds up by about 12% on a
1572
   450 MHz PIII - 9% with ACE_FAST.
1573
   Maybe we should have separate simulator loops?  */
1574
#if 1
1575
  { "n", "n", "movs.w @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0000",
1576
    "MA (1);",
1577
    "R[n] -= 2;",
1578
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1579
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1580
  },
1581
  { "", "n",  "movs.w @<REG_N>,<DSP_REG_M>",  "111101NNMMMM0100",
1582
    "MA (1);",
1583
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1584
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1585
  },
1586
  { "n", "n", "movs.w @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1000",
1587
    "MA (1);",
1588
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1589
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1590
    "R[n] += 2;",
1591
  },
1592
  { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1100",
1593
    "MA (1);",
1594
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1595
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1596
    "R[n] += R[8];",
1597
  },
1598
  { "n", "n", "movs.w @-<REG_N>,<DSP_GRD_M>", "111101NNGGGG0000",
1599
    "MA (1);",
1600
    "R[n] -= 2;",
1601
    "DSP_R (m) = RSWAT (R[n]);",
1602
  },
1603
  { "", "n",  "movs.w @<REG_N>,<DSP_GRD_M>",  "111101NNGGGG0100",
1604
    "MA (1);",
1605
    "DSP_R (m) = RSWAT (R[n]);",
1606
  },
1607
  { "n", "n", "movs.w @<REG_N>+,<DSP_GRD_M>", "111101NNGGGG1000",
1608
    "MA (1);",
1609
    "DSP_R (m) = RSWAT (R[n]);",
1610
    "R[n] += 2;",
1611
  },
1612
  { "n", "n8","movs.w @<REG_N>+REG_8,<DSP_GRD_M>", "111101NNGGGG1100",
1613
    "MA (1);",
1614
    "DSP_R (m) = RSWAT (R[n]);",
1615
    "R[n] += R[8];",
1616
  },
1617
  { "n", "n", "movs.w <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0001",
1618
    "MA (1);",
1619
    "R[n] -= 2;",
1620
    "WWAT (R[n], DSP_R (m) >> 16);",
1621
  },
1622
  { "", "n",  "movs.w <DSP_REG_M>,@<REG_N>",  "111101NNMMMM0101",
1623
    "MA (1);",
1624
    "WWAT (R[n], DSP_R (m) >> 16);",
1625
  },
1626
  { "n", "n", "movs.w <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1001",
1627
    "MA (1);",
1628
    "WWAT (R[n], DSP_R (m) >> 16);",
1629
    "R[n] += 2;",
1630
  },
1631
  { "n", "n8","movs.w <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1101",
1632
    "MA (1);",
1633
    "WWAT (R[n], DSP_R (m) >> 16);",
1634
    "R[n] += R[8];",
1635
  },
1636
  { "n", "n", "movs.w <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0001",
1637
    "MA (1);",
1638
    "R[n] -= 2;",
1639
    "WWAT (R[n], SEXT (DSP_R (m)));",
1640
  },
1641
  { "", "n",  "movs.w <DSP_GRD_M>,@<REG_N>",  "111101NNGGGG0101",
1642
    "MA (1);",
1643
    "WWAT (R[n], SEXT (DSP_R (m)));",
1644
  },
1645
  { "n", "n", "movs.w <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1001",
1646
    "MA (1);",
1647
    "WWAT (R[n], SEXT (DSP_R (m)));",
1648
    "R[n] += 2;",
1649
  },
1650
  { "n", "n8","movs.w <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1101",
1651
    "MA (1);",
1652
    "WWAT (R[n], SEXT (DSP_R (m)));",
1653
    "R[n] += R[8];",
1654
  },
1655
  { "n", "n", "movs.l @-<REG_N>,<DSP_REG_M>", "111101NNMMMM0010",
1656
    "MA (1);",
1657
    "R[n] -= 4;",
1658
    "DSP_R (m) = RLAT (R[n]);",
1659
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1660
  },
1661
  { "", "n",  "movs.l @<REG_N>,<DSP_REG_M>",  "111101NNMMMM0110",
1662
    "MA (1);",
1663
    "DSP_R (m) = RLAT (R[n]);",
1664
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1665
  },
1666
  { "n", "n", "movs.l @<REG_N>+,<DSP_REG_M>", "111101NNMMMM1010",
1667
    "MA (1);",
1668
    "DSP_R (m) = RLAT (R[n]);",
1669
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1670
    "R[n] += 4;",
1671
  },
1672
  { "n", "n8","movs.l @<REG_N>+REG_8,<DSP_REG_M>", "111101NNMMMM1110",
1673
    "MA (1);",
1674
    "DSP_R (m) = RLAT (R[n]);",
1675
    "DSP_GRD (m) = SIGN32 (DSP_R (m));",
1676
    "R[n] += R[8];",
1677
  },
1678
  { "n", "n", "movs.l <DSP_REG_M>,@-<REG_N>", "111101NNMMMM0011",
1679
    "MA (1);",
1680
    "R[n] -= 4;",
1681
    "WLAT (R[n], DSP_R (m));",
1682
  },
1683
  { "", "n",  "movs.l <DSP_REG_M>,@<REG_N>",  "111101NNMMMM0111",
1684
    "MA (1);",
1685
    "WLAT (R[n], DSP_R (m));",
1686
  },
1687
  { "n", "n", "movs.l <DSP_REG_M>,@<REG_N>+", "111101NNMMMM1011",
1688
    "MA (1);",
1689
    "WLAT (R[n], DSP_R (m));",
1690
    "R[n] += 4;",
1691
  },
1692
  { "n", "n8","movs.l <DSP_REG_M>,@<REG_N>+REG_8", "111101NNMMMM1111",
1693
    "MA (1);",
1694
    "WLAT (R[n], DSP_R (m));",
1695
    "R[n] += R[8];",
1696
  },
1697
  { "n", "n", "movs.l <DSP_GRD_M>,@-<REG_N>", "111101NNGGGG0011",
1698
    "MA (1);",
1699
    "R[n] -= 4;",
1700
    "WLAT (R[n], SEXT (DSP_R (m)));",
1701
  },
1702
  { "", "n",  "movs.l <DSP_GRD_M>,@<REG_N>",  "111101NNGGGG0111",
1703
    "MA (1);",
1704
    "WLAT (R[n], SEXT (DSP_R (m)));",
1705
  },
1706
  { "n", "n", "movs.l <DSP_GRD_M>,@<REG_N>+", "111101NNGGGG1011",
1707
    "MA (1);",
1708
    "WLAT (R[n], SEXT (DSP_R (m)));",
1709
    "R[n] += 4;",
1710
  },
1711
  { "n", "n8","movs.l <DSP_GRD_M>,@<REG_N>+REG_8", "111101NNGGGG1111",
1712
    "MA (1);",
1713
    "WLAT (R[n], SEXT (DSP_R (m)));",
1714
    "R[n] += R[8];",
1715
  },
1716
  { "", "n", "movx.w @<REG_xy>,<DSP_XY>",   "111100xyXY0001??",
1717
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1718
    "if (iword & 3)",
1719
    "  {",
1720
    "    iword &= 0xfd53; goto top;",
1721
    "  }",
1722
  },
1723
  { "", "n", "movx.l @<REG_xy>,<DSP_XY>",   "111100xyXY010100",
1724
    "DSP_R (m) = RLAT (R[n]);",
1725
  },
1726
  { "n", "n", "movx.w @<REG_xy>+,<DSP_XY>", "111100xyXY0010??",
1727
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1728
    "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1729
    "if (iword & 3)",
1730
    "  {",
1731
    "    iword &= 0xfd53; goto top;",
1732
    "  }",
1733
  },
1734
  { "n", "n", "movx.l @<REG_xy>+,<DSP_XY>", "111100xyXY011000",
1735
    "DSP_R (m) = RLAT (R[n]);",
1736
    "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1737
  },
1738
  { "n", "n8","movx.w @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY0011??",
1739
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1740
    "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1741
    "if (iword & 3)",
1742
    "  {",
1743
    "    iword &= 0xfd53; goto top;",
1744
    "  }",
1745
  },
1746
  { "n", "n8","movx.l @<REG_xy>+REG_8,<DSP_XY>", "111100xyXY011100",
1747
    "DSP_R (m) = RLAT (R[n]);",
1748
    "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1749
  },
1750
  { "", "n", "movx.w <DSP_Ax>,@<REG_xy>",   "111100xyax1001??",
1751
    "WWAT (R[n], DSP_R (m) >> 16);",
1752
    "if (iword & 3)",
1753
    "  {",
1754
    "    iword &= 0xfd53; goto top;",
1755
    "  }",
1756
  },
1757
  { "", "n", "movx.l <DSP_Ax>,@<REG_xy>",   "111100xyax110100",
1758
    "WLAT (R[n], DSP_R (m));",
1759
  },
1760
  { "n", "n", "movx.w <DSP_Ax>,@<REG_xy>+", "111100xyax1010??",
1761
    "WWAT (R[n], DSP_R (m) >> 16);",
1762
    "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1763
    "if (iword & 3)",
1764
    "  {",
1765
    "    iword &= 0xfd53; goto top;",
1766
    "  }",
1767
  },
1768
  { "n", "n", "movx.l <DSP_Ax>,@<REG_xy>+", "111100xyax111000",
1769
    "WLAT (R[n], DSP_R (m));",
1770
    "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1771
  },
1772
  { "n", "n8","movx.w <DSP_Ax>,@<REG_xy>+REG_8","111100xyax1011??",
1773
    "WWAT (R[n], DSP_R (m) >> 16);",
1774
    "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1775
    "if (iword & 3)",
1776
    "  {",
1777
    "    iword &= 0xfd53; goto top;",
1778
    "  }",
1779
  },
1780
  { "n", "n8","movx.l <DSP_Ax>,@<REG_xy>+REG_8","111100xyax111100",
1781
    "WLAT (R[n], DSP_R (m));",
1782
    "R[n] += ((R[n] & 0xffff) == MOD_ME) ? MOD_DELTA : R[8];",
1783
  },
1784
  { "", "n", "movy.w @<REG_yx>,<DSP_YX>",   "111100yxYX000001",
1785
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1786
  },
1787
  { "n", "n", "movy.w @<REG_yx>+,<DSP_YX>", "111100yxYX000010",
1788
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1789
    "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1790
  },
1791
  { "n", "n9","movy.w @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX000011",
1792
    "DSP_R (m) = RSWAT (R[n]) << 16;",
1793
    "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1794
  },
1795
  { "", "n", "movy.w <DSP_Ay>,@<REG_yx>",   "111100yxAY010001",
1796
    "WWAT (R[n], DSP_R (m) >> 16);",
1797
  },
1798
  { "n", "n", "movy.w <DSP_Ay>,@<REG_yx>+", "111100yxAY010010",
1799
    "WWAT (R[n], DSP_R (m) >> 16);",
1800
    "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 2;",
1801
  },
1802
  { "n", "n9", "movy.w <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY010011",
1803
    "WWAT (R[n], DSP_R (m) >> 16);",
1804
    "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1805
  },
1806
  { "", "n", "movy.l @<REG_yx>,<DSP_YX>",   "111100yxYX100001",
1807
    "DSP_R (m) = RLAT (R[n]);",
1808
  },
1809
  { "n", "n", "movy.l @<REG_yx>+,<DSP_YX>", "111100yxYX100010",
1810
    "DSP_R (m) = RLAT (R[n]);",
1811
    "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1812
  },
1813
  { "n", "n9","movy.l @<REG_yx>+REG_9,<DSP_YX>", "111100yxYX100011",
1814
    "DSP_R (m) = RLAT (R[n]);",
1815
    "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1816
  },
1817
  { "", "n", "movy.l <DSP_Ay>,@<REG_yx>",   "111100yxAY110001",
1818
    "WLAT (R[n], DSP_R (m));",
1819
  },
1820
  { "n", "n", "movy.l <DSP_Ay>,@<REG_yx>+", "111100yxAY110010",
1821
    "WLAT (R[n], DSP_R (m));",
1822
    "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : 4;",
1823
  },
1824
  { "n", "n9", "movy.l <DSP_Ay>,@<REG_yx>+REG_9", "111100yxAY110011",
1825
    "WLAT (R[n], DSP_R (m));",
1826
    "R[n] += ((R[n] | ~0xffff) == MOD_ME) ? MOD_DELTA : R[9];",
1827
  },
1828
  { "", "", "nopx nopy", "1111000000000000",
1829
    "/* nop */",
1830
  },
1831
  { "", "", "ppi", "1111100000000000",
1832
    "RAISE_EXCEPTION_IF_IN_DELAY_SLOT ();",
1833
    "ppi_insn (RIAT (nip));",
1834
    "SET_NIP (nip + 2);",
1835
    "iword &= 0xf7ff; goto top;",
1836
  },
1837
#endif
1838
  {0, 0}};
1839
 
1840
op ppi_tab[] =
1841
{
1842
  { "","", "pshl #<imm>,dz",    "00000iiim16.zzzz",
1843
    "int Sz = DSP_R (z) & 0xffff0000;",
1844
    "",
1845
    "if (i <= 16)",
1846
    "  res = Sz << i;",
1847
    "else if (i >= 128 - 16)",
1848
    "  res = (unsigned) Sz >> 128 - i;  /* no sign extension */",
1849
    "else",
1850
    "  {",
1851
    "    RAISE_EXCEPTION (SIGILL);",
1852
    "    return;",
1853
    "  }",
1854
    "res &= 0xffff0000;",
1855
    "res_grd = 0;",
1856
    "goto logical;",
1857
  },
1858
  { "","", "psha #<imm>,dz",    "00010iiim32.zzzz",
1859
    "int Sz = DSP_R (z);",
1860
    "int Sz_grd = GET_DSP_GRD (z);",
1861
    "",
1862
    "if (i <= 32)",
1863
    "  {",
1864
    "    if (i == 32)",
1865
    "      {",
1866
    "        res = 0;",
1867
    "        res_grd = Sz;",
1868
    "      }",
1869
    "    else",
1870
    "      {",
1871
    "        res = Sz << i;",
1872
    "        res_grd = Sz_grd << i | (unsigned) Sz >> 32 - i;",
1873
    "      }",
1874
    "    res_grd = SEXT (res_grd);",
1875
    "    carry = res_grd & 1;",
1876
    "  }",
1877
    "else if (i >= 96)",
1878
    "  {",
1879
    "    i = 128 - i;",
1880
    "    if (i == 32)",
1881
    "      {",
1882
    "        res_grd = SIGN32 (Sz_grd);",
1883
    "        res = Sz_grd;",
1884
    "      }",
1885
    "    else",
1886
    "      {",
1887
    "        res = Sz >> i | Sz_grd << 32 - i;",
1888
    "        res_grd = Sz_grd >> i;",
1889
    "      }",
1890
    "    carry = Sz >> (i - 1) & 1;",
1891
    "  }",
1892
    "else",
1893
    "  {",
1894
    "    RAISE_EXCEPTION (SIGILL);",
1895
    "    return;",
1896
    "  }",
1897
    "COMPUTE_OVERFLOW;",
1898
    "greater_equal = 0;",
1899
  },
1900
  { "","", "pmuls Se,Sf,Dg",    "0100eeffxxyygguu",
1901
    "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1902
    "if (res == 0x80000000)",
1903
    "  res = 0x7fffffff;",
1904
    "DSP_R (g) = res;",
1905
    "DSP_GRD (g) = SIGN32 (res);",
1906
    "return;",
1907
  },
1908
  { "","", "psub Sx,Sy,Du pmuls Se,Sf,Dg",      "0110eeffxxyygguu",
1909
    "int Sx = DSP_R (x);",
1910
    "int Sx_grd = GET_DSP_GRD (x);",
1911
    "int Sy = DSP_R (y);",
1912
    "int Sy_grd = SIGN32 (Sy);",
1913
    "",
1914
    "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1915
    "if (res == 0x80000000)",
1916
    "  res = 0x7fffffff;",
1917
    "DSP_R (g) = res;",
1918
    "DSP_GRD (g) = SIGN32 (res);",
1919
    "",
1920
    "z = u;",
1921
    "res = Sx - Sy;",
1922
    "carry = (unsigned) res > (unsigned) Sx;",
1923
    "res_grd = Sx_grd - Sy_grd - carry;",
1924
    "COMPUTE_OVERFLOW;",
1925
    "ADD_SUB_GE;",
1926
  },
1927
  { "","", "padd Sx,Sy,Du pmuls Se,Sf,Dg",      "0111eeffxxyygguu",
1928
    "int Sx = DSP_R (x);",
1929
    "int Sx_grd = GET_DSP_GRD (x);",
1930
    "int Sy = DSP_R (y);",
1931
    "int Sy_grd = SIGN32 (Sy);",
1932
    "",
1933
    "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
1934
    "if (res == 0x80000000)",
1935
    "  res = 0x7fffffff;",
1936
    "DSP_R (g) = res;",
1937
    "DSP_GRD (g) = SIGN32 (res);",
1938
    "",
1939
    "z = u;",
1940
    "res = Sx + Sy;",
1941
    "carry = (unsigned) res < (unsigned) Sx;",
1942
    "res_grd = Sx_grd + Sy_grd + carry;",
1943
    "COMPUTE_OVERFLOW;",
1944
  },
1945
  { "","", "psubc Sx,Sy,Dz",            "10100000xxyyzzzz",
1946
    "int Sx = DSP_R (x);",
1947
    "int Sx_grd = GET_DSP_GRD (x);",
1948
    "int Sy = DSP_R (y);",
1949
    "int Sy_grd = SIGN32 (Sy);",
1950
    "",
1951
    "res = Sx - Sy - (DSR & 1);",
1952
    "carry = (unsigned) res > (unsigned) Sx || (res == Sx && Sy);",
1953
    "res_grd = Sx_grd + Sy_grd + carry;",
1954
    "COMPUTE_OVERFLOW;",
1955
    "ADD_SUB_GE;",
1956
    "DSR &= ~0xf1;\n",
1957
    "if (res || res_grd)\n",
1958
    "  DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1959
    "else\n",
1960
    "  DSR |= DSR_MASK_Z | overflow;\n",
1961
    "DSR |= carry;\n",
1962
    "goto assign_z;\n",
1963
  },
1964
  { "","", "paddc Sx,Sy,Dz",    "10110000xxyyzzzz",
1965
    "int Sx = DSP_R (x);",
1966
    "int Sx_grd = GET_DSP_GRD (x);",
1967
    "int Sy = DSP_R (y);",
1968
    "int Sy_grd = SIGN32 (Sy);",
1969
    "",
1970
    "res = Sx + Sy + (DSR & 1);",
1971
    "carry = (unsigned) res < (unsigned) Sx || (res == Sx && Sy);",
1972
    "res_grd = Sx_grd + Sy_grd + carry;",
1973
    "COMPUTE_OVERFLOW;",
1974
    "ADD_SUB_GE;",
1975
    "DSR &= ~0xf1;\n",
1976
    "if (res || res_grd)\n",
1977
    "  DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n",
1978
    "else\n",
1979
    "  DSR |= DSR_MASK_Z | overflow;\n",
1980
    "DSR |= carry;\n",
1981
    "goto assign_z;\n",
1982
  },
1983
  { "","", "pcmp Sx,Sy",        "10000100xxyyzzzz",
1984
    "int Sx = DSP_R (x);",
1985
    "int Sx_grd = GET_DSP_GRD (x);",
1986
    "int Sy = DSP_R (y);",
1987
    "int Sy_grd = SIGN32 (Sy);",
1988
    "",
1989
    "z = 17; /* Ignore result.  */",
1990
    "res = Sx - Sy;",
1991
    "carry = (unsigned) res > (unsigned) Sx;",
1992
    "res_grd = Sx_grd - Sy_grd - carry;",
1993
    "COMPUTE_OVERFLOW;",
1994
    "ADD_SUB_GE;",
1995
  },
1996
  { "","", "pwsb Sx,Sy,Dz",     "10100100xxyyzzzz",
1997
  },
1998
  { "","", "pwad Sx,Sy,Dz",     "10110100xxyyzzzz",
1999
  },
2000
  { "","", "(if cc) pabs Sx,Dz",        "100010ccxx01zzzz",
2001
    "/* FIXME: duplicate code pabs.  */",
2002
    "res = DSP_R (x);",
2003
    "res_grd = GET_DSP_GRD (x);",
2004
    "if (res >= 0)",
2005
    "  carry = 0;",
2006
    "else",
2007
    "  {",
2008
    "    res = -res;",
2009
    "    carry = (res != 0); /* The manual has a bug here.  */",
2010
    "    res_grd = -res_grd - carry;",
2011
    "  }",
2012
    "COMPUTE_OVERFLOW;",
2013
    "/* ??? The re-computing of overflow after",
2014
    "   saturation processing is specific to pabs.  */",
2015
    "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2016
    "ADD_SUB_GE;",
2017
  },
2018
  { "","", "pabs Sx,Dz",        "10001000xx..zzzz",
2019
    "res = DSP_R (x);",
2020
    "res_grd = GET_DSP_GRD (x);",
2021
    "if (res >= 0)",
2022
    "  carry = 0;",
2023
    "else",
2024
    "  {",
2025
    "    res = -res;",
2026
    "    carry = (res != 0); /* The manual has a bug here.  */",
2027
    "    res_grd = -res_grd - carry;",
2028
    "  }",
2029
    "COMPUTE_OVERFLOW;",
2030
    "/* ??? The re-computing of overflow after",
2031
    "   saturation processing is specific to pabs.  */",
2032
    "overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0;",
2033
    "ADD_SUB_GE;",
2034
  },
2035
 
2036
  { "","", "(if cc) prnd Sx,Dz",        "100110ccxx01zzzz",
2037
    "/* FIXME: duplicate code prnd.  */",
2038
    "int Sx = DSP_R (x);",
2039
    "int Sx_grd = GET_DSP_GRD (x);",
2040
    "",
2041
    "res = (Sx + 0x8000) & 0xffff0000;",
2042
    "carry = (unsigned) res < (unsigned) Sx;",
2043
    "res_grd = Sx_grd + carry;",
2044
    "COMPUTE_OVERFLOW;",
2045
    "ADD_SUB_GE;",
2046
  },
2047
  { "","", "prnd Sx,Dz",        "10011000xx..zzzz",
2048
    "int Sx = DSP_R (x);",
2049
    "int Sx_grd = GET_DSP_GRD (x);",
2050
    "",
2051
    "res = (Sx + 0x8000) & 0xffff0000;",
2052
    "carry = (unsigned) res < (unsigned) Sx;",
2053
    "res_grd = Sx_grd + carry;",
2054
    "COMPUTE_OVERFLOW;",
2055
    "ADD_SUB_GE;",
2056
  },
2057
 
2058
  { "","", "(if cc) pabs Sy,Dz",        "101010cc01yyzzzz",
2059
    "/* FIXME: duplicate code pabs.  */",
2060
    "res = DSP_R (y);",
2061
    "res_grd = 0;",
2062
    "overflow = 0;",
2063
    "greater_equal = DSR_MASK_G;",
2064
    "if (res >= 0)",
2065
    "  carry = 0;",
2066
    "else",
2067
    "  {",
2068
    "    res = -res;",
2069
    "    carry = 1;",
2070
    "    if (res < 0)",
2071
    "      {",
2072
    "        if (S)",
2073
    "          res = 0x7fffffff;",
2074
    "        else",
2075
    "          {",
2076
    "            overflow = DSR_MASK_V;",
2077
    "            greater_equal = 0;",
2078
    "          }",
2079
    "      }",
2080
    "  }",
2081
  },
2082
  { "","", "pabs Sy,Dz",        "10101000..yyzzzz",
2083
    "res = DSP_R (y);",
2084
    "res_grd = 0;",
2085
    "overflow = 0;",
2086
    "greater_equal = DSR_MASK_G;",
2087
    "if (res >= 0)",
2088
    "  carry = 0;",
2089
    "else",
2090
    "  {",
2091
    "    res = -res;",
2092
    "    carry = 1;",
2093
    "    if (res < 0)",
2094
    "      {",
2095
    "        if (S)",
2096
    "          res = 0x7fffffff;",
2097
    "        else",
2098
    "          {",
2099
    "            overflow = DSR_MASK_V;",
2100
    "            greater_equal = 0;",
2101
    "          }",
2102
    "      }",
2103
    "  }",
2104
  },
2105
  { "","", "(if cc) prnd Sy,Dz",        "101110cc01yyzzzz",
2106
    "/* FIXME: duplicate code prnd.  */",
2107
    "int Sy = DSP_R (y);",
2108
    "int Sy_grd = SIGN32 (Sy);",
2109
    "",
2110
    "res = (Sy + 0x8000) & 0xffff0000;",
2111
    "carry = (unsigned) res < (unsigned) Sy;",
2112
    "res_grd = Sy_grd + carry;",
2113
    "COMPUTE_OVERFLOW;",
2114
    "ADD_SUB_GE;",
2115
  },
2116
  { "","", "prnd Sy,Dz",        "10111000..yyzzzz",
2117
    "int Sy = DSP_R (y);",
2118
    "int Sy_grd = SIGN32 (Sy);",
2119
    "",
2120
    "res = (Sy + 0x8000) & 0xffff0000;",
2121
    "carry = (unsigned) res < (unsigned) Sy;",
2122
    "res_grd = Sy_grd + carry;",
2123
    "COMPUTE_OVERFLOW;",
2124
    "ADD_SUB_GE;",
2125
  },
2126
  { "","", "(if cc) pshl Sx,Sy,Dz",     "100000ccxxyyzzzz",
2127
    "int Sx = DSP_R (x) & 0xffff0000;",
2128
    "int Sy = DSP_R (y) >> 16 & 0x7f;",
2129
    "",
2130
    "if (Sy <= 16)",
2131
    "  res = Sx << Sy;",
2132
    "else if (Sy >= 128 - 16)",
2133
    "  res = (unsigned) Sx >> 128 - Sy; /* no sign extension */",
2134
    "else",
2135
    "  {",
2136
    "    RAISE_EXCEPTION (SIGILL);",
2137
    "    return;",
2138
    "  }",
2139
    "goto cond_logical;",
2140
  },
2141
  { "","", "(if cc) psha Sx,Sy,Dz",     "100100ccxxyyzzzz",
2142
    "int Sx = DSP_R (x);",
2143
    "int Sx_grd = GET_DSP_GRD (x);",
2144
    "int Sy = DSP_R (y) >> 16 & 0x7f;",
2145
    "",
2146
    "if (Sy <= 32)",
2147
    "  {",
2148
    "    if (Sy == 32)",
2149
    "      {",
2150
    "        res = 0;",
2151
    "        res_grd = Sx;",
2152
    "      }",
2153
    "    else",
2154
    "      {",
2155
    "        res = Sx << Sy;",
2156
    "        res_grd = Sx_grd << Sy | (unsigned) Sx >> 32 - Sy;",
2157
    "      }",
2158
    "    res_grd = SEXT (res_grd);",
2159
    "    carry = res_grd & 1;",
2160
    "  }",
2161
    "else if (Sy >= 96)",
2162
    "  {",
2163
    "    Sy = 128 - Sy;",
2164
    "    if (Sy == 32)",
2165
    "      {",
2166
    "        res_grd = SIGN32 (Sx_grd);",
2167
    "        res = Sx_grd;",
2168
    "      }",
2169
    "    else",
2170
    "      {",
2171
    "        res = Sx >> Sy | Sx_grd << 32 - Sy;",
2172
    "        res_grd = Sx_grd >> Sy;",
2173
    "      }",
2174
    "    carry = Sx >> (Sy - 1) & 1;",
2175
    "  }",
2176
    "else",
2177
    "  {",
2178
    "    RAISE_EXCEPTION (SIGILL);",
2179
    "    return;",
2180
    "  }",
2181
    "COMPUTE_OVERFLOW;",
2182
    "greater_equal = 0;",
2183
  },
2184
  { "","", "(if cc) psub Sx,Sy,Dz",     "101000ccxxyyzzzz",
2185
    "int Sx = DSP_R (x);",
2186
    "int Sx_grd = GET_DSP_GRD (x);",
2187
    "int Sy = DSP_R (y);",
2188
    "int Sy_grd = SIGN32 (Sy);",
2189
    "",
2190
    "res = Sx - Sy;",
2191
    "carry = (unsigned) res > (unsigned) Sx;",
2192
    "res_grd = Sx_grd - Sy_grd - carry;",
2193
    "COMPUTE_OVERFLOW;",
2194
    "ADD_SUB_GE;",
2195
  },
2196
  { "","", "(if cc) psub Sy,Sx,Dz",     "100001ccxxyyzzzz",
2197
    "int Sx = DSP_R (x);",
2198
    "int Sx_grd = GET_DSP_GRD (x);",
2199
    "int Sy = DSP_R (y);",
2200
    "int Sy_grd = SIGN32 (Sy);",
2201
    "",
2202
    "res = Sy - Sx;",
2203
    "carry = (unsigned) res > (unsigned) Sy;",
2204
    "res_grd = Sy_grd - Sx_grd - carry;",
2205
    "COMPUTE_OVERFLOW;",
2206
    "ADD_SUB_GE;",
2207
  },
2208
  { "","", "(if cc) padd Sx,Sy,Dz",     "101100ccxxyyzzzz",
2209
    "int Sx = DSP_R (x);",
2210
    "int Sx_grd = GET_DSP_GRD (x);",
2211
    "int Sy = DSP_R (y);",
2212
    "int Sy_grd = SIGN32 (Sy);",
2213
    "",
2214
    "res = Sx + Sy;",
2215
    "carry = (unsigned) res < (unsigned) Sx;",
2216
    "res_grd = Sx_grd + Sy_grd + carry;",
2217
    "COMPUTE_OVERFLOW;",
2218
    "ADD_SUB_GE;",
2219
  },
2220
  { "","", "(if cc) pand Sx,Sy,Dz",     "100101ccxxyyzzzz",
2221
    "res = DSP_R (x) & DSP_R (y);",
2222
  "cond_logical:",
2223
    "res &= 0xffff0000;",
2224
    "res_grd = 0;",
2225
    "if (iword & 0x200)\n",
2226
    "  goto assign_z;\n",
2227
  "logical:",
2228
    "carry = 0;",
2229
    "overflow = 0;",
2230
    "greater_equal = 0;",
2231
    "DSR &= ~0xf1;\n",
2232
    "if (res)\n",
2233
    "  DSR |= res >> 26 & DSR_MASK_N;\n",
2234
    "else\n",
2235
    "  DSR |= DSR_MASK_Z;\n",
2236
    "goto assign_dc;\n",
2237
  },
2238
  { "","", "(if cc) pxor Sx,Sy,Dz",     "101001ccxxyyzzzz",
2239
    "res = DSP_R (x) ^ DSP_R (y);",
2240
    "goto cond_logical;",
2241
  },
2242
  { "","", "(if cc) por Sx,Sy,Dz",      "101101ccxxyyzzzz",
2243
    "res = DSP_R (x) | DSP_R (y);",
2244
    "goto cond_logical;",
2245
  },
2246
  { "","", "(if cc) pdec Sx,Dz",        "100010ccxx..zzzz",
2247
    "int Sx = DSP_R (x);",
2248
    "int Sx_grd = GET_DSP_GRD (x);",
2249
    "",
2250
    "res = Sx - 0x10000;",
2251
    "carry = res > Sx;",
2252
    "res_grd = Sx_grd - carry;",
2253
    "COMPUTE_OVERFLOW;",
2254
    "ADD_SUB_GE;",
2255
    "res &= 0xffff0000;",
2256
  },
2257
  { "","", "(if cc) pinc Sx,Dz",        "100110ccxx..zzzz",
2258
    "int Sx = DSP_R (x);",
2259
    "int Sx_grd = GET_DSP_GRD (x);",
2260
    "",
2261
    "res = Sx + 0x10000;",
2262
    "carry = res < Sx;",
2263
    "res_grd = Sx_grd + carry;",
2264
    "COMPUTE_OVERFLOW;",
2265
    "ADD_SUB_GE;",
2266
    "res &= 0xffff0000;",
2267
  },
2268
  { "","", "(if cc) pdec Sy,Dz",        "101010cc..yyzzzz",
2269
    "int Sy = DSP_R (y);",
2270
    "int Sy_grd = SIGN32 (Sy);",
2271
    "",
2272
    "res = Sy - 0x10000;",
2273
    "carry = res > Sy;",
2274
    "res_grd = Sy_grd - carry;",
2275
    "COMPUTE_OVERFLOW;",
2276
    "ADD_SUB_GE;",
2277
    "res &= 0xffff0000;",
2278
  },
2279
  { "","", "(if cc) pinc Sy,Dz",        "101110cc..yyzzzz",
2280
    "int Sy = DSP_R (y);",
2281
    "int Sy_grd = SIGN32 (Sy);",
2282
    "",
2283
    "res = Sy + 0x10000;",
2284
    "carry = res < Sy;",
2285
    "res_grd = Sy_grd + carry;",
2286
    "COMPUTE_OVERFLOW;",
2287
    "ADD_SUB_GE;",
2288
    "res &= 0xffff0000;",
2289
  },
2290
  { "","", "(if cc) pclr Dz",           "100011cc....zzzz",
2291
    "res = 0;",
2292
    "res_grd = 0;",
2293
    "carry = 0;",
2294
    "overflow = 0;",
2295
    "greater_equal = 1;",
2296
  },
2297
  { "","", "pclr Du pmuls Se,Sf,Dg",    "0100eeff0001gguu",
2298
    "/* Do multiply.  */",
2299
    "res = (DSP_R (e) >> 16) * (DSP_R (f) >> 16) * 2;",
2300
    "if (res == 0x80000000)",
2301
    "  res = 0x7fffffff;",
2302
    "DSP_R (g) = res;",
2303
    "DSP_GRD (g) = SIGN32 (res);",
2304
    "/* FIXME: update DSR based on results of multiply!  */",
2305
    "",
2306
    "/* Do clr.  */",
2307
    "z = u;",
2308
    "res = 0;",
2309
    "res_grd = 0;",
2310
    "goto assign_z;",
2311
  },
2312
  { "","", "(if cc) pdmsb Sx,Dz",       "100111ccxx..zzzz",
2313
    "unsigned Sx = DSP_R (x);",
2314
    "int Sx_grd = GET_DSP_GRD (x);",
2315
    "int i = 16;",
2316
    "",
2317
    "if (Sx_grd < 0)",
2318
    "  {",
2319
    "    Sx_grd = ~Sx_grd;",
2320
    "    Sx = ~Sx;",
2321
    "  }",
2322
    "if (Sx_grd)",
2323
    "  {",
2324
    "    Sx = Sx_grd;",
2325
    "    res = -2;",
2326
    "  }",
2327
    "else if (Sx)",
2328
    "  res = 30;",
2329
    "else",
2330
    "  res = 31;",
2331
    "do",
2332
    "  {",
2333
    "    if (Sx & ~0 << i)",
2334
    "      {",
2335
    "        res -= i;",
2336
    "        Sx >>= i;",
2337
    "      }",
2338
    "  }",
2339
    "while (i >>= 1);",
2340
    "res <<= 16;",
2341
    "res_grd = SIGN32 (res);",
2342
    "carry = 0;",
2343
    "overflow = 0;",
2344
    "ADD_SUB_GE;",
2345
  },
2346
  { "","", "(if cc) pdmsb Sy,Dz",       "101111cc..yyzzzz",
2347
    "unsigned Sy = DSP_R (y);",
2348
    "int i;",
2349
    "",
2350
    "if (Sy < 0)",
2351
    "  Sy = ~Sy;",
2352
    "Sy <<= 1;",
2353
    "res = 31;",
2354
    "do",
2355
    "  {",
2356
    "    if (Sy & ~0 << i)",
2357
    "      {",
2358
    "        res -= i;",
2359
    "        Sy >>= i;",
2360
    "      }",
2361
    "  }",
2362
    "while (i >>= 1);",
2363
    "res <<= 16;",
2364
    "res_grd = SIGN32 (res);",
2365
    "carry = 0;",
2366
    "overflow = 0;",
2367
    "ADD_SUB_GE;",
2368
  },
2369
  { "","", "(if cc) pneg Sx,Dz",        "110010ccxx..zzzz",
2370
    "int Sx = DSP_R (x);",
2371
    "int Sx_grd = GET_DSP_GRD (x);",
2372
    "",
2373
    "res = 0 - Sx;",
2374
    "carry = res != 0;",
2375
    "res_grd = 0 - Sx_grd - carry;",
2376
    "COMPUTE_OVERFLOW;",
2377
    "ADD_SUB_GE;",
2378
  },
2379
  { "","", "(if cc) pcopy Sx,Dz",       "110110ccxx..zzzz",
2380
    "res = DSP_R (x);",
2381
    "res_grd = GET_DSP_GRD (x);",
2382
    "carry = 0;",
2383
    "COMPUTE_OVERFLOW;",
2384
    "ADD_SUB_GE;",
2385
  },
2386
  { "","", "(if cc) pneg Sy,Dz",        "111010cc..yyzzzz",
2387
    "int Sy = DSP_R (y);",
2388
    "int Sy_grd = SIGN32 (Sy);",
2389
    "",
2390
    "res = 0 - Sy;",
2391
    "carry = res != 0;",
2392
    "res_grd = 0 - Sy_grd - carry;",
2393
    "COMPUTE_OVERFLOW;",
2394
    "ADD_SUB_GE;",
2395
  },
2396
  { "","", "(if cc) pcopy Sy,Dz",       "111110cc..yyzzzz",
2397
    "res = DSP_R (y);",
2398
    "res_grd = SIGN32 (res);",
2399
    "carry = 0;",
2400
    "COMPUTE_OVERFLOW;",
2401
    "ADD_SUB_GE;",
2402
  },
2403
  { "","", "(if cc) psts MACH,Dz",      "110011cc....zzzz",
2404
    "res = MACH;",
2405
    "res_grd = SIGN32 (res);",
2406
    "goto assign_z;",
2407
  },
2408
  { "","", "(if cc) psts MACL,Dz",      "110111cc....zzzz",
2409
    "res = MACL;",
2410
    "res_grd = SIGN32 (res);",
2411
    "goto assign_z;",
2412
  },
2413
  { "","", "(if cc) plds Dz,MACH",      "111011cc....zzzz",
2414
    "if (0xa05f >> z & 1)",
2415
    "  RAISE_EXCEPTION (SIGILL);",
2416
    "else",
2417
    "  MACH = DSP_R (z);",
2418
    "return;",
2419
  },
2420
  { "","", "(if cc) plds Dz,MACL",      "111111cc....zzzz",
2421
    "if (0xa05f >> z & 1)",
2422
    "  RAISE_EXCEPTION (SIGILL);",
2423
    "else",
2424
    "  MACL = DSP_R (z) = res;",
2425
    "return;",
2426
  },
2427
  /* sh4a */
2428
  { "","", "(if cc) pswap Sx,Dz",       "100111ccxx01zzzz",
2429
    "int Sx = DSP_R (x);",
2430
    "",
2431
    "res = ((Sx & 0xffff) * 65536) + ((Sx >> 16) & 0xffff);",
2432
    "res_grd = GET_DSP_GRD (x);",
2433
    "carry = 0;",
2434
    "overflow = 0;",
2435
    "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2436
  },
2437
  /* sh4a */
2438
  { "","", "(if cc) pswap Sy,Dz",       "101111cc01yyzzzz",
2439
    "int Sy = DSP_R (y);",
2440
    "",
2441
    "res = ((Sy & 0xffff) * 65536) + ((Sy >> 16) & 0xffff);",
2442
    "res_grd = SIGN32 (Sy);",
2443
    "carry = 0;",
2444
    "overflow = 0;",
2445
    "greater_equal = res & 0x80000000 ? 0 : DSR_MASK_G;",
2446
  },
2447
 
2448
  {0, 0}
2449
};
2450
 
2451
/* Tables of things to put into enums for sh-opc.h */
2452
static char *nibble_type_list[] =
2453
{
2454
  "HEX_0",
2455
  "HEX_1",
2456
  "HEX_2",
2457
  "HEX_3",
2458
  "HEX_4",
2459
  "HEX_5",
2460
  "HEX_6",
2461
  "HEX_7",
2462
  "HEX_8",
2463
  "HEX_9",
2464
  "HEX_A",
2465
  "HEX_B",
2466
  "HEX_C",
2467
  "HEX_D",
2468
  "HEX_E",
2469
  "HEX_F",
2470
  "REG_N",
2471
  "REG_M",
2472
  "BRANCH_12",
2473
  "BRANCH_8",
2474
  "DISP_8",
2475
  "DISP_4",
2476
  "IMM_4",
2477
  "IMM_4BY2",
2478
  "IMM_4BY4",
2479
  "PCRELIMM_8BY2",
2480
  "PCRELIMM_8BY4",
2481
  "IMM_8",
2482
  "IMM_8BY2",
2483
  "IMM_8BY4",
2484
 
2485
};
2486
static
2487
char *arg_type_list[] =
2488
{
2489
  "A_END",
2490
  "A_BDISP12",
2491
  "A_BDISP8",
2492
  "A_DEC_M",
2493
  "A_DEC_N",
2494
  "A_DISP_GBR",
2495
  "A_DISP_PC",
2496
  "A_DISP_REG_M",
2497
  "A_DISP_REG_N",
2498
  "A_GBR",
2499
  "A_IMM",
2500
  "A_INC_M",
2501
  "A_INC_N",
2502
  "A_IND_M",
2503
  "A_IND_N",
2504
  "A_IND_R0_REG_M",
2505
  "A_IND_R0_REG_N",
2506
  "A_MACH",
2507
  "A_MACL",
2508
  "A_PR",
2509
  "A_R0",
2510
  "A_R0_GBR",
2511
  "A_REG_M",
2512
  "A_REG_N",
2513
  "A_SR",
2514
  "A_VBR",
2515
  "A_SSR",
2516
  "A_SPC",
2517
  0,
2518
};
2519
 
2520
static void
2521
make_enum_list (name, s)
2522
     char *name;
2523
     char **s;
2524
{
2525
  int i = 1;
2526
  printf ("typedef enum {\n");
2527
  while (*s)
2528
    {
2529
      printf ("\t%s,\n", *s);
2530
      s++;
2531
      i++;
2532
    }
2533
  printf ("} %s;\n", name);
2534
}
2535
 
2536
static int
2537
qfunc (a, b)
2538
     op *a;
2539
     op *b;
2540
{
2541
  char bufa[9];
2542
  char bufb[9];
2543
  int diff;
2544
 
2545
  memcpy (bufa, a->code, 4);
2546
  memcpy (bufa + 4, a->code + 12, 4);
2547
  bufa[8] = 0;
2548
 
2549
  memcpy (bufb, b->code, 4);
2550
  memcpy (bufb + 4, b->code + 12, 4);
2551
  bufb[8] = 0;
2552
  diff = strcmp (bufa, bufb);
2553
  /* Stabilize the sort, so that later entries can override more general
2554
     preceding entries.  */
2555
  return diff ? diff : a - b;
2556
}
2557
 
2558
static void
2559
sorttab ()
2560
{
2561
  op *p = tab;
2562
  int len = 0;
2563
 
2564
  while (p->name)
2565
    {
2566
      p++;
2567
      len++;
2568
    }
2569
  qsort (tab, len, sizeof (*p), qfunc);
2570
}
2571
 
2572
static void
2573
gengastab ()
2574
{
2575
  op *p;
2576
  sorttab ();
2577
  for (p = tab; p->name; p++)
2578
    {
2579
      printf ("%s %-30s\n", p->code, p->name);
2580
    }
2581
}
2582
 
2583
static unsigned short table[1 << 16];
2584
 
2585
static int warn_conflicts = 0;
2586
 
2587
static void
2588
conflict_warn (val, i)
2589
     int val;
2590
     int i;
2591
{
2592
  int ix, key;
2593
  int j = table[val];
2594
 
2595
  fprintf (stderr, "Warning: opcode table conflict: 0x%04x (idx %d && %d)\n",
2596
           val, i, table[val]);
2597
 
2598
  for (ix = sizeof (tab) / sizeof (tab[0]); ix >= 0; ix--)
2599
    if (tab[ix].index == i || tab[ix].index == j)
2600
      {
2601
        key = ((tab[ix].code[0] - '0') << 3) +
2602
          ((tab[ix].code[1] - '0') << 2) +
2603
          ((tab[ix].code[2] - '0') << 1) +
2604
          ((tab[ix].code[3] - '0'));
2605
 
2606
        if (val >> 12 == key)
2607
          fprintf (stderr, "  %s -- %s\n", tab[ix].code, tab[ix].name);
2608
      }
2609
 
2610
  for (ix = sizeof (movsxy_tab) / sizeof (movsxy_tab[0]); ix >= 0; ix--)
2611
    if (movsxy_tab[ix].index == i || movsxy_tab[ix].index == j)
2612
      {
2613
        key = ((movsxy_tab[ix].code[0] - '0') << 3) +
2614
          ((movsxy_tab[ix].code[1] - '0') << 2) +
2615
          ((movsxy_tab[ix].code[2] - '0') << 1) +
2616
          ((movsxy_tab[ix].code[3] - '0'));
2617
 
2618
        if (val >> 12 == key)
2619
          fprintf (stderr, "  %s -- %s\n",
2620
                   movsxy_tab[ix].code, movsxy_tab[ix].name);
2621
      }
2622
 
2623
  for (ix = sizeof (ppi_tab) / sizeof (ppi_tab[0]); ix >= 0; ix--)
2624
    if (ppi_tab[ix].index == i || ppi_tab[ix].index == j)
2625
      {
2626
        key = ((ppi_tab[ix].code[0] - '0') << 3) +
2627
          ((ppi_tab[ix].code[1] - '0') << 2) +
2628
          ((ppi_tab[ix].code[2] - '0') << 1) +
2629
          ((ppi_tab[ix].code[3] - '0'));
2630
 
2631
        if (val >> 12 == key)
2632
          fprintf (stderr, "  %s -- %s\n",
2633
                   ppi_tab[ix].code, ppi_tab[ix].name);
2634
      }
2635
}
2636
 
2637
/* Take an opcode, expand all varying fields in it out and fill all the
2638
   right entries in 'table' with the opcode index.  */
2639
 
2640
static void
2641
expand_opcode (val, i, s)
2642
     int val;
2643
     int i;
2644
     char *s;
2645
{
2646
  if (*s == 0)
2647
    {
2648
      if (warn_conflicts && table[val] != 0)
2649
        conflict_warn (val, i);
2650
      table[val] = i;
2651
    }
2652
  else
2653
    {
2654
      int j = 0, m = 0;
2655
 
2656
      switch (s[0])
2657
        {
2658
        default:
2659
          fprintf (stderr, "expand_opcode: illegal char '%c'\n", s[0]);
2660
          exit (1);
2661
        case '0':
2662
        case '1':
2663
          /* Consume an arbitrary number of ones and zeros.  */
2664
          do {
2665
            j = (j << 1) + (s[m++] - '0');
2666
          } while (s[m] == '0' || s[m] == '1');
2667
          expand_opcode ((val << m) | j, i, s + m);
2668
          break;
2669
        case 'N':       /* NN -- four-way fork */
2670
          for (j = 0; j < 4; j++)
2671
            expand_opcode ((val << 2) | j, i, s + 2);
2672
          break;
2673
        case 'x':       /* xx or xy -- two-way or four-way fork */
2674
          for (j = 0; j < 4; j += (s[1] == 'x' ? 2 : 1))
2675
            expand_opcode ((val << 2) | j, i, s + 2);
2676
          break;
2677
        case 'y':       /* yy or yx -- two-way or four-way fork */
2678
          for (j = 0; j < (s[1] == 'x' ? 4 : 2); j++)
2679
            expand_opcode ((val << 2) | j, i, s + 2);
2680
          break;
2681
        case '?':       /* Seven-way "wildcard" fork for movxy */
2682
          expand_opcode ((val << 2), i, s + 2);
2683
          for (j = 1; j < 4; j++)
2684
            {
2685
              expand_opcode ((val << 2) | j, i, s + 2);
2686
              expand_opcode ((val << 2) | (j + 16), i, s + 2);
2687
            }
2688
          break;
2689
        case 'i':       /* eg. "i8*1" */
2690
        case '.':       /* "...." is a wildcard */
2691
        case 'n':
2692
        case 'm':
2693
          /* nnnn, mmmm, i#*#, .... -- 16-way fork.  */
2694
          for (j = 0; j < 16; j++)
2695
            expand_opcode ((val << 4) | j, i, s + 4);
2696
          break;
2697
        case 'e':
2698
          /* eeee -- even numbered register:
2699
             8 way fork.  */
2700
          for (j = 0; j < 15; j += 2)
2701
            expand_opcode ((val << 4) | j, i, s + 4);
2702
          break;
2703
        case 'M':
2704
          /* A0, A1, X0, X1, Y0, Y1, M0, M1, A0G, A1G:
2705
             MMMM -- 10-way fork */
2706
          expand_opcode ((val << 4) | 5, i, s + 4);
2707
          for (j = 7; j < 16; j++)
2708
            expand_opcode ((val << 4) | j, i, s + 4);
2709
          break;
2710
        case 'G':
2711
          /* A1G, A0G:
2712
             GGGG -- two-way fork */
2713
          for (j = 13; j <= 15; j +=2)
2714
            expand_opcode ((val << 4) | j, i, s + 4);
2715
          break;
2716
        case 's':
2717
          /* ssss -- 10-way fork */
2718
          /* System registers mach, macl, pr: */
2719
          for (j = 0; j < 3; j++)
2720
            expand_opcode ((val << 4) | j, i, s + 4);
2721
          /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */
2722
          for (j = 5; j < 12; j++)
2723
            expand_opcode ((val << 4) | j, i, s + 4);
2724
          break;
2725
        case 'X':
2726
          /* XX/XY -- 2/4 way fork.  */
2727
          for (j = 0; j < 4; j += (s[1] == 'X' ? 2 : 1))
2728
            expand_opcode ((val << 2) | j, i, s + 2);
2729
          break;
2730
        case 'a':
2731
          /* aa/ax -- 2/4 way fork.  */
2732
          for (j = 0; j < 4; j += (s[1] == 'a' ? 2 : 1))
2733
            expand_opcode ((val << 2) | j, i, s + 2);
2734
          break;
2735
        case 'Y':
2736
          /* YY/YX -- 2/4 way fork.  */
2737
          for (j = 0; j < (s[1] == 'Y' ? 2 : 4); j += 1)
2738
            expand_opcode ((val << 2) | j, i, s + 2);
2739
          break;
2740
        case 'A':
2741
          /* AA/AY: 2/4 way fork.  */
2742
          for (j = 0; j < (s[1] == 'A' ? 2 : 4); j += 1)
2743
            expand_opcode ((val << 2) | j, i, s + 2);
2744
          break;
2745
        case 'v':
2746
          /* vv(VV) -- 4(16) way fork.  */
2747
          /* Vector register fv0/4/8/12.  */
2748
          if (s[2] == 'V')
2749
            {
2750
              /* 2 vector registers.  */
2751
              for (j = 0; j < 15; j++)
2752
                expand_opcode ((val << 4) | j, i, s + 4);
2753
            }
2754
          else
2755
            {
2756
              /* 1 vector register.  */
2757
              for (j = 0; j < 4; j += 1)
2758
                expand_opcode ((val << 2) | j, i, s + 2);
2759
            }
2760
          break;
2761
        }
2762
    }
2763
}
2764
 
2765
/* Print the jump table used to index an opcode into a switch
2766
   statement entry.  */
2767
 
2768
static void
2769
dumptable (name, size, start)
2770
     char *name;
2771
     int size;
2772
     int start;
2773
{
2774
  int lump = 256;
2775
  int online = 16;
2776
 
2777
  int i = start;
2778
 
2779
  printf ("unsigned short %s[%d]={\n", name, size);
2780
  while (i < start + size)
2781
    {
2782
      int j = 0;
2783
 
2784
      printf ("/* 0x%x */\n", i);
2785
 
2786
      while (j < lump)
2787
        {
2788
          int k = 0;
2789
          while (k < online)
2790
            {
2791
              printf ("%2d", table[i + j + k]);
2792
              if (j + k < lump)
2793
                printf (",");
2794
 
2795
              k++;
2796
            }
2797
          j += k;
2798
          printf ("\n");
2799
        }
2800
      i += j;
2801
    }
2802
  printf ("};\n");
2803
}
2804
 
2805
 
2806
static void
2807
filltable (p)
2808
     op *p;
2809
{
2810
  static int index = 1;
2811
 
2812
  sorttab ();
2813
  for (; p->name; p++)
2814
    {
2815
      p->index = index++;
2816
      expand_opcode (0, p->index, p->code);
2817
    }
2818
}
2819
 
2820
/* Table already contains all the switch case tags for 16-bit opcode double
2821
   data transfer (ddt) insns, and the switch case tag for processing parallel
2822
   processing insns (ppi) for code 0xf800 (ppi nopx nopy).  Copy the
2823
   latter tag to represent all combinations of ppi with ddt.  */
2824
static void
2825
expand_ppi_movxy ()
2826
{
2827
  int i;
2828
 
2829
  for (i = 0xf000; i < 0xf400; i++)
2830
    if (table[i])
2831
      table[i + 0x800] = table[0xf800];
2832
}
2833
 
2834
static void
2835
gensim_caselist (p)
2836
     op *p;
2837
{
2838
  for (; p->name; p++)
2839
    {
2840
      int j;
2841
      int sextbit = -1;
2842
      int needm = 0;
2843
      int needn = 0;
2844
 
2845
      char *s = p->code;
2846
 
2847
      printf ("  /* %s %s */\n", p->name, p->code);
2848
      printf ("  case %d:      \n", p->index);
2849
 
2850
      printf ("    {\n");
2851
      while (*s)
2852
        {
2853
          switch (*s)
2854
            {
2855
            default:
2856
              fprintf (stderr, "gencode/gensim_caselist: illegal char '%c'\n",
2857
                       *s);
2858
              exit (1);
2859
              break;
2860
            case '?':
2861
              /* Wildcard expansion, nothing to do here.  */
2862
              s += 2;
2863
              break;
2864
            case 'v':
2865
              printf ("      int v1 = ((iword >> 10) & 3) * 4;\n");
2866
              s += 2;
2867
              break;
2868
            case 'V':
2869
              printf ("      int v2 = ((iword >> 8)  & 3) * 4;\n");
2870
              s += 2;
2871
              break;
2872
            case '0':
2873
            case '1':
2874
              s += 2;
2875
              break;
2876
            case '.':
2877
              s += 4;
2878
              break;
2879
            case 'n':
2880
            case 'e':
2881
              printf ("      int n = (iword >> 8) & 0xf;\n");
2882
              needn = 1;
2883
              s += 4;
2884
              break;
2885
            case 'N':
2886
              printf ("      int n = (((iword >> 8) - 2) & 0x3) + 2;\n");
2887
              s += 2;
2888
              break;
2889
            case 'x':
2890
              if (s[1] == 'y')  /* xy */
2891
                {
2892
                  printf ("      int n = (iword & 3) ? \n");
2893
                  printf ("              ((iword >> 9) & 1) + 4 : \n");
2894
                  printf ("              REG_xy ((iword >> 8) & 3);\n");
2895
                }
2896
              else
2897
                printf ("      int n = ((iword >> 9) & 1) + 4;\n");
2898
              needn = 1;
2899
              s += 2;
2900
              break;
2901
            case 'y':
2902
              if (s[1] == 'x')  /* yx */
2903
                {
2904
                  printf ("      int n = (iword & 0xc) ? \n");
2905
                  printf ("              ((iword >> 8) & 1) + 6 : \n");
2906
                  printf ("              REG_yx ((iword >> 8) & 3);\n");
2907
                }
2908
              else
2909
                printf ("      int n = ((iword >> 8) & 1) + 6;\n");
2910
              needn = 1;
2911
              s += 2;
2912
              break;
2913
            case 'm':
2914
              needm = 1;
2915
            case 's':
2916
            case 'M':
2917
            case 'G':
2918
              printf ("      int m = (iword >> 4) & 0xf;\n");
2919
              s += 4;
2920
              break;
2921
            case 'X':
2922
              if (s[1] == 'Y')  /* XY */
2923
                {
2924
                  printf ("      int m = (iword & 3) ? \n");
2925
                  printf ("              ((iword >> 7) & 1) + 8 : \n");
2926
                  printf ("              DSP_xy ((iword >> 6) & 3);\n");
2927
                }
2928
              else
2929
                printf ("      int m = ((iword >> 7) & 1) + 8;\n");
2930
              s += 2;
2931
              break;
2932
            case 'a':
2933
              if (s[1] == 'x')  /* ax */
2934
                {
2935
                  printf ("      int m = (iword & 3) ? \n");
2936
                  printf ("              7 - ((iword >> 6) & 2) : \n");
2937
                  printf ("              DSP_ax ((iword >> 6) & 3);\n");
2938
                }
2939
              else
2940
                printf ("      int m = 7 - ((iword >> 6) & 2);\n");
2941
              s += 2;
2942
              break;
2943
            case 'Y':
2944
              if (s[1] == 'X')  /* YX */
2945
                {
2946
                  printf ("      int m = (iword & 0xc) ? \n");
2947
                  printf ("              ((iword >> 6) & 1) + 10 : \n");
2948
                  printf ("              DSP_yx ((iword >> 6) & 3);\n");
2949
                }
2950
              else
2951
                printf ("      int m = ((iword >> 6) & 1) + 10;\n");
2952
              s += 2;
2953
              break;
2954
            case 'A':
2955
              if (s[1] == 'Y')  /* AY */
2956
                {
2957
                  printf ("      int m = (iword & 0xc) ? \n");
2958
                  printf ("              7 - ((iword >> 5) & 2) : \n");
2959
                  printf ("              DSP_ay ((iword >> 6) & 3);\n");
2960
                }
2961
              else
2962
                printf ("      int m = 7 - ((iword >> 5) & 2);\n");
2963
              s += 2;
2964
              break;
2965
 
2966
            case 'i':
2967
              printf ("      int i = (iword & 0x");
2968
 
2969
              switch (s[1])
2970
                {
2971
                default:
2972
                  fprintf (stderr,
2973
                           "gensim_caselist: Unknown char '%c' in %s\n",
2974
                           s[1], s);
2975
                  exit (1);
2976
                  break;
2977
                case '4':
2978
                  printf ("f");
2979
                  break;
2980
                case '8':
2981
                  printf ("ff");
2982
                  break;
2983
                case '1':
2984
                  sextbit = 12;
2985
                  printf ("fff");
2986
                  break;
2987
                }
2988
              printf (")");
2989
 
2990
              switch (s[3])
2991
                {
2992
                default:
2993
                  fprintf (stderr,
2994
                           "gensim_caselist: Unknown char '%c' in %s\n",
2995
                           s[3], s);
2996
                  exit (1);
2997
                  break;
2998
                case '.':       /* eg. "i12." */
2999
                  break;
3000
                case '1':
3001
                  break;
3002
                case '2':
3003
                  printf (" << 1");
3004
                  break;
3005
                case '4':
3006
                  printf (" << 2");
3007
                  break;
3008
                }
3009
              printf (";\n");
3010
              s += 4;
3011
            }
3012
        }
3013
      if (sextbit > 0)
3014
        {
3015
          printf ("      i = (i ^ (1 << %d)) - (1 << %d);\n",
3016
                  sextbit - 1, sextbit - 1);
3017
        }
3018
 
3019
      if (needm && needn)
3020
        printf ("      TB (m,n);\n");
3021
      else if (needm)
3022
        printf ("      TL (m);\n");
3023
      else if (needn)
3024
        printf ("      TL (n);\n");
3025
 
3026
      {
3027
        /* Do the refs.  */
3028
        char *r;
3029
        for (r = p->refs; *r; r++)
3030
          {
3031
            if (*r == 'f') printf ("      CREF (15);\n");
3032
            if (*r == '-')
3033
              {
3034
                printf ("      {\n");
3035
                printf ("        int i = n;\n");
3036
                printf ("        do {\n");
3037
                printf ("          CREF (i);\n");
3038
                printf ("        } while (i-- > 0);\n");
3039
                printf ("      }\n");
3040
              }
3041
            if (*r == '+')
3042
              {
3043
                printf ("      {\n");
3044
                printf ("        int i = n;\n");
3045
                printf ("        do {\n");
3046
                printf ("          CREF (i);\n");
3047
                printf ("        } while (i++ < 14);\n");
3048
                printf ("      }\n");
3049
              }
3050
            if (*r == '0') printf ("      CREF (0);\n");
3051
            if (*r == '8') printf ("      CREF (8);\n");
3052
            if (*r == '9') printf ("      CREF (9);\n");
3053
            if (*r == 'n') printf ("      CREF (n);\n");
3054
            if (*r == 'm') printf ("      CREF (m);\n");
3055
          }
3056
      }
3057
 
3058
      printf ("      {\n");
3059
      for (j = 0; j < MAX_NR_STUFF; j++)
3060
        {
3061
          if (p->stuff[j])
3062
            {
3063
              printf ("        %s\n", p->stuff[j]);
3064
            }
3065
        }
3066
      printf ("      }\n");
3067
 
3068
      {
3069
        /* Do the defs.  */
3070
        char *r;
3071
        for (r = p->defs; *r; r++)
3072
          {
3073
            if (*r == 'f') printf ("      CDEF (15);\n");
3074
            if (*r == '-')
3075
              {
3076
                printf ("      {\n");
3077
                printf ("        int i = n;\n");
3078
                printf ("        do {\n");
3079
                printf ("          CDEF (i);\n");
3080
                printf ("        } while (i-- > 0);\n");
3081
                printf ("      }\n");
3082
              }
3083
            if (*r == '+')
3084
              {
3085
                printf ("      {\n");
3086
                printf ("        int i = n;\n");
3087
                printf ("        do {\n");
3088
                printf ("          CDEF (i);\n");
3089
                printf ("        } while (i++ < 14);\n");
3090
                printf ("      }\n");
3091
              }
3092
            if (*r == '0') printf ("      CDEF (0);\n");
3093
            if (*r == 'n') printf ("      CDEF (n);\n");
3094
            if (*r == 'm') printf ("      CDEF (m);\n");
3095
          }
3096
      }
3097
 
3098
      printf ("      break;\n");
3099
      printf ("    }\n");
3100
    }
3101
}
3102
 
3103
static void
3104
gensim ()
3105
{
3106
  printf ("{\n");
3107
  printf ("/* REG_xy = [r4, r5, r0, r1].  */\n");
3108
  printf ("#define REG_xy(R) ((R)==0 ? 4 : (R)==2 ? 5 : (R)==1 ?  0 :  1)\n");
3109
  printf ("/* REG_yx = [r6, r7, r2, r3].  */\n");
3110
  printf ("#define REG_yx(R) ((R)==0 ? 6 : (R)==1 ? 7 : (R)==2 ?  2 :  3)\n");
3111
  printf ("/* DSP_ax = [a0, a1, x0, x1].  */\n");
3112
  printf ("#define DSP_ax(R) ((R)==0 ? 7 : (R)==2 ? 5 : (R)==1 ?  8 :  9)\n");
3113
  printf ("/* DSP_ay = [a0, a1, y0, y1].  */\n");
3114
  printf ("#define DSP_ay(R) ((R)==0 ? 7 : (R)==1 ? 5 : (R)==2 ? 10 : 11)\n");
3115
  printf ("/* DSP_xy = [x0, x1, y0, y1].  */\n");
3116
  printf ("#define DSP_xy(R) ((R)==0 ? 8 : (R)==2 ? 9 : (R)==1 ? 10 : 11)\n");
3117
  printf ("/* DSP_yx = [y0, y1, x0, x1].  */\n");
3118
  printf ("#define DSP_yx(R) ((R)==0 ? 10 : (R)==1 ? 11 : (R)==2 ? 8 : 9)\n");
3119
  printf ("  switch (jump_table[iword]) {\n");
3120
 
3121
  gensim_caselist (tab);
3122
  gensim_caselist (movsxy_tab);
3123
 
3124
  printf ("  default:\n");
3125
  printf ("    {\n");
3126
  printf ("      RAISE_EXCEPTION (SIGILL);\n");
3127
  printf ("    }\n");
3128
  printf ("  }\n");
3129
  printf ("}\n");
3130
}
3131
 
3132
static void
3133
gendefines ()
3134
{
3135
  op *p;
3136
  filltable (tab);
3137
  for (p = tab; p->name; p++)
3138
    {
3139
      char *s = p->name;
3140
      printf ("#define OPC_");
3141
      while (*s) {
3142
        if (isupper (*s))
3143
          *s = tolower (*s);
3144
        if (isalpha (*s))
3145
          printf ("%c", *s);
3146
        if (*s == ' ')
3147
          printf ("_");
3148
        if (*s == '@')
3149
          printf ("ind_");
3150
        if (*s == ',')
3151
          printf ("_");
3152
        s++;
3153
      }
3154
      printf (" %d\n",p->index);
3155
    }
3156
}
3157
 
3158
static int ppi_index;
3159
 
3160
/* Take a ppi code, expand all varying fields in it and fill all the
3161
   right entries in 'table' with the opcode index.
3162
   NOTE: tail recursion optimization removed for simplicity.  */
3163
 
3164
static void
3165
expand_ppi_code (val, i, s)
3166
     int val;
3167
     int i;
3168
     char *s;
3169
{
3170
  int j;
3171
 
3172
  switch (s[0])
3173
    {
3174
    default:
3175
      fprintf (stderr, "gencode/expand_ppi_code: Illegal char '%c'\n", s[0]);
3176
      exit (2);
3177
      break;
3178
    case 'g':
3179
    case 'z':
3180
      if (warn_conflicts && table[val] != 0)
3181
        conflict_warn (val, i);
3182
 
3183
      /* The last four bits are disregarded for the switch table.  */
3184
      table[val] = i;
3185
      return;
3186
    case 'm':
3187
      /* Four-bit expansion.  */
3188
      for (j = 0; j < 16; j++)
3189
        expand_ppi_code ((val << 4) + j, i, s + 4);
3190
      break;
3191
    case '.':
3192
    case '0':
3193
      expand_ppi_code ((val << 1), i, s + 1);
3194
      break;
3195
    case '1':
3196
      expand_ppi_code ((val << 1) + 1, i, s + 1);
3197
      break;
3198
    case 'i':
3199
    case 'e': case 'f':
3200
    case 'x': case 'y':
3201
      expand_ppi_code ((val << 1), i, s + 1);
3202
      expand_ppi_code ((val << 1) + 1, i, s + 1);
3203
      break;
3204
    case 'c':
3205
      expand_ppi_code ((val << 2) + 1, ppi_index++, s + 2);
3206
      expand_ppi_code ((val << 2) + 2, i, s + 2);
3207
      expand_ppi_code ((val << 2) + 3, i, s + 2);
3208
      break;
3209
    }
3210
}
3211
 
3212
static void
3213
ppi_filltable ()
3214
{
3215
  op *p;
3216
  ppi_index = 1;
3217
 
3218
  for (p = ppi_tab; p->name; p++)
3219
    {
3220
      p->index = ppi_index++;
3221
      expand_ppi_code (0, p->index, p->code);
3222
    }
3223
}
3224
 
3225
static void
3226
ppi_gensim ()
3227
{
3228
  op *p = ppi_tab;
3229
 
3230
  printf ("#define DSR_MASK_G 0x80\n");
3231
  printf ("#define DSR_MASK_Z 0x40\n");
3232
  printf ("#define DSR_MASK_N 0x20\n");
3233
  printf ("#define DSR_MASK_V 0x10\n");
3234
  printf ("\n");
3235
  printf ("#define COMPUTE_OVERFLOW do {\\\n");
3236
  printf ("  overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n");
3237
  printf ("  if (overflow && S) \\\n");
3238
  printf ("    { \\\n");
3239
  printf ("      if (res_grd & 0x80) \\\n");
3240
  printf ("        { \\\n");
3241
  printf ("          res = 0x80000000; \\\n");
3242
  printf ("          res_grd |=  0xff; \\\n");
3243
  printf ("        } \\\n");
3244
  printf ("      else \\\n");
3245
  printf ("        { \\\n");
3246
  printf ("          res = 0x7fffffff; \\\n");
3247
  printf ("          res_grd &= ~0xff; \\\n");
3248
  printf ("        } \\\n");
3249
  printf ("      overflow = 0; \\\n");
3250
  printf ("    } \\\n");
3251
  printf ("} while (0)\n");
3252
  printf ("\n");
3253
  printf ("#define ADD_SUB_GE \\\n");
3254
  printf ("  (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n");
3255
  printf ("\n");
3256
  printf ("static void\n");
3257
  printf ("ppi_insn (iword)\n");
3258
  printf ("     int iword;\n");
3259
  printf ("{\n");
3260
  printf ("  /* 'ee' = [x0, x1, y0, a1] */\n");
3261
  printf ("  static char e_tab[] = { 8,  9, 10,  5};\n");
3262
  printf ("  /* 'ff' = [y0, y1, x0, a1] */\n");
3263
  printf ("  static char f_tab[] = {10, 11,  8,  5};\n");
3264
  printf ("  /* 'xx' = [x0, x1, a0, a1]  */\n");
3265
  printf ("  static char x_tab[] = { 8,  9,  7,  5};\n");
3266
  printf ("  /* 'yy' = [y0, y1, m0, m1]  */\n");
3267
  printf ("  static char y_tab[] = {10, 11, 12, 14};\n");
3268
  printf ("  /* 'gg' = [m0, m1, a0, a1]  */\n");
3269
  printf ("  static char g_tab[] = {12, 14,  7,  5};\n");
3270
  printf ("  /* 'uu' = [x0, y0, a0, a1]  */\n");
3271
  printf ("  static char u_tab[] = { 8, 10,  7,  5};\n");
3272
  printf ("\n");
3273
  printf ("  int z;\n");
3274
  printf ("  int res, res_grd;\n");
3275
  printf ("  int carry, overflow, greater_equal;\n");
3276
  printf ("\n");
3277
  printf ("  switch (ppi_table[iword >> 4]) {\n");
3278
 
3279
  for (; p->name; p++)
3280
    {
3281
      int shift, j;
3282
      int cond = 0;
3283
      int havedecl = 0;
3284
 
3285
      char *s = p->code;
3286
 
3287
      printf ("  /* %s %s */\n", p->name, p->code);
3288
      printf ("  case %d:      \n", p->index);
3289
 
3290
      printf ("    {\n");
3291
      for (shift = 16; *s; )
3292
        {
3293
          switch (*s)
3294
            {
3295
            case 'i':
3296
              printf ("      int i = (iword >> 4) & 0x7f;\n");
3297
              s += 6;
3298
              break;
3299
            case 'e':
3300
            case 'f':
3301
            case 'x':
3302
            case 'y':
3303
            case 'g':
3304
            case 'u':
3305
              shift -= 2;
3306
              printf ("      int %c = %c_tab[(iword >> %d) & 3];\n",
3307
                      *s, *s, shift);
3308
              havedecl = 1;
3309
              s += 2;
3310
              break;
3311
            case 'c':
3312
              printf ("      if ((((iword >> 8) ^ DSR) & 1) == 0)\n");
3313
              printf ("\treturn;\n");
3314
              printf ("    }\n");
3315
              printf ("  case %d:      \n", p->index + 1);
3316
              printf ("    {\n");
3317
              cond = 1;
3318
            case '0':
3319
            case '1':
3320
            case '.':
3321
              shift -= 2;
3322
              s += 2;
3323
              break;
3324
            case 'z':
3325
              if (havedecl)
3326
                printf ("\n");
3327
              printf ("      z = iword & 0xf;\n");
3328
              havedecl = 2;
3329
              s += 4;
3330
              break;
3331
            }
3332
        }
3333
      if (havedecl == 1)
3334
        printf ("\n");
3335
      else if (havedecl == 2)
3336
        printf ("      {\n");
3337
      for (j = 0; j < MAX_NR_STUFF; j++)
3338
        {
3339
          if (p->stuff[j])
3340
            {
3341
              printf ("      %s%s\n",
3342
                      (havedecl == 2 ? "  " : ""),
3343
                      p->stuff[j]);
3344
            }
3345
        }
3346
      if (havedecl == 2)
3347
        printf ("      }\n");
3348
      if (cond)
3349
        {
3350
          printf ("      if (iword & 0x200)\n");
3351
          printf ("        goto assign_z;\n");
3352
        }
3353
      printf ("      break;\n");
3354
      printf ("    }\n");
3355
    }
3356
 
3357
  printf ("  default:\n");
3358
  printf ("    {\n");
3359
  printf ("      RAISE_EXCEPTION (SIGILL);\n");
3360
  printf ("      return;\n");
3361
  printf ("    }\n");
3362
  printf ("  }\n");
3363
  printf ("  DSR &= ~0xf1;\n");
3364
  printf ("  if (res || res_grd)\n");
3365
  printf ("    DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n");
3366
  printf ("  else\n");
3367
  printf ("    DSR |= DSR_MASK_Z | overflow;\n");
3368
  printf (" assign_dc:\n");
3369
  printf ("  switch (DSR >> 1 & 7)\n");
3370
  printf ("    {\n");
3371
  printf ("    case 0: /* Carry Mode */\n");
3372
  printf ("      DSR |= carry;\n");
3373
  printf ("    case 1: /* Negative Value Mode */\n");
3374
  printf ("      DSR |= res_grd >> 7 & 1;\n");
3375
  printf ("    case 2: /* Zero Value Mode */\n");
3376
  printf ("      DSR |= DSR >> 6 & 1;\n");
3377
  printf ("    case 3: /* Overflow mode\n");
3378
  printf ("      DSR |= overflow >> 4;\n");
3379
  printf ("    case 4: /* Signed Greater Than Mode */\n");
3380
  printf ("      DSR |= DSR >> 7 & 1;\n");
3381
  printf ("    case 4: /* Signed Greater Than Or Equal Mode */\n");
3382
  printf ("      DSR |= greater_equal >> 7;\n");
3383
  printf ("    }\n");
3384
  printf (" assign_z:\n");
3385
  printf ("  if (0xa05f >> z & 1)\n");
3386
  printf ("    {\n");
3387
  printf ("      RAISE_EXCEPTION (SIGILL);\n");
3388
  printf ("      return;\n");
3389
  printf ("    }\n");
3390
  printf ("  DSP_R (z) = res;\n");
3391
  printf ("  DSP_GRD (z) = res_grd;\n");
3392
  printf ("}\n");
3393
}
3394
 
3395
int
3396
main (ac, av)
3397
     int ac;
3398
     char **av;
3399
{
3400
  /* Verify the table before anything else.  */
3401
  {
3402
    op *p;
3403
    for (p = tab; p->name; p++)
3404
      {
3405
        /* Check that the code field contains 16 bits.  */
3406
        if (strlen (p->code) != 16)
3407
          {
3408
            fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n",
3409
                     p->code, strlen (p->code), p->name);
3410
            abort ();
3411
          }
3412
      }
3413
  }
3414
 
3415
  /* Now generate the requested data.  */
3416
  if (ac > 1)
3417
    {
3418
      if (ac > 2 && strcmp (av[2], "-w") == 0)
3419
        {
3420
          warn_conflicts = 1;
3421
        }
3422
      if (strcmp (av[1], "-t") == 0)
3423
        {
3424
          gengastab ();
3425
        }
3426
      else if (strcmp (av[1], "-d") == 0)
3427
        {
3428
          gendefines ();
3429
        }
3430
      else if (strcmp (av[1], "-s") == 0)
3431
        {
3432
          filltable (tab);
3433
          dumptable ("sh_jump_table", 1 << 16, 0);
3434
 
3435
          memset (table, 0, sizeof table);
3436
          filltable (movsxy_tab);
3437
          expand_ppi_movxy ();
3438
          dumptable ("sh_dsp_table", 1 << 12, 0xf000);
3439
 
3440
          memset (table, 0, sizeof table);
3441
          ppi_filltable ();
3442
          dumptable ("ppi_table", 1 << 12, 0);
3443
        }
3444
      else if (strcmp (av[1], "-x") == 0)
3445
        {
3446
          filltable (tab);
3447
          filltable (movsxy_tab);
3448
          gensim ();
3449
        }
3450
      else if (strcmp (av[1], "-p") == 0)
3451
        {
3452
          ppi_filltable ();
3453
          ppi_gensim ();
3454
        }
3455
    }
3456
  else
3457
    fprintf (stderr, "Opcode table generation no longer supported.\n");
3458
  return 0;
3459
}

powered by: WebSVN 2.1.0

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