Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1186 savelij 1
/* code960.c */
2
/*****************************************************************************/
3
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
4
/*                                                                           */
5
/* Makroassembler AS                                                         */
6
/*                                                                           */
7
/* Codegenerator i960-Familie                                                */
8
/*                                                                           */
9
/*****************************************************************************/
10
 
11
#include "stdinc.h"
12
#include <string.h>
13
#include <ctype.h>
14
 
15
#include "be_le.h"
16
#include "strutil.h"
17
#include "bpemu.h"
18
#include "asmdef.h"
19
#include "asmsub.h"
20
#include "asmpars.h"
21
#include "asmallg.h"
22
#include "onoff_common.h"
23
#include "asmitree.h"
24
#include "codevars.h"
25
#include "codepseudo.h"
26
#include "intpseudo.h"
27
#include "headids.h"
28
#include "errmsg.h"
29
 
30
#include "code960.h"
31
 
32
/*--------------------------------------------------------------------------*/
33
 
34
enum
35
{
36
  ModNone = -1,
37
  ModReg = 0,
38
  ModFReg = 1,
39
  ModImm = 2
40
};
41
 
42
#define MModReg (1 << ModReg)
43
#define MModFReg (1 << ModFReg)
44
#define MModImm (1 << ModImm)
45
 
46
typedef enum
47
{
48
  NoneOp, IntOp, LongOp, QuadOp, SingleOp, DoubleOp, ExtOp, OpCnt
49
} OpType;
50
 
51
static LongWord OpMasks[OpCnt] =
52
{
53
  0xffffffff, 0, 1, 3, 0, 1, 3
54
};
55
 
56
typedef struct
57
{
58
  LongWord Code;
59
} FixedOrder;
60
 
61
typedef struct
62
{
63
  LongWord Code;
64
  Boolean HasSrc;
65
} CobrOrder;
66
 
67
typedef struct
68
{
69
  LongWord Code;
70
  OpType Src1Type, Src2Type, DestType;
71
  Boolean Imm1, Imm2, Privileged;
72
} RegOrder;
73
 
74
typedef struct
75
{
76
  LongWord Code;
77
  OpType Type;
78
  ShortInt RegPos;
79
} MemOrder;
80
 
81
typedef struct
82
{
83
  char Name[4];
84
  LongWord Code;
85
} SpecReg;
86
 
87
static FixedOrder *FixedOrders;
88
static RegOrder *RegOrders;
89
static CobrOrder *CobrOrders;
90
static FixedOrder *CtrlOrders;
91
static MemOrder *MemOrders;
92
static const SpecReg SpecRegs[] =
93
{
94
  { "FP" , 31 },
95
  { "PFP",  0 },
96
  { "SP" ,  1 },
97
  { "RIP",  2 }
98
};
99
 
100
static CPUVar CPU80960;
101
 
102
/*--------------------------------------------------------------------------*/
103
 
104
static Boolean ChkAdr(int AMode, Byte Mask, LongWord *Erg, LongWord *Mode)
105
{
106
  UNUSED(Erg);
107
 
108
  if (!(Mask & (1 << AMode)))
109
  {
110
    WrError(ErrNum_InvAddrMode);
111
    return False;
112
  }
113
  else
114
  {
115
    *Mode = (AMode != ModReg);
116
    return True;
117
  }
118
}
119
 
120
/*!------------------------------------------------------------------------
121
 * \fn     DecodeIRegCore(const char *pArg, LongWord *pResult)
122
 * \brief  check whether argument is a CPU register
123
 * \param  pArg source argument
124
 * \param  pResult register # if yes
125
 * \return True if yes
126
 * ------------------------------------------------------------------------ */
127
 
128
static Boolean DecodeIRegCore(const char *pArg, LongWord *pResult)
129
{
130
  size_t z;
131
  LongWord Offs;
132
 
133
  for (z = 0; z < as_array_size(SpecRegs); z++)
134
   if (!as_strcasecmp(pArg, SpecRegs[z].Name))
135
   {
136
     *pResult = REGSYM_FLAG_ALIAS | SpecRegs[z].Code;
137
     return True;
138
   }
139
 
140
  switch (as_toupper(*pArg))
141
  {
142
    case 'G':
143
      Offs = 16;
144
      goto eval;
145
    case 'R':
146
      Offs = 0;
147
      goto eval;
148
    default:
149
      return False;
150
    eval:
151
    {
152
      char *pEnd;
153
 
154
      *pResult = strtoul(pArg + 1, &pEnd, 10);
155
      if (!*pEnd && (*pResult <= 15))
156
      {
157
        *pResult += Offs;
158
        return True;
159
      }
160
    }
161
  }
162
 
163
  return False;
164
}
165
 
166
/*!------------------------------------------------------------------------
167
 * \fn     DecodeFPRegCore(const char *pArg, LongWord *pResult)
168
 * \brief  check whether argument is an FPU register
169
 * \param  pArg source argument
170
 * \param  pResult register # if yes
171
 * \return True if yes
172
 * ------------------------------------------------------------------------ */
173
 
174
static Boolean DecodeFPRegCore(const char *pArg, LongWord *pResult)
175
{
176
  if (!as_strncasecmp(pArg, "FP", 2))
177
  {
178
    char *pEnd;
179
 
180
    *pResult = strtoul(pArg + 2, &pEnd, 10);
181
    if (!*pEnd && (*pResult <= 3))
182
      return True;
183
  }
184
 
185
  return False;
186
}
187
 
188
/*!------------------------------------------------------------------------
189
 * \fn     DissectReg_960(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
190
 * \brief  dissect register symbols - i960 variant
191
 * \param  pDest destination buffer
192
 * \param  DestSize destination buffer size
193
 * \param  Value numeric register value
194
 * \param  InpSize register size
195
 * ------------------------------------------------------------------------ */
196
 
197
static void DissectReg_960(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
198
{
199
  switch (InpSize)
200
  {
201
    case eSymbolSize32Bit:
202
    {
203
      size_t z;
204
 
205
      for (z = 0; z < as_array_size(SpecRegs); z++)
206
        if (Value == (REGSYM_FLAG_ALIAS | SpecRegs[z].Code))
207
        {
208
          as_snprintf(pDest, DestSize, "%s", SpecRegs[z].Name);
209
          return;
210
        }
211
      as_snprintf(pDest, DestSize, "%c%u", Value & 16 ? 'G' : 'R', (unsigned)(Value & 15));
212
      break;
213
    }
214
    case eSymbolSizeFloat64Bit:
215
      as_snprintf(pDest, DestSize, "FP%u", (unsigned)Value);
216
      break;
217
    default:
218
      as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
219
  }
220
}
221
 
222
/*!------------------------------------------------------------------------
223
 * \fn     DecodeIReg(const tStrComp *pArg, LongWord *pResult, Boolean MustBeReg)
224
 * \brief  check whether argument is a CPU register or register alias
225
 * \param  pArg source argument
226
 * \param  pResult register # if yes
227
 * \param  MustBeReg True if register is expected
228
 * \return reg eval result
229
 * ------------------------------------------------------------------------ */
230
 
231
static tRegEvalResult DecodeIReg(const tStrComp *pArg, LongWord *pResult, Boolean MustBeReg)
232
{
233
  if (DecodeIRegCore(pArg->str.p_str, pResult))
234
  {
235
    *pResult &= ~REGSYM_FLAG_ALIAS;
236
    return eIsReg;
237
  }
238
  else
239
  {
240
    tRegDescr RegDescr;
241
    tEvalResult EvalResult;
242
    tRegEvalResult RegEvalResult;
243
 
244
    RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSize32Bit, MustBeReg);
245
    if (eIsReg == RegEvalResult)
246
      *pResult = RegDescr.Reg & ~REGSYM_FLAG_ALIAS;
247
    return RegEvalResult;
248
  }
249
}
250
 
251
/*!------------------------------------------------------------------------
252
 * \fn     DecodeIOrFPReg(const tStrComp *pArg, LongWord *pResult, tSymbolSize *pSize, Boolean MustBeReg)
253
 * \brief  check whether argument is a CPU/FPU register or register alias
254
 * \param  pArg source argument
255
 * \param  pResult register # if yes
256
 * \param  pSize returns register size/type
257
 * \param  MustBeReg True if register is expected
258
 * \return reg eval result
259
 * ------------------------------------------------------------------------ */
260
 
261
static tRegEvalResult DecodeIOrFPReg(const tStrComp *pArg, LongWord *pResult, tSymbolSize *pSize, Boolean MustBeReg)
262
{
263
  if (DecodeIRegCore(pArg->str.p_str, pResult))
264
  {
265
    *pResult &= ~REGSYM_FLAG_ALIAS;
266
    *pSize = eSymbolSize32Bit;
267
    return eIsReg;
268
  }
269
  else if (DecodeFPRegCore(pArg->str.p_str, pResult))
270
  {
271
    *pSize = eSymbolSizeFloat64Bit;
272
    return eIsReg;
273
  }
274
  else
275
  {
276
    tRegDescr RegDescr;
277
    tEvalResult EvalResult;
278
    tRegEvalResult RegEvalResult;
279
 
280
    RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
281
    if (eIsReg == RegEvalResult)
282
    {
283
      *pResult = RegDescr.Reg & ~REGSYM_FLAG_ALIAS;
284
      *pSize = EvalResult.DataSize;
285
    }
286
    return RegEvalResult;
287
  }
288
}
289
 
290
static Boolean DecodeAdr(const tStrComp *pArg, Byte Mask, OpType Type, LongWord *Erg, LongWord *Mode)
291
{
292
  as_float_t FVal;
293
  tEvalResult EvalResult;
294
  tSymbolSize DataSize;
295
 
296
  *Mode = ModNone;
297
  *Erg = 0;
298
 
299
  switch (DecodeIOrFPReg(pArg, Erg, &DataSize, False))
300
  {
301
    case eIsReg:
302
      switch (DataSize)
303
      {
304
        case eSymbolSize32Bit:
305
          if ((*Erg) & OpMasks[Type])
306
          {
307
            WrStrErrorPos(ErrNum_InvRegPair, pArg);
308
            return False;
309
          }
310
          else
311
            return ChkAdr(ModReg, Mask, Erg, Mode);
312
        case eSymbolSizeFloat64Bit:
313
          return ChkAdr(ModFReg, Mask, Erg, Mode);
314
        default:
315
          break;
316
      }
317
      break;
318
    case eRegAbort:
319
      return False;
320
    case eIsNoReg:
321
      break;
322
  }
323
 
324
  if (Type != IntOp)
325
  {
326
    FVal = EvalStrFloatExpressionWithResult(pArg, &EvalResult);
327
    if (EvalResult.OK)
328
    {
329
      if (mFirstPassUnknown(EvalResult.Flags))
330
        FVal = 0.0;
331
      if (FVal == 0.0)
332
        *Erg = 16;
333
      else if (FVal == 1.0)
334
        *Erg = 22;
335
      else
336
      {
337
        WrError(ErrNum_OverRange);
338
        EvalResult.OK = False;
339
      }
340
      if (EvalResult.OK)
341
        return ChkAdr(ModImm, Mask, Erg, Mode);
342
    }
343
  }
344
  else
345
  {
346
    *Erg = EvalStrIntExpressionWithResult(pArg, UInt5, &EvalResult);
347
    if (EvalResult.OK)
348
      return ChkAdr(ModImm, Mask, Erg, Mode);
349
  }
350
  return False;
351
}
352
 
353
#define NOREG 33
354
#define IPREG 32
355
 
356
static int AddrError(tErrorNum Num)
357
{
358
  WrError(Num);
359
  return -1;
360
}
361
 
362
static int DecodeMem(const tStrComp *pArg, LongWord *Erg, LongWord *Ext)
363
{
364
  LongInt DispAcc;
365
  LongWord Base, Index, Scale, Mode;
366
  Boolean Done;
367
  int ArgLen, Scale2;
368
  char *p, *p2, *end;
369
  Boolean OK;
370
  tStrComp Arg = *pArg, RegArg, ScaleArg;
371
 
372
  Base = Index = NOREG;
373
  Scale = 0;
374
 
375
  /* Register abhobeln */
376
 
377
  Done = FALSE;
378
  do
379
  {
380
    ArgLen = strlen(Arg.str.p_str);
381
    if (ArgLen == 0)
382
      Done = True;
383
    else switch (Arg.str.p_str[ArgLen - 1])
384
    {
385
      case ']':
386
        if (Index != NOREG) return AddrError(ErrNum_InvAddrMode);
387
        for (p = Arg.str.p_str + ArgLen - 1; p >= Arg.str.p_str; p--)
388
          if (*p == '[')
389
            break;
390
        if (p < Arg.str.p_str) return AddrError(ErrNum_BrackErr);
391
        StrCompShorten(&Arg, 1);
392
        StrCompSplitRef(&Arg, &RegArg, &Arg, p);
393
        p2 = strchr(RegArg.str.p_str, '*');
394
        if (p2)
395
        {
396
          StrCompSplitRef(&RegArg, &ScaleArg, &RegArg, p2);
397
          Scale2 = strtol(ScaleArg.str.p_str, &end, 10);
398
          if (*end != '\0') return AddrError(ErrNum_InvAddrMode);
399
          for (Scale = 0; Scale < 5; Scale++, Scale2 = Scale2 >> 1)
400
            if (Odd(Scale2))
401
              break;
402
          if (Scale2 != 1) return AddrError(ErrNum_InvAddrMode);
403
        }
404
        if (DecodeIReg(&RegArg, &Index, True) != eIsReg)
405
          return -1;
406
 
407
        break;
408
      case ')':
409
        if (Base != NOREG) return AddrError(ErrNum_InvAddrMode);
410
        for (p = Arg.str.p_str + ArgLen - 1; p >= Arg.str.p_str; p--)
411
          if (*p == '(')
412
            break;
413
        if (p < Arg.str.p_str) return AddrError(ErrNum_BrackErr);
414
        StrCompShorten(&Arg, 1);
415
        StrCompSplitRef(&Arg, &RegArg, &Arg, p);
416
        if (!as_strcasecmp(RegArg.str.p_str, "IP"))
417
          Base = IPREG;
418
        else if (DecodeIReg(&RegArg, &Base, True) != eIsReg)
419
          return -1;
420
        break;
421
      default:
422
        Done = True;
423
    }
424
  }
425
  while (!Done);
426
 
427
  if (Arg.str.p_str[0])
428
    DispAcc = EvalStrIntExpression(&Arg, Int32, &OK);
429
  else
430
  {
431
    DispAcc = 0;
432
    OK = True;
433
  }
434
 
435
  if (Base == IPREG)
436
  {
437
    DispAcc -= EProgCounter() + 8;
438
    if (Index != NOREG) return AddrError(ErrNum_InvAddrMode);
439
    else
440
    {
441
      *Erg = (5 << 10);
442
      *Ext = DispAcc;
443
      return 1;
444
    }
445
  }
446
  else if ((Index == NOREG) && (DispAcc >= 0) && (DispAcc <= 4095))
447
  {
448
    *Erg = DispAcc;
449
    if (Base != NOREG)
450
      *Erg += 0x2000 + (Base << 14);
451
    return 0;
452
  }
453
  else
454
  {
455
    Mode = (Ord(DispAcc != 0) << 3) + 4 + (Ord(Index != NOREG) << 1) + Ord(Base != NOREG);
456
    if ((Mode & 9) == 0)
457
      Mode += 8;
458
    if (Mode == 5)
459
      Mode--;
460
    *Erg = (Mode << 10);
461
    if (Base != NOREG)
462
      *Erg += Base << 14;
463
    if (Index != NOREG)
464
      *Erg += Index + (Scale << 7);
465
    if (Mode < 8) return 0;
466
    else
467
    {
468
      *Ext = DispAcc;
469
      return 1;
470
    }
471
  }
472
}
473
 
474
/*--------------------------------------------------------------------------*/
475
 
476
static void DecodeFixed(Word Index)
477
{
478
  FixedOrder *Op = FixedOrders + Index;
479
 
480
  if (ChkArgCnt(0, 0))
481
  {
482
    DAsmCode[0] = Op->Code;
483
    CodeLen = 4;
484
  }
485
}
486
 
487
static void DecodeReg(Word Index)
488
{
489
  RegOrder *Op = RegOrders + Index;
490
  LongWord DReg = 0, DMode = 0;
491
  LongWord S1Reg = 0, S1Mode = 0;
492
  LongWord S2Reg = 0, S2Mode = 0;
493
  unsigned NumArgs = 1 + Ord(Op->Src2Type != NoneOp) + Ord(Op->DestType != NoneOp), ActArgCnt;
494
  tStrComp *pDestArg = NULL;
495
 
496
  /* if destination required, but too few args, assume the last op is also destination */
497
 
498
  ActArgCnt = ArgCnt;
499
  if (Op->DestType != NoneOp)
500
  {
501
    if (ArgCnt == 1 + Ord(Op->Src2Type != NoneOp))
502
      ActArgCnt++;
503
    pDestArg = &ArgStr[ArgCnt];
504
  }
505
 
506
  if (!ChkArgCntExt(ActArgCnt, NumArgs, NumArgs));
507
  else if (((Op->DestType >= SingleOp) || (Op->Src1Type >= SingleOp)) && (!FPUAvail)) WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
508
  else if (((Op->DestType == NoneOp) || (DecodeAdr(pDestArg, MModReg | (Op->DestType >= SingleOp ? MModFReg : 0), Op->DestType, &DReg, &DMode)))
509
        && (DecodeAdr(&ArgStr[1], MModReg | (Op->Src1Type >= SingleOp ? MModFReg : 0) | (Op->Imm1 ? MModImm : 0 ), Op->Src1Type, &S1Reg, &S1Mode))
510
        && ((Op->Src2Type == NoneOp) || (DecodeAdr(&ArgStr[2], MModReg | (Op->Src2Type >= SingleOp ? MModFReg : 0) | (Op->Imm2 ? MModImm : 0), Op->Src2Type, &S2Reg, &S2Mode))))
511
  {
512
    DAsmCode[0] = ((Op->Code & 0xff0) << 20)
513
                + ((Op->Code & 0xf) << 7)
514
                + (S1Reg)
515
                + (S2Reg << 14)
516
                + (DReg << 19)
517
                + (S1Mode << 11)
518
                + (S2Mode << 12)
519
                + (DMode << 13);
520
    CodeLen = 4;
521
    if ((Op->Privileged) && (!SupAllowed)) WrError(ErrNum_PrivOrder);
522
  }
523
}
524
 
525
static void DecodeCobr(Word Index)
526
{
527
  CobrOrder *Op = CobrOrders + Index;
528
  LongWord S1Reg, S1Mode;
529
  LongWord S2Reg = 0, S2Mode = 0;
530
  LongInt AdrInt;
531
  Boolean OK;
532
  tSymbolFlags Flags;
533
  unsigned NumArgs = 1 + 2 * Ord(Op->HasSrc);
534
 
535
  if (!ChkArgCnt(NumArgs, NumArgs));
536
  else if ((DecodeAdr(&ArgStr[1], MModReg | (Op->HasSrc ? MModImm : 0), IntOp, &S1Reg, &S1Mode))
537
        && ((!Op->HasSrc) || (DecodeAdr(&ArgStr[2], MModReg, IntOp, &S2Reg, &S2Mode))))
538
  {
539
    OK = True;
540
    Flags = eSymbolFlag_None;
541
    AdrInt = (Op->HasSrc) ? EvalStrIntExpressionWithFlags(&ArgStr[3], UInt32, &OK, &Flags) - EProgCounter() : 0;
542
    if (mFirstPassUnknown(Flags))
543
      AdrInt &= (~3);
544
    if (OK)
545
    {
546
      if (AdrInt & 3) WrError(ErrNum_NotAligned);
547
      else if (!mSymbolQuestionable(Flags) && ((AdrInt < -4096) || (AdrInt > 4090))) WrError(ErrNum_JmpDistTooBig);
548
      else
549
      {
550
        DAsmCode[0] = (Op->Code << 24)
551
                    + (S1Reg << 19)
552
                    + (S2Reg << 14)
553
                    + (S1Mode << 13)
554
                    + (AdrInt & 0x1ffc);
555
        CodeLen = 4;
556
      }
557
    }
558
  }
559
}
560
 
561
static void DecodeCtrl(Word Index)
562
{
563
  FixedOrder *Op = CtrlOrders + Index;
564
  LongInt AdrInt;
565
  tSymbolFlags Flags;
566
  Boolean OK;
567
 
568
  if (ChkArgCnt(1, 1))
569
  {
570
    AdrInt = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt32, &OK, &Flags) - EProgCounter();
571
    if (mFirstPassUnknown(Flags)) AdrInt &= (~3);
572
    if (OK)
573
    {
574
      if (AdrInt & 3) WrError(ErrNum_NotAligned);
575
      else if (!mSymbolQuestionable(Flags) && ((AdrInt < -8388608) || (AdrInt > 8388604))) WrError(ErrNum_JmpDistTooBig);
576
      else
577
      {
578
        DAsmCode[0] = (Op->Code << 24) + (AdrInt & 0xfffffc);
579
        CodeLen = 4;
580
      }
581
    }
582
  }
583
}
584
 
585
static void DecodeMemO(Word Index)
586
{
587
  MemOrder *Op = MemOrders + Index;
588
  LongWord Reg = 0, Mem = 0;
589
  int MemType;
590
  ShortInt MemPos = (Op->RegPos > 0) ? 3 - Op->RegPos : 1;
591
  unsigned NumArgs = 1 + Ord(Op->RegPos > 0);
592
 
593
  if (!ChkArgCnt(NumArgs, NumArgs));
594
  else if ((Op->RegPos > 0) && (DecodeIReg(&ArgStr[Op->RegPos], &Reg, True) != eIsReg));
595
  else if (Reg & OpMasks[Op->Type]) WrStrErrorPos(ErrNum_InvReg, &ArgStr[Op->RegPos]);
596
  else if ((MemType = DecodeMem(&ArgStr[MemPos], &Mem,DAsmCode + 1)) >= 0)
597
  {
598
    DAsmCode[0] = (Op->Code << 24) + (Reg << 19) + Mem;
599
    CodeLen = (1 + MemType) << 2;
600
  }
601
}
602
 
603
static void DecodeWORD(Word Code)
604
{
605
  Boolean OK;
606
  int z;
607
 
608
  UNUSED(Code);
609
 
610
  if (ChkArgCnt(1, ArgCntMax))
611
  {
612
    OK = True;
613
    z = 1;
614
    while ((z <= ArgCnt) && (OK))
615
    {
616
      DAsmCode[z - 1] = EvalStrIntExpression(&ArgStr[z], Int32, &OK);
617
      z++;
618
    }
619
    if (OK)
620
      CodeLen = 4 * ArgCnt;
621
  }
622
}
623
 
624
static void DecodeSPACE(Word Code)
625
{
626
  Boolean OK;
627
  LongWord Size;
628
  tSymbolFlags Flags;
629
 
630
  UNUSED(Code);
631
 
632
  if (ChkArgCnt(1, 1))
633
  {
634
    Size = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &OK, &Flags);
635
    if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
636
    if (OK && !mFirstPassUnknown(Flags))
637
    {
638
      DontPrint = True;
639
      if (!Size) WrError(ErrNum_NullResMem);
640
      CodeLen = Size;
641
      BookKeeping();
642
    }
643
  }
644
}
645
 
646
/*!------------------------------------------------------------------------
647
 * \fn     void check_alignment(Word index)
648
 * \brief  check dword alignment of program counter (required for machine insns)
649
 * ------------------------------------------------------------------------ */
650
 
651
static void check_alignment(Word index)
652
{
653
  UNUSED(index);
654
 
655
  /* Befehlszaehler nicht ausgerichtet? */
656
 
657
  if (EProgCounter() & 3)
658
    WrError(ErrNum_AddrNotAligned);
659
}
660
 
661
/*--------------------------------------------------------------------------*/
662
 
663
static void MakeCode_960(void)
664
{
665
  if (!LookupInstTable(InstTable, OpPart.str.p_str))
666
    WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
667
}
668
 
669
/*--------------------------------------------------------------------------*/
670
 
671
static void AddFixed(const char *NName, LongWord NCode)
672
{
673
  order_array_rsv_end(FixedOrders, FixedOrder);
674
  FixedOrders[InstrZ].Code = NCode;
675
  AddInstTable(InstTable, NName, InstrZ++, DecodeFixed);
676
}
677
 
678
static void AddReg(const char *NName, LongWord NCode,
679
                   OpType NSrc1, OpType NSrc2, OpType NDest,
680
                   Boolean NImm1, Boolean NImm2, Boolean NPriv)
681
{
682
  order_array_rsv_end(RegOrders, RegOrder);
683
  RegOrders[InstrZ].Code = NCode;
684
  RegOrders[InstrZ].Src1Type = NSrc1;
685
  RegOrders[InstrZ].Src2Type = NSrc2;
686
  RegOrders[InstrZ].DestType = NDest;
687
  RegOrders[InstrZ].Imm1 = NImm1;
688
  RegOrders[InstrZ].Imm2 = NImm2;
689
  RegOrders[InstrZ].Privileged = NPriv;
690
  AddInstTable(InstTable, NName, InstrZ++, DecodeReg);
691
}
692
 
693
static void AddCobr(const char *NName, LongWord NCode, Boolean NHas)
694
{
695
  order_array_rsv_end(CobrOrders, CobrOrder);
696
  CobrOrders[InstrZ].Code = NCode;
697
  CobrOrders[InstrZ].HasSrc = NHas;
698
  AddInstTable(InstTable, NName, InstrZ++, DecodeCobr);
699
}
700
 
701
static void AddCtrl(const char *NName, LongWord NCode)
702
{
703
  order_array_rsv_end(CtrlOrders, FixedOrder);
704
  CtrlOrders[InstrZ].Code = NCode;
705
  AddInstTable(InstTable, NName, InstrZ++, DecodeCtrl);
706
}
707
 
708
static void AddMem(const char *NName, LongWord NCode, OpType NType, int NPos)
709
{
710
  order_array_rsv_end(MemOrders, MemOrder);
711
  MemOrders[InstrZ].Code = NCode;
712
  MemOrders[InstrZ].Type = NType;
713
  MemOrders[InstrZ].RegPos = NPos;
714
  AddInstTable(InstTable, NName, InstrZ++, DecodeMemO);
715
}
716
 
717
static void InitFields(void)
718
{
719
  InstTable = CreateInstTable(301);
720
 
721
  add_null_pseudo(InstTable);
722
 
723
  inst_table_set_prefix_proc(InstTable, check_alignment, 0);
724
  InstrZ = 0;
725
  AddFixed("FLUSHREG", 0x66000680);
726
  AddFixed("FMARK"   , 0x66000600);
727
  AddFixed("MARK"    , 0x66000580);
728
  AddFixed("RET"     , 0x0a000000);
729
  AddFixed("SYNCF"   , 0x66000780);
730
  AddFixed("FAULTNO" , 0x18000000);
731
  AddFixed("FAULTG"  , 0x19000000);
732
  AddFixed("FAULTE"  , 0x1a000000);
733
  AddFixed("FAULTGE" , 0x1b000000);
734
  AddFixed("FAULTL"  , 0x1c000000);
735
  AddFixed("FAULTNE" , 0x1d000000);
736
  AddFixed("FAULTLE" , 0x1e000000);
737
  AddFixed("FAULTO"  , 0x1f000000);
738
 
739
  InstrZ = 0;
740
      /*  Name       OpCode Src1Type  Src2Type  DestType  Imm1   Imm2 */
741
  AddReg("ADDC"    , 0x5b0, IntOp   , IntOp   , IntOp   , True , True , False);
742
  AddReg("ADDI"    , 0x591, IntOp   , IntOp   , IntOp   , True , True , False);
743
  AddReg("ADDO"    , 0x590, IntOp   , IntOp   , IntOp   , True , True , False);
744
  AddReg("ADDR"    , 0x78f, SingleOp, SingleOp, SingleOp, True , True , False);
745
  AddReg("ADDRL"   , 0x79f, DoubleOp, DoubleOp, DoubleOp, True , True , False);
746
  AddReg("ALTERBIT", 0x58f, IntOp   , IntOp   , IntOp   , True , True , False);
747
  AddReg("AND"     , 0x581, IntOp   , IntOp   , IntOp   , True , True , False);
748
  AddReg("ANDNOT"  , 0x582, IntOp   , IntOp   , IntOp   , True , True , False);
749
  AddReg("ATADD"   , 0x612, IntOp   , IntOp   , IntOp   , True , True , False);
750
  AddReg("ATANR"   , 0x680, SingleOp, SingleOp, SingleOp, True , True , False);
751
  AddReg("ATANRL"  , 0x690, DoubleOp, DoubleOp, DoubleOp, True , True , False);
752
  AddReg("ATMOD"   , 0x610, IntOp   , IntOp   , IntOp   , True , True , False);
753
  AddReg("CALLS"   , 0x660, IntOp   , NoneOp  , NoneOp  , True , False, False);
754
  AddReg("CHKBIT"  , 0x5ae, IntOp   , IntOp   , NoneOp  , True , True , False);
755
  AddReg("CLASSR"  , 0x68f, SingleOp, NoneOp  , NoneOp  , True , False, False);
756
  AddReg("CLASSRL" , 0x69f, DoubleOp, NoneOp  , NoneOp  , True , False, False);
757
  AddReg("CLRBIT"  , 0x58c, IntOp   , IntOp   , IntOp   , True , True , False);
758
  AddReg("CMPDECI" , 0x5a7, IntOp   , IntOp   , IntOp   , True , False, False);
759
  AddReg("CMPDECO" , 0x5a6, IntOp   , IntOp   , IntOp   , True , False, False);
760
  AddReg("CMPI"    , 0x5a1, IntOp   , IntOp   , NoneOp  , True , True , False);
761
  AddReg("CMPO"    , 0x5a0, IntOp   , IntOp   , NoneOp  , True , True , False);
762
  AddReg("CMPINCI" , 0x5a5, IntOp   , IntOp   , IntOp   , True , False, False);
763
  AddReg("CMPINCO" , 0x5a4, IntOp   , IntOp   , IntOp   , True , False, False);
764
  AddReg("CMPOR"   , 0x684, SingleOp, SingleOp, NoneOp  , True , True , False);
765
  AddReg("CMPORL"  , 0x694, DoubleOp, DoubleOp, NoneOp  , True , True , False);
766
  AddReg("CMPR"    , 0x685, SingleOp, SingleOp, NoneOp  , True , True , False);
767
  AddReg("CMPRL"   , 0x695, DoubleOp, DoubleOp, NoneOp  , True , True , False);
768
  AddReg("CONCMPI" , 0x5a3, IntOp   , IntOp   , NoneOp  , True , True , False);
769
  AddReg("CONCMPO" , 0x5a2, IntOp   , IntOp   , NoneOp  , True , True , False);
770
  AddReg("COSR"    , 0x68d, SingleOp, NoneOp  , SingleOp, True , False, False);
771
  AddReg("COSRL"   , 0x69d, DoubleOp, NoneOp  , DoubleOp, True , False, False);
772
  AddReg("CPYSRE"  , 0x6e2, SingleOp, SingleOp, SingleOp, True , True , False);
773
  AddReg("CPYRSRE" , 0x6e3, SingleOp, SingleOp, SingleOp, True , True , False);
774
  AddReg("CVTIR"   , 0x674, IntOp,    NoneOp  , SingleOp, True , False, False);
775
  AddReg("CVTILR"  , 0x675, LongOp,   NoneOp  , DoubleOp, True , False, False);
776
  AddReg("CVTRI"   , 0x6c0, SingleOp, NoneOp  , IntOp   , True , False, False);
777
  AddReg("CVTRIL"  , 0x6c1, SingleOp, NoneOp  , LongOp  , True , False, False);
778
  AddReg("CVTZRI"  , 0x6c2, IntOp   , NoneOp  , IntOp   , True , False, False);
779
  AddReg("CVTZRIL" , 0x6c2, LongOp  , NoneOp  , LongOp  , True , False, False);
780
      /*  Name       OpCode Src1Type  Src2Type  DestType  Imm1   Imm2 */
781
  AddReg("DADDC"   , 0x642, IntOp   , IntOp   , IntOp   , False, False, False);
782
  AddReg("DIVI"    , 0x74b, IntOp   , IntOp   , IntOp   , True , True , False);
783
  AddReg("DIVO"    , 0x70b, IntOp   , IntOp   , IntOp   , True , True , False);
784
  AddReg("DIVR"    , 0x78b, SingleOp, SingleOp, SingleOp, True , True , False);
785
  AddReg("DIVRL"   , 0x79b, DoubleOp, DoubleOp, DoubleOp, True , True , False);
786
  AddReg("DMOVT"   , 0x644, IntOp   , NoneOp  , IntOp   , False, False, False);
787
  AddReg("DSUBC"   , 0x643, IntOp   , IntOp   , IntOp   , False, False, False);
788
  AddReg("EDIV"    , 0x671, IntOp   , LongOp  , LongOp  , True , True , False);
789
  AddReg("EMUL"    , 0x670, IntOp   , IntOp   , LongOp  , True , True , False);
790
  AddReg("EXPR"    , 0x689, SingleOp, NoneOp  , SingleOp, True , False, False);
791
  AddReg("EXPRL"   , 0x699, DoubleOp, NoneOp  , DoubleOp, True , False, False);
792
  AddReg("EXTRACT" , 0x651, IntOp   , IntOp   , IntOp   , True , True , False);
793
  AddReg("LOGBNR"  , 0x68a, SingleOp, NoneOp  , SingleOp, True , False, False);
794
  AddReg("LOGBNRL" , 0x69a, DoubleOp, NoneOp  , DoubleOp, True , False, False);
795
  AddReg("LOGEPR"  , 0x681, SingleOp, SingleOp, SingleOp, True , True , False);
796
  AddReg("LOGEPRL" , 0x691, DoubleOp, DoubleOp, DoubleOp, True , True , False);
797
  AddReg("LOGR"    , 0x682, SingleOp, SingleOp, SingleOp, True , True , False);
798
  AddReg("LOGRL"   , 0x692, DoubleOp, DoubleOp, DoubleOp, True , True , False);
799
  AddReg("MODAC"   , 0x645, IntOp   , IntOp   , IntOp   , True , True , False);
800
  AddReg("MODI"    , 0x749, IntOp   , IntOp   , IntOp   , True , True , False);
801
  AddReg("MODIFY"  , 0x650, IntOp   , IntOp   , IntOp   , True , True , False);
802
  AddReg("MODPC"   , 0x655, IntOp   , IntOp   , IntOp   , True , True , True );
803
  AddReg("MODTC"   , 0x654, IntOp   , IntOp   , IntOp   , True , True , False);
804
  AddReg("MOV"     , 0x5cc, IntOp   , NoneOp  , IntOp   , True , False, False);
805
  AddReg("MOVL"    , 0x5dc, LongOp  , NoneOp  , LongOp  , True , False, False);
806
  AddReg("MOVT"    , 0x5ec, QuadOp  , NoneOp  , QuadOp  , True , False, False);
807
  AddReg("MOVQ"    , 0x5fc, QuadOp  , NoneOp  , QuadOp  , True , False, False);
808
  AddReg("MOVR"    , 0x6c9, SingleOp, NoneOp  , SingleOp, True , False, False);
809
  AddReg("MOVRL"   , 0x6d9, DoubleOp, NoneOp  , DoubleOp, True , False, False);
810
  AddReg("MOVRE"   , 0x6e1, ExtOp   , NoneOp  , ExtOp   , True , False, False);
811
  AddReg("MULI"    , 0x741, IntOp   , IntOp   , IntOp   , True , True , False);
812
  AddReg("MULO"    , 0x701, IntOp   , IntOp   , IntOp   , True , True , False);
813
  AddReg("MULR"    , 0x78c, SingleOp, SingleOp, SingleOp, True , True , False);
814
  AddReg("MULRL"   , 0x79c, DoubleOp, DoubleOp, DoubleOp, True , True , False);
815
  AddReg("NAND"    , 0x58e, IntOp   , IntOp   , IntOp   , True , True , False);
816
  AddReg("NOR"     , 0x588, IntOp   , IntOp   , IntOp   , True , True , False);
817
  AddReg("NOT"     , 0x58a, IntOp   , NoneOp  , IntOp   , True , False, False);
818
  AddReg("NOTAND"  , 0x584, IntOp   , IntOp   , IntOp   , True , True , False);
819
  AddReg("NOTBIT"  , 0x580, IntOp   , IntOp   , IntOp   , True , True , False);
820
  AddReg("NOTOR"   , 0x58d, IntOp   , IntOp   , IntOp   , True , True , False);
821
  AddReg("OR"      , 0x587, IntOp   , IntOp   , IntOp   , True , True , False);
822
  AddReg("ORNOT"   , 0x58b, IntOp   , IntOp   , IntOp   , True , True , False);
823
      /*  Name       OpCode TwoSrc HDest  Float     Imm1   Imm2 */
824
  AddReg("REMI"    , 0x748, IntOp   , IntOp   , IntOp   , True , True , False);
825
  AddReg("REMO"    , 0x708, IntOp   , IntOp   , IntOp   , True , True , False);
826
  AddReg("REMR"    , 0x683, SingleOp, SingleOp, SingleOp, True , True , False);
827
  AddReg("REMRL"   , 0x693, DoubleOp, DoubleOp, DoubleOp, True , True , False);
828
  AddReg("ROTATE"  , 0x59d, IntOp   , IntOp   , IntOp   , True , True , False);
829
  AddReg("ROUNDR"  , 0x68b, SingleOp, NoneOp  , SingleOp, True , False, False);
830
  AddReg("ROUNDRL" , 0x69b, DoubleOp, NoneOp  , DoubleOp, True , False, False);
831
  AddReg("SCALER"  , 0x677, IntOp   , SingleOp, SingleOp, True , True , False);
832
  AddReg("SCALERL" , 0x676, IntOp   , DoubleOp, DoubleOp, True , True , False);
833
  AddReg("SCANBIT" , 0x641, IntOp   , NoneOp  , IntOp   , True , False, False);
834
  AddReg("SCANBYTE", 0x5ac, IntOp   , NoneOp  , IntOp   , True , False, False);
835
  AddReg("SETBIT"  , 0x583, IntOp   , IntOp   , IntOp   , True , True , False);
836
  AddReg("SHLO"    , 0x59c, IntOp   , IntOp   , IntOp   , True , True , False);
837
  AddReg("SHRO"    , 0x598, IntOp   , IntOp   , IntOp   , True , True , False);
838
  AddReg("SHLI"    , 0x59e, IntOp   , IntOp   , IntOp   , True , True , False);
839
  AddReg("SHRI"    , 0x59B, IntOp   , IntOp   , IntOp   , True , True , False);
840
  AddReg("SHRDI"   , 0x59a, IntOp   , IntOp   , IntOp   , True , True , False);
841
  AddReg("SINR"    , 0x68c, SingleOp, NoneOp  , SingleOp, True , False, False);
842
  AddReg("SINRL"   , 0x69c, DoubleOp, NoneOp  , DoubleOp, True , False, False);
843
  AddReg("SPANBIT" , 0x640, IntOp   , NoneOp  , IntOp   , True , False, False);
844
  AddReg("SQRTR"   , 0x688, SingleOp, NoneOp  , SingleOp, True , False, False);
845
  AddReg("SQRTRL"  , 0x698, DoubleOp, NoneOp  , DoubleOp, True , False, False);
846
  AddReg("SUBC"    , 0x5b2, IntOp   , IntOp   , IntOp   , True , True , False);
847
  AddReg("SUBI"    , 0x593, IntOp   , IntOp   , IntOp   , True , True , False);
848
  AddReg("SUBO"    , 0x592, IntOp   , IntOp   , IntOp   , True , True , False);
849
  AddReg("SUBR"    , 0x78d, SingleOp, SingleOp, SingleOp, True , True , False);
850
  AddReg("SUBRL"   , 0x79d, DoubleOp, DoubleOp, DoubleOp, True , True , False);
851
  AddReg("SYNLD"   , 0x615, IntOp   , NoneOp  , IntOp   , False, False, False);
852
  AddReg("SYNMOV"  , 0x600, IntOp   , NoneOp  , IntOp   , False, False, False);
853
  AddReg("SYNMOVL" , 0x601, IntOp   , NoneOp  , IntOp   , False, False, False);
854
  AddReg("SYNMOVQ" , 0x602, IntOp   , NoneOp  , IntOp   , False, False, False);
855
  AddReg("TANR"    , 0x68e, SingleOp, NoneOp  , SingleOp, True , False, False);
856
  AddReg("TANRL"   , 0x69e, DoubleOp, NoneOp  , DoubleOp, True , False, False);
857
  AddReg("XOR"     , 0x589, IntOp   , IntOp   , IntOp   , True , True , False);
858
  AddReg("XNOR"    , 0x589, IntOp   , IntOp   , IntOp   , True , True , False);
859
 
860
  InstrZ = 0;
861
  AddCobr("BBC"    , 0x30, True ); AddCobr("BBS"    , 0x37, True );
862
  AddCobr("CMPIBE" , 0x3a, True ); AddCobr("CMPOBE" , 0x32, True );
863
  AddCobr("CMPIBNE", 0x3d, True ); AddCobr("CMPOBNE", 0x35, True );
864
  AddCobr("CMPIBL" , 0x3c, True ); AddCobr("CMPOBL" , 0x34, True );
865
  AddCobr("CMPIBLE", 0x3e, True ); AddCobr("CMPOBLE", 0x36, True );
866
  AddCobr("CMPIBG" , 0x39, True ); AddCobr("CMPOBG" , 0x31, True );
867
  AddCobr("CMPIBGE", 0x3b, True ); AddCobr("CMPOBGE", 0x33, True );
868
  AddCobr("CMPIBO" , 0x3f, True ); AddCobr("CMPIBNO", 0x38, True );
869
  AddCobr("TESTE"  , 0x22, False); AddCobr("TESTNE" , 0x25, False);
870
  AddCobr("TESTL"  , 0x24, False); AddCobr("TESTLE" , 0x26, False);
871
  AddCobr("TESTG"  , 0x21, False); AddCobr("TESTGE" , 0x23, False);
872
  AddCobr("TESTO"  , 0x27, False); AddCobr("TESTNO" , 0x27, False);
873
 
874
  InstrZ = 0;
875
  AddCtrl("B"   , 0x08); AddCtrl("CALL", 0x09);
876
  AddCtrl("BAL" , 0x0b); AddCtrl("BNO" , 0x19);
877
  AddCtrl("BG"  , 0x11); AddCtrl("BE"  , 0x12);
878
  AddCtrl("BGE" , 0x13); AddCtrl("BL"  , 0x14);
879
  AddCtrl("BNE" , 0x15); AddCtrl("BLE" , 0x16);
880
  AddCtrl("BO"  , 0x17);
881
 
882
  InstrZ = 0;
883
  AddMem("LDOB" , 0x80, IntOp   , 2);
884
  AddMem("STOB" , 0x82, IntOp   , 1);
885
  AddMem("BX"   , 0x84, IntOp   , 0);
886
  AddMem("BALX" , 0x85, IntOp   , 2);
887
  AddMem("CALLX", 0x86, IntOp   , 0);
888
  AddMem("LDOS" , 0x88, IntOp   , 2);
889
  AddMem("STOS" , 0x8a, IntOp   , 1);
890
  AddMem("LDA"  , 0x8c, IntOp   , 2);
891
  AddMem("LD"   , 0x90, IntOp   , 2);
892
  AddMem("ST"   , 0x92, IntOp   , 1);
893
  AddMem("LDL"  , 0x98, LongOp  , 2);
894
  AddMem("STL"  , 0x9a, LongOp  , 1);
895
  AddMem("LDT"  , 0xa0, QuadOp  , 2);
896
  AddMem("STT"  , 0xa2, QuadOp  , 1);
897
  AddMem("LDQ"  , 0xb0, QuadOp  , 2);
898
  AddMem("STQ"  , 0xb2, QuadOp  , 1);
899
  AddMem("LDIB" , 0xc0, IntOp   , 2);
900
  AddMem("STIB" , 0xc2, IntOp   , 1);
901
  AddMem("LDIS" , 0xc8, IntOp   , 2);
902
  AddMem("STIS" , 0xca, IntOp   , 1);
903
 
904
  AddInstTable(InstTable, "WORD", 0, DecodeWORD);
905
  AddInstTable(InstTable, "SPACE", 0, DecodeSPACE);
906
  AddInstTable(InstTable, "REG", 0, CodeREG);
907
 
908
  inst_table_set_prefix_proc(InstTable, NULL, 0);
909
  AddIntelPseudo(InstTable, eIntPseudoFlag_LittleEndian);
910
}
911
 
912
static void DeinitFields(void)
913
{
914
  DestroyInstTable(InstTable);
915
  order_array_free(FixedOrders);
916
  order_array_free(RegOrders);
917
  order_array_free(CobrOrders);
918
  order_array_free(CtrlOrders);
919
}
920
 
921
/*--------------------------------------------------------------------------*/
922
 
923
static Boolean IsDef_960(void)
924
{
925
  return Memo("REG");
926
}
927
 
928
/*!------------------------------------------------------------------------
929
 * \fn     InternSymbol_960(char *pArg, TempResult *pResult)
930
 * \brief  handle built-in symbols on i960
931
 * \param  pArg source argument
932
 * \param  pResult result buffer
933
 * ------------------------------------------------------------------------ */
934
 
935
static void InternSymbol_960(char *pArg, TempResult *pResult)
936
{
937
  LongWord Reg;
938
 
939
  if (DecodeIRegCore(pArg, &Reg))
940
  {
941
    pResult->Typ = TempReg;
942
    pResult->DataSize = eSymbolSize32Bit;
943
    pResult->Contents.RegDescr.Reg = Reg;
944
    pResult->Contents.RegDescr.Dissect = DissectReg_960;
945
    pResult->Contents.RegDescr.compare = NULL;
946
  }
947
  else if (DecodeFPRegCore(pArg, &Reg))
948
  {
949
    pResult->Typ = TempReg;
950
    pResult->DataSize = eSymbolSizeFloat64Bit;
951
    pResult->Contents.RegDescr.Reg = Reg;
952
    pResult->Contents.RegDescr.Dissect = DissectReg_960;
953
    pResult->Contents.RegDescr.compare = NULL;
954
  }
955
}
956
 
957
static void SwitchTo_960(void)
958
{
959
  const TFamilyDescr *FoundId;
960
 
961
  TurnWords = False;
962
  SetIntConstMode(eIntConstModeIntel);
963
 
964
  FoundId = FindFamilyByName("i960");
965
  if (!FoundId)
966
    exit(255);
967
  PCSymbol = "$";
968
  HeaderID = FoundId->Id;
969
  NOPCode = 0x000000000;
970
  DivideChars = ",";
971
  HasAttrs = False;
972
 
973
  ValidSegs=(1 << SegCode);
974
  Grans[SegCode] = 1;
975
  ListGrans[SegCode] = 4;
976
  SegInits[SegCode] = 0;
977
  SegLimits[SegCode] = (LargeWord)IntTypeDefs[UInt32].Max;
978
 
979
  MakeCode = MakeCode_960;
980
  IsDef = IsDef_960;
981
  InternSymbol = InternSymbol_960;
982
  DissectReg = DissectReg_960;
983
  SwitchFrom = DeinitFields;
984
  onoff_fpu_add();
985
  onoff_supmode_add();
986
 
987
  InitFields();
988
}
989
 
990
void code960_init(void)
991
{
992
  CPU80960 = AddCPU("80960", SwitchTo_960);
993
}