Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

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