/* codens32k.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* Code Generator National Semiconductor NS32000 */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include "bpemu.h"
#include "strutil.h"
#include "ieeefloat.h"
#include "headids.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmallg.h"
#include "onoff_common.h"
#include "asmitree.h"
#include "codevars.h"
#include "codepseudo.h"
#include "intpseudo.h"
#include "codepseudo.h"
#include "intpseudo.h"
#include "codens32k.h"
typedef enum
{
eCoreNone,
eCoreGen1,
eCoreGen1Ext,
eCoreGenE,
eCoreGen2,
eCoreCount
} tCore;
typedef enum
{
eFPUNone,
eFPU16081,
eFPU32081,
eFPU32181,
eFPU32381,
eFPU32580,
eFPUCount
} tFPU;
typedef enum
{
ePMMUNone,
ePMMU16082,
ePMMU32082,
ePMMU32382,
ePMMU32532,
ePMMUCount
} tPMMU;
typedef struct
{
const char *pName;
Byte CPUType, DefFPU, DefPMMU;
IntType MemIntType;
} tCPUProps;
static char FPUNames[eFPUCount][8] = { "OFF", "NS16081", "NS32081", "NS32181", "NS32381", "NS32580" };
static char PMMUNames[ePMMUCount][8] = { "OFF", "NS16082", "NS32082", "NS32382", "NS32532" };
typedef struct
{
const char *pName;
Word Code, Mask;
Boolean Privileged;
} tCtlReg;
#ifdef __cplusplus
#include "codens32k.hpp"
#endif
#define MAllowImm (1 << 0)
#define MAllowReg (1 << 1)
#define MAllowRegPair (1 << 2)
static tCtlReg *CtlRegs, *MMURegs;
static tSymbolSize OpSize;
static const tCPUProps *pCurrCPUProps;
static tFPU MomFPU;
static tPMMU MomPMMU;
static Boolean CustomAvail;
/*!------------------------------------------------------------------------
* \fn SetOpSize(tSymbolSize Size, const tStrComp *pArg)
* \brief set (new) operand size of instruction
* \param Size size to set
* \param pArg source argument size was deduced from
* \return True if no conflict
* ------------------------------------------------------------------------ */
static Boolean SetOpSize(tSymbolSize Size, const tStrComp *pArg)
{
if (OpSize == eSymbolSizeUnknown)
OpSize = Size;
else if ((Size != eSymbolSizeUnknown) && (Size != OpSize))
{
WrStrErrorPos(ErrNum_ConfOpSizes, pArg);
return False;
}
return True;
}
/*!------------------------------------------------------------------------
* \fn ResetOpSize(void)
* \brief back to undefined op size
* \return constat True
* ------------------------------------------------------------------------ */
static Boolean ResetOpSize(void)
{
OpSize = eSymbolSizeUnknown;
return True;
}
/*!------------------------------------------------------------------------
* \fn CheckCore(unsigned CoreMask)
* \brief check for CPU/Core requirement
* \param CoreMask bit mask of core type supported
* \return True if fulfilled
* ------------------------------------------------------------------------ */
static Boolean CheckCore(unsigned CoreMask)
{
if ((CoreMask >> pCurrCPUProps->CPUType) & 1)
return True;
WrStrErrorPos(ErrNum_InstructionNotSupported, &OpPart);
return False;
}
/*!------------------------------------------------------------------------
* \fn CheckSup(Boolean Required, const tStrComp *pArg)
* \brief check whether supervisor mode requirement is violated
* \param Required is supervisor mode required?
* \param pArg source argument
* \return False if violated
* ------------------------------------------------------------------------ */
static Boolean CheckSup(Boolean Required, const tStrComp *pArg)
{
if (!SupAllowed && Required)
{
WrStrErrorPos(ErrNum_PrivOrder, pArg);
return False;
}
return True;
}
/*!------------------------------------------------------------------------
* \fn SetMomFPU(tFPU NewFPU)
* \brief set new FPU type in use
* \param NewFPU new type
* ------------------------------------------------------------------------ */
static void SetMomFPU(tFPU NewFPU)
{
switch ((MomFPU = NewFPU))
{
case eFPU16081:
case eFPU32081:
case eFPU32181:
case eFPU32381:
case eFPU32580:
{
tStrComp TmpComp;
String TmpCompStr;
StrCompMkTemp(&TmpComp, TmpCompStr, sizeof(TmpCompStr));
strmaxcpy(TmpCompStr, MomFPUIdentName, sizeof(TmpCompStr));
strmaxcpy(MomFPUIdent, FPUNames[MomFPU], sizeof(MomFPUIdent));
EnterStringSymbol(&TmpComp, FPUNames[MomFPU], True);
break;
}
default:
break;
}
}
/*!------------------------------------------------------------------------
* \fn SetMomPMMU(tFPU NewPMMU)
* \brief set new PMMU type in use
* \param NewPMMU new type
* ------------------------------------------------------------------------ */
static void SetMomPMMU(tPMMU NewPMMU)
{
switch ((MomPMMU = NewPMMU))
{
case ePMMU16082:
case ePMMU32082:
case ePMMU32382:
case ePMMU32532:
{
tStrComp TmpComp;
String TmpCompStr;
StrCompMkTemp(&TmpComp, TmpCompStr, sizeof(TmpCompStr));
strmaxcpy(TmpCompStr, MomPMMUIdentName, sizeof(TmpCompStr));
strmaxcpy(MomPMMUIdent, PMMUNames[MomPMMU], sizeof(MomPMMUIdent));
EnterStringSymbol(&TmpComp, PMMUNames[MomPMMU], True);
break;
}
default:
break;
}
}
/*!------------------------------------------------------------------------
* \fn CheckFPUAvail(void)
* \brief check whether FPU instructions are enabled
* \return False if not
* ------------------------------------------------------------------------ */
static Boolean CheckFPUAvail(tFPU MinFPU)
{
if (!FPUAvail)
{
WrStrErrorPos(ErrNum_FPUNotEnabled, &OpPart);
return False;
}
else if (MomFPU < MinFPU)
{
WrStrErrorPos(ErrNum_FPUInstructionNotSupported, &OpPart);
return False;
}
return True;
}
/*!------------------------------------------------------------------------
* \fn CheckPMMUAvail(void)
* \brief check whether PMMU instructions are enabled
* \return False if not
* ------------------------------------------------------------------------ */
static Boolean CheckPMMUAvail(void)
{
if (!PMMUAvail)
{
WrStrErrorPos(ErrNum_PMMUNotEnabled, &OpPart);
return False;
}
return True;
}
/*!------------------------------------------------------------------------
* \fn CheckCustomAvail(void)
* \brief check whether Custom instructions are enabled
* \return False if not
* ------------------------------------------------------------------------ */
static Boolean CheckCustomAvail(void)
{
if (!CustomAvail)
{
WrStrErrorPos(ErrNum_CustomNotEnabled, &OpPart);
return False;
}
return True;
}
/*--------------------------------------------------------------------------*/
/* Register Handling */
static const char MemRegNames[][3] = { "FP", "SP", "SB" };
#define MemRegCount (sizeof(MemRegNames) / sizeof(*MemRegNames))
/*!------------------------------------------------------------------------
* \fn DecodeRegCore(const char *pArg, Word *pValue, tSymbolSize *pSize)
* \brief check whether argument describes a register
* \param pArg source argument
* \param pValue register number if yes
* \param pSize register size if yes
* \return True if it is
* ------------------------------------------------------------------------ */
static Boolean DecodeRegCore(const char *pArg, Word *pRegNum, tSymbolSize *pRegSize)
{
unsigned z;
for (z = 0; z < MemRegCount; z++)
if (!as_strcasecmp(pArg, MemRegNames[z]))
{
*pRegNum = z + 8;
*pRegSize = eSymbolSize32Bit;
return True;
}
if ((strlen(pArg
) != 2) || (pArg
[1] < '0') || (pArg
[1] > '7'))
return False;
*pRegNum = pArg[1] - '0';
switch (as_toupper(*pArg))
{
case 'F': *pRegSize = eSymbolSizeFloat32Bit; return True;
case 'R': *pRegSize = eSymbolSize32Bit; return True;
case 'L': *pRegSize = eSymbolSizeFloat64Bit; return True;
default:
return False;
}
}
/*!------------------------------------------------------------------------
* \fn DissectReg_NS32K(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
* \brief dissect register symbols - NS32000 variant
* \param pDest destination buffer
* \param DestSize destination buffer size
* \param Value numeric register value
* \param InpSize register size
* ------------------------------------------------------------------------ */
static void DissectReg_NS32K(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
{
switch (InpSize)
{
case eSymbolSize32Bit:
if (Value < 8)
as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
else if (Value < 8 + MemRegCount)
as_snprintf(pDest, DestSize, "%s", MemRegNames[Value - 8]);
else
goto unknown;
break;
case eSymbolSizeFloat32Bit:
as_snprintf(pDest, DestSize, "F%u", (unsigned)Value);
break;
case eSymbolSizeFloat64Bit:
as_snprintf(pDest, DestSize, "L%u", (unsigned)Value);
break;
default:
unknown:
as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeReg(const tStrComp *pArg, Word *pValue, tSymbolSize *pSize, tSymbolSize ChkRegSize, Boolean MustBeReg)
* \brief check whether argument is a CPU register or user-defined register alias
* \param pArg argument
* \param pValue resulting register # if yes
* \param pSize resulting register size if yes
* \param ChkReqSize explicitly request certain register size
* \param MustBeReg expecting register or maybe not?
* \return reg eval result
* ------------------------------------------------------------------------ */
static Boolean MatchRegSize(tSymbolSize IsSize, tSymbolSize ReqSize)
{
return (ReqSize == eSymbolSizeUnknown)
|| (IsSize == ReqSize)
|| ((ReqSize == eSymbolSizeFloat64Bit) && (IsSize == eSymbolSizeFloat32Bit));
}
static tRegEvalResult DecodeReg(const tStrComp *pArg, Word *pValue, tSymbolSize *pSize, tSymbolSize ChkRegSize, Boolean MustBeReg)
{
tEvalResult EvalResult;
tRegEvalResult RegEvalResult;
if (DecodeRegCore(pArg->str.p_str, pValue, &EvalResult.DataSize))
RegEvalResult = eIsReg;
else
{
tRegDescr RegDescr;
RegEvalResult = EvalStrRegExpressionAsOperand(pArg, &RegDescr, &EvalResult, eSymbolSizeUnknown, MustBeReg);
if (eIsReg == RegEvalResult)
*pValue = RegDescr.Reg;
}
if ((RegEvalResult == eIsReg) && !MatchRegSize(EvalResult.DataSize, ChkRegSize))
{
WrStrErrorPos(ErrNum_InvOpSize, pArg);
RegEvalResult = MustBeReg ? eIsNoReg : eRegAbort;
}
if (pSize) *pSize = EvalResult.DataSize;
return RegEvalResult;
}
/*!------------------------------------------------------------------------
* \fn DecodeCtlReg(const tStrComp *pArg, Word *pResult)
* \brief decode control processor register
* \param pArg source argument
* \param pResult result buffer
* \return True if src expr is a register
* ------------------------------------------------------------------------ */
static Boolean DecodeCtlReg(const tStrComp *pArg, Word *pResult)
{
unsigned z;
for (z = 0; CtlRegs[z].pName; z++)
if (!as_strcasecmp(pArg->str.p_str, CtlRegs[z].pName))
{
*pResult = CtlRegs[z].Code;
return CheckSup(CtlRegs[z].Privileged, pArg);
}
WrStrErrorPos(ErrNum_InvReg, pArg);
return False;
}
/*!------------------------------------------------------------------------
* \fn DecodeMMUReg(const tStrComp *pArg, Word *pResult)
* \brief decode MMU register
* \param pArg source argument
* \param pResult result buffer
* \return True if src expr is a register
* ------------------------------------------------------------------------ */
static Boolean DecodeMMUReg(const tStrComp *pArg, Word *pResult)
{
unsigned z;
for (z = 0; MMURegs[z].pName; z++)
if (!as_strcasecmp(pArg->str.p_str, MMURegs[z].pName))
{
if (!((MMURegs[z].Mask >> MomPMMU) & 1))
{
WrStrErrorPos(ErrNum_InvPMMUReg, pArg);
return False;
}
*pResult = MMURegs[z].Code;
return CheckSup(MMURegs[z].Privileged, pArg);
}
WrStrErrorPos(ErrNum_InvPMMUReg, pArg);
return False;
}
/*!------------------------------------------------------------------------
* \fn DecodeRegList(const tStrComp *pArg, Boolean BitRev, Byte *pResult)
* \brief Decode Register List
* \param pArg Source Argument
* \param BitRev Reverse Bit Order, i.e. R0->Bit 7 ?
* \param pResult Result Buffer
* \return True if successfully parsed
* ------------------------------------------------------------------------ */
static Boolean DecodeRegList(const tStrComp *pArg, Boolean BitRev, Byte *pResult)
{
tStrComp Part, Remainder;
int l
= strlen(pArg
->str.
p_str);
Word Reg;
char *pSep;
if ((l < 2)
|| (pArg->str.p_str[0] != '[')
|| (pArg->str.p_str[l - 1] != ']'))
{
WrStrErrorPos(ErrNum_InvRegList, pArg);
return False;
}
*pResult = 0;
StrCompRefRight(&Part, pArg, 1);
StrCompShorten(&Part, 1);
while (True)
{
KillPrefBlanksStrCompRef(&Part);
pSep
= strchr(Part.
str.
p_str, ',');
if (pSep)
StrCompSplitRef(&Part, &Remainder, &Part, pSep);
KillPostBlanksStrComp(&Part);
if (DecodeReg(&Part, &Reg, NULL, eSymbolSize32Bit, True) != eIsReg)
return False;
if (Reg >= 8)
{
WrStrErrorPos(ErrNum_InvReg, &Part);
return False;
}
*pResult |= 1 << (BitRev ? 7 - Reg : Reg);
if (pSep)
Part = Remainder;
else
break;
}
return True;
}
/*!------------------------------------------------------------------------
* \fn DecodeCfgList(const tStrComp *pArg, Byte *pResult)
* \brief Decode Config Option List
* \param pArg Source Argument
* \param pResult Result Buffer
* \return True if successfully parsed
* ------------------------------------------------------------------------ */
static Boolean DecodeCfgList(const tStrComp *pArg, Byte *pResult)
{
tStrComp Part, Remainder;
int l
= strlen(pArg
->str.
p_str);
char *pSep;
const char Opts[] = "IFMC", *pOpt;
if ((l < 2)
|| (pArg->str.p_str[0] != '[')
|| (pArg->str.p_str[l - 1] != ']'))
{
WrStrErrorPos(ErrNum_InvCfgList, pArg);
return False;
}
*pResult = 0;
StrCompRefRight(&Part, pArg, 1);
StrCompShorten(&Part, 1);
while (True)
{
KillPrefBlanksStrCompRef(&Part);
pSep
= strchr(Part.
str.
p_str, ',');
if (pSep)
StrCompSplitRef(&Part, &Remainder, &Part, pSep);
KillPostBlanksStrComp(&Part);
switch (strlen(Part.
str.
p_str))
{
case 0:
break;
case 1:
pOpt
= strchr(Opts
, as_toupper
(*Part.
str.
p_str));
if (pOpt)
{
*pResult |= 1 << (pOpt - Opts);
break;
}
/* else fall-through */
default:
WrStrErrorPos(ErrNum_InvCfgList, &Part);
return False;
}
if (pSep)
Part = Remainder;
else
break;
}
return True;
}
/*--------------------------------------------------------------------------*/
/* Address Decoder */
enum
{
AddrCode_Reg = 0x00,
AddrCode_Relative = 0x08,
AddrCode_MemRelative = 0x10,
AddrCode_Reserved = 0x13,
AddrCode_Immediate = 0x14,
AddrCode_Absolute = 0x15,
AddrCode_External = 0x16,
AddrCode_TOS = 0x17,
AddrCode_MemSpace = 0x18,
AddrCode_ScaledIndex = 0x1c
};
typedef struct
{
Byte Code;
Byte Index[1], Disp[8];
unsigned IndexCnt, DispCnt;
} tAdrVals;
static void ClearAdrVals(tAdrVals *pVals)
{
pVals->Code = AddrCode_Reserved;
pVals->IndexCnt = pVals->DispCnt = 0;
}
/*!------------------------------------------------------------------------
* \fn EncodeDisplacement(LongInt Disp, tAdrVals *pDest, tErrorNum ErrorNum, const tStrComp *pArg)
* \brief encode signed displacement
* \param Disp displacement to encode
* \param pDest destination buffer
* \param ErrorNum error msg to print if out of range
* \param pArg source argument for error messages
* \return True if successfully encoded
* ------------------------------------------------------------------------ */
static Boolean EncodeDisplacement(LongInt Disp, tAdrVals *pDest, tErrorNum ErrorNum, const tStrComp *pArg)
{
if ((Disp >= -64) && (Disp <= 63))
{
pDest->Disp[pDest->DispCnt++] = Disp & 0x7f;
return True;
}
else if ((Disp >= -8192) && (Disp <= 8191))
{
pDest->Disp[pDest->DispCnt++] = 0x80 | ((Disp >> 8) & 0x3f);
pDest->Disp[pDest->DispCnt++] = Disp & 0xff;
return True;
}
else if ((Disp >= -520093696) && (Disp <= 536870911))
{
Byte HiByte = 0xc0 | ((Disp >> 24) & 0x3f);
if (HiByte == 0xe0)
goto error;
pDest->Disp[pDest->DispCnt++] = HiByte;
pDest->Disp[pDest->DispCnt++] = (Disp >> 16) & 0xff;
pDest->Disp[pDest->DispCnt++] = (Disp >> 8) & 0xff;
pDest->Disp[pDest->DispCnt++] = Disp & 0xff;
return True;
}
else
{
error:
WrStrErrorPos(ErrorNum, pArg);
return False;
}
}
/*!------------------------------------------------------------------------
* \fn EncodePCRel(const tStrComp *pArg, tAdrVals *pDest)
* \brief PC-relative encoding of address
* \param pArg address in source
* \param pDest dest buffer
* \return True if success
* ------------------------------------------------------------------------ */
static Boolean EncodePCRel(const tStrComp *pArg, tAdrVals *pDest)
{
tEvalResult EvalResult;
LongInt Dist = EvalStrIntExpressionWithResult(pArg, pCurrCPUProps->MemIntType, &EvalResult) - EProgCounter();
ClearAdrVals(pDest);
if (!EvalResult.OK
|| !EncodeDisplacement(Dist, pDest, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_JmpDistTooBig, pArg))
return False;
pDest->Code = AddrCode_MemSpace + 3;
return True;
}
/*!------------------------------------------------------------------------
* \fn DecodeAdr(tStrComp *pArg, tAdrVals *pDest, unsigned AddrModeMask)
* \brief decode address expression
* \param pArg source argument
* \param pDest dest buffer
* \param AddrModeMask allow immediate/register addressing?
* \return True if success
* ------------------------------------------------------------------------ */
static Boolean DecodeAdr(const tStrComp *pArg, tAdrVals *pDest, Boolean AddrModeMask)
{
Byte IndexCode = 0;
Boolean OK, NeedEvenReg;
const Boolean IsFloat = (OpSize == eSymbolSizeFloat32Bit) || (OpSize == eSymbolSizeFloat64Bit);
Word RegValue, IndexReg = 0;
int ArgLen, SplitPos;
tStrComp BaseArg;
const char IndexChars[] = "BWDQ";
char *pSplit, *pSplit2, Scale;
ClearAdrVals(pDest);
/* split off scaled indexing, which is orthogonal to (almost) all other modes */
pSplit = MatchCharsRev(pArg->str.p_str, " : ? ] ", IndexChars, &Scale);
pSplit2 = (pSplit && (pSplit > pArg->str.p_str))
? FindOpeningParenthese(pArg->str.p_str, pSplit - 1, "[]")
: NULL;
if (pSplit && pSplit2)
{
tStrComp Mid, Right;
const char *pScaleIndex;
StrCompSplitRef(&BaseArg, &Right, pArg, pSplit);
StrCompSplitRef(&BaseArg, &Mid, &BaseArg, pSplit2);
KillPrefBlanksStrCompRef(&Mid);
KillPostBlanksStrComp(&BaseArg);
pArg = &BaseArg;
pScaleIndex
= strchr(IndexChars
, as_toupper
(Scale
));
if (!pScaleIndex)
{
WrStrErrorPos(ErrNum_InvScale, &Right);
return False;
}
IndexCode = AddrCode_ScaledIndex + (pScaleIndex - IndexChars);
if ((DecodeReg(&Mid, &IndexReg, NULL, eSymbolSize32Bit, True) == eIsReg)
&& (IndexReg >= 8))
{
WrStrErrorPos(ErrNum_InvReg, &Mid);
return False;
}
/* Immediate cannot be combined with scaling, so disallow regardless of caller's
preference: */
AddrModeMask &= ~MAllowImm;
}
/* absolute: */
if (*pArg->str.p_str == '@')
{
tStrComp Arg;
LongWord Addr;
StrCompRefRight(&Arg, pArg, 1);
Addr = EvalStrIntExpression(&Arg, pCurrCPUProps->MemIntType, &OK);
if (!OK)
return False;
/* On a CPU with non-32-bit address bus, addresses @ the upper end may be encoded
as negative 'displacements': */
if ((pCurrCPUProps->MemIntType == UInt24)
&& (Addr & 0x800000ul))
Addr |= 0xff000000ul;
if (EncodeDisplacement((LongInt)Addr, pDest, ErrNum_OverRange, &Arg))
{
pDest->Code = AddrCode_Absolute;
goto chk;
}
else
return False;
}
/* TOS? */
if (!as_strcasecmp(pArg->str.p_str, "TOS"))
{
pDest->Code = AddrCode_TOS;
goto chk;
}
/* register? */
if (IsFloat)
NeedEvenReg = (OpSize == eSymbolSizeFloat64Bit) && (MomFPU < eFPU32181);
else
NeedEvenReg = !!(AddrModeMask & MAllowRegPair);
switch (DecodeReg(pArg, &RegValue, NULL, IsFloat ? OpSize : eSymbolSize32Bit, False))
{
case eIsReg:
if (NeedEvenReg && (RegValue & 1))
{
WrStrErrorPos(ErrNum_InvRegPair, pArg);
return False;
}
else if (!(AddrModeMask & (MAllowReg | MAllowRegPair)))
{
WrStrErrorPos(ErrNum_InvAddrMode, pArg);
return False;
}
else
{
pDest->Code = AddrCode_Reg + RegValue;
goto chk;
}
case eIsNoReg:
break;
default:
return False;
}
/* EXT mode */
pSplit = MatchChars(pArg->str.p_str, " EXT (");
if (pSplit)
{
tStrComp Left, Mid, Right;
LongInt Disp1, Disp2 = 0;
Boolean OK;
StrCompSplitRef(&Left, &Mid, pArg, pSplit - 1);
pSplit = FindClosingParenthese(Mid.str.p_str);
if (!pSplit)
{
WrStrErrorPos(ErrNum_BrackErr, pArg);
return False;
}
StrCompSplitRef(&Mid, &Right, &Mid, pSplit);
Disp1 = EvalStrIntExpression(&Mid, Int30, &OK);
if (!OK)
return False;
*(--Right.str.p_str) = '0'; Right.Pos.Len++; Right.Pos.StartCol--;
if (*Right.str.p_str)
Disp2 = EvalStrIntExpression(&Right, Int30, &OK);
if (!OK)
return False;
pDest->Code = AddrCode_External;
if (!EncodeDisplacement(Disp1, pDest, ErrNum_OverRange, &Mid)
|| !EncodeDisplacement(Disp2, pDest, ErrNum_OverRange, &Right))
return False;
goto chk;
}
/* PC-relative */
if (!strcmp(pArg
->str.
p_str, "*")
|| MatchChars(pArg->str.p_str, "* ?", "+-", NULL))
{
LongInt Disp;
Boolean OK;
*pArg->str.p_str = '0';
Disp = EvalStrIntExpression(pArg, Int30, &OK);
*pArg->str.p_str = '*';
if (!OK
|| !EncodeDisplacement(Disp, pDest, ErrNum_OverRange, pArg))
return False;
pDest->Code = AddrCode_MemSpace + 3;
goto chk;
}
/* disp(...)? */
SplitPos = FindDispBaseSplit(pArg->str.p_str, &ArgLen);
if (SplitPos >= 0)
{
tStrComp OutDisp, InnerArg;
LongInt OutDispVal;
tEvalResult OutEvalResult;
memset(&OutEvalResult
, 0, sizeof(OutEvalResult
));
StrCompSplitRef(&OutDisp, &InnerArg, pArg, &pArg->str.p_str[SplitPos]);
if (OutDisp.Pos.Len)
{
OutDispVal = EvalStrIntExpressionWithResult(&OutDisp, Int30, &OutEvalResult);
if (!OutEvalResult.OK)
return False;
}
else
{
OutEvalResult.OK = True;
OutDispVal = 0;
}
StrCompShorten(&InnerArg, 1);
KillPrefBlanksStrCompRef(&InnerArg);
KillPostBlanksStrComp(&InnerArg);
switch (DecodeReg(&InnerArg, &RegValue, NULL, eSymbolSize32Bit, False))
{
case eIsReg: /* disp(Rn/FP/SP/SB) */
pDest->Code = (RegValue < 8) ? AddrCode_Relative + RegValue : AddrCode_MemSpace + (RegValue - 8);
if (!EncodeDisplacement(OutDispVal, pDest, ErrNum_OverRange, &OutDisp))
return False;
goto chk;
IsPCRel:
if (EncodeDisplacement(OutDispVal - EProgCounter(), pDest, mFirstPassUnknownOrQuestionable(OutEvalResult.Flags) ? ErrNum_None : ErrNum_JmpDistTooBig, &OutDisp))
pDest->Code = AddrCode_MemSpace + 3;
goto chk;
case eIsNoReg:
{
tStrComp InDisp;
LongInt InDispVal = 0;
if (!as_strcasecmp(InnerArg.str.p_str, "PC"))
goto IsPCRel;
SplitPos = FindDispBaseSplit(InnerArg.str.p_str, &ArgLen);
if (SplitPos < 0)
{
WrStrErrorPos(ErrNum_InvAddrMode, &InnerArg);
return False;
}
StrCompSplitRef(&InDisp, &InnerArg, &InnerArg, &InnerArg.str.p_str[SplitPos]);
if (InDisp.Pos.Len)
{
InDispVal = EvalStrIntExpression(&InDisp, Int30, &OK);
if (!OK)
return False;
}
StrCompShorten(&InnerArg, 1);
KillPrefBlanksStrCompRef(&InnerArg);
KillPostBlanksStrComp(&InnerArg);
/* disp2(disp1(ext)) is an alias for EXT(disp1)+disp2 */
if (!as_strcasecmp(InnerArg.str.p_str, "EXT"))
{
pDest->Code = AddrCode_External;
}
/* disp2(disp1(FP/SP/SB)) */
else
{
if (DecodeReg(&InnerArg, &RegValue, NULL, eSymbolSize32Bit, True) != eIsReg)
return False;
if (RegValue < 8)
{
WrStrErrorPos(ErrNum_InvReg, &InnerArg);
return False;
}
pDest->Code = AddrCode_MemRelative + (RegValue - 8);
}
if (!EncodeDisplacement(InDispVal, pDest, ErrNum_OverRange, &InDisp)
|| !EncodeDisplacement(OutDispVal, pDest, ErrNum_OverRange, &OutDisp))
return False;
goto chk;
}
default:
return False;
}
}
/* -> immediate or PC-relative */
if (AddrModeMask & MAllowImm)
{
switch (OpSize)
{
case eSymbolSize8Bit:
pDest->Disp[0] = EvalStrIntExpression(pArg, Int8, &OK);
if (OK)
pDest->DispCnt = 1;
break;
case eSymbolSize16Bit:
{
Word Val = EvalStrIntExpression(pArg, Int16, &OK);
if (OK)
{
pDest->Disp[pDest->DispCnt++] = Hi(Val);
pDest->Disp[pDest->DispCnt++] = Lo(Val);
}
break;
}
case eSymbolSize32Bit:
{
LongWord Val = EvalStrIntExpression(pArg, Int32, &OK);
if (OK)
{
pDest->Disp[pDest->DispCnt++] = (Val >> 24) & 0xff;
pDest->Disp[pDest->DispCnt++] = (Val >> 16) & 0xff;
pDest->Disp[pDest->DispCnt++] = (Val >> 8) & 0xff;
pDest->Disp[pDest->DispCnt++] = (Val >> 0) & 0xff;
}
break;
}
case eSymbolSize64Bit:
{
LargeWord Val = EvalStrIntExpression(pArg, LargeIntType, &OK);
if (OK)
{
#ifdef HAS64
pDest->Disp[pDest->DispCnt++] = (Val >> 56) & 0xff;
pDest->Disp[pDest->DispCnt++] = (Val >> 48) & 0xff;
pDest->Disp[pDest->DispCnt++] = (Val >> 40) & 0xff;
pDest->Disp[pDest->DispCnt++] = (Val >> 32) & 0xff;
#else
pDest->Disp[pDest->DispCnt + 0] =
pDest->Disp[pDest->DispCnt + 1] =
pDest->Disp[pDest->DispCnt + 2] =
pDest->Disp[pDest->DispCnt + 3] = (Val & 0x80000000ul) ? 0xff : 0x00;
pDest->DispCnt += 4;
#endif
pDest->Disp[pDest->DispCnt++] = (Val >> 24) & 0xff;
pDest->Disp[pDest->DispCnt++] = (Val >> 16) & 0xff;
pDest->Disp[pDest->DispCnt++] = (Val >> 8) & 0xff;
pDest->Disp[pDest->DispCnt++] = (Val >> 0) & 0xff;
}
break;
}
case eSymbolSizeFloat32Bit:
{
Double Val = EvalStrFloatExpression(pArg, Float32, &OK);
if (OK)
{
Double_2_ieee4(Val, pDest->Disp, True);
pDest->DispCnt = 4;
}
break;
}
case eSymbolSizeFloat64Bit:
{
Double Val = EvalStrFloatExpression(pArg, Float64, &OK);
if (OK)
{
Double_2_ieee8(Val, pDest->Disp, True);
pDest->DispCnt = 8;
}
break;
}
default:
WrStrErrorPos(ErrNum_UndefOpSizes, pArg);
}
if (pDest->DispCnt)
pDest->Code = AddrCode_Immediate;
else
return False;
}
else if (!EncodePCRel(pArg, pDest))
return False;
chk:
/* if we have an index code, check it's not immedate, otherwise relocate */
if (IndexCode)
{
if (pDest->Code == AddrCode_Immediate)
{
WrStrErrorPos(ErrNum_InvAddrMode, pArg);
return False;
}
pDest->Index[pDest->IndexCnt++] = (pDest->Code << 3) | IndexReg;
pDest->Code = IndexCode;
}
return True;
}
/*!------------------------------------------------------------------------
* \fn AppendIndex(const tAdrVals *pVals)
* \brief append optional index byte to code
* \param pVals encoded addressing mode
* ------------------------------------------------------------------------ */
static void AppendIndex(const tAdrVals *pVals)
{
if (pVals->IndexCnt)
{
memcpy(&BAsmCode
[CodeLen
], pVals
->Index
, pVals
->IndexCnt
);
CodeLen += pVals->IndexCnt;
}
}
/*!------------------------------------------------------------------------
* \fn AppendDisp(const tAdrVals *pVals)
* \brief append optional displacement to code
* \param pVals encoded addressing mode
* ------------------------------------------------------------------------ */
static void AppendDisp(const tAdrVals *pVals)
{
if (pVals->DispCnt)
{
memcpy(&BAsmCode
[CodeLen
], pVals
->Disp
, pVals
->DispCnt
);
CodeLen += pVals->DispCnt;
}
}
/*--------------------------------------------------------------------------*/
/* Helper Functions */
/*!------------------------------------------------------------------------
* \fn SizeCodeI(tSymbolSize Size)
* \brief transform (integer) operand size to i size in instruction
* \param Size Operand Size
* \return Size Code
* ------------------------------------------------------------------------ */
static LongWord SizeCodeI(tSymbolSize Size)
{
switch (Size)
{
case eSymbolSize8Bit:
return 0;
case eSymbolSize16Bit:
return 1;
case eSymbolSize32Bit:
return 3;
default:
return 2;
}
}
/*!------------------------------------------------------------------------
* \fn SizeCodeF(tSymbolSize Size)
* \brief transform (float) operand size to f size in instruction
* \param Size Operand Size
* \return Size Code
* ------------------------------------------------------------------------ */
static LongWord SizeCodeF(tSymbolSize Size)
{
switch (Size)
{
case eSymbolSizeFloat64Bit:
return 0;
case eSymbolSizeFloat32Bit:
return 1;
default:
return 0xff;
}
}
/*!------------------------------------------------------------------------
* \fn SizeCodeC(tSymbolSize Size)
* \brief transform (custom) operand size to c size in instruction
* \param Size Operand Size
* \return Size Code
* ------------------------------------------------------------------------ */
static LongWord SizeCodeC(tSymbolSize Size)
{
switch (Size)
{
case eSymbolSize64Bit:
return 0;
case eSymbolSize32Bit:
return 1;
default:
return 0xff;
}
}
/*!------------------------------------------------------------------------
* \fn GetOpSizeFromCode(Word Code)
* \brief get operand size of instruction from insn name
* \param Code contains size in MSB
* \return operand size
* ------------------------------------------------------------------------ */
static tSymbolSize GetOpSizeFromCode(Word Code)
{
Byte Size = Hi(Code) & 15;
return (Size == 0xff) ? eSymbolSizeUnknown : (tSymbolSize)Size;
}
/*!------------------------------------------------------------------------
* \fn SetOpSizeFromCode(Word Code)
* \brief set operand size of instruction from insn code MSB
* \param Code contains size in MSB
* \return True if success
* ------------------------------------------------------------------------ */
static Boolean SetOpSizeFromCode(Word Code)
{
return SetOpSize(GetOpSizeFromCode(Code), &OpPart);
}
/*!------------------------------------------------------------------------
* \fn SetFOpSizeFromCode(Word Code)
* \brief set FP operand size of instruction from insn code
* \param Code contains size in LSB
* \return True if success
* ------------------------------------------------------------------------ */
static Boolean SetFOpSizeFromCode(Word Code)
{
return SetOpSize((Code & 1) ? eSymbolSizeFloat32Bit : eSymbolSizeFloat64Bit, &OpPart);
}
/*!------------------------------------------------------------------------
* \fn SetCOpSizeFromCode(Word Code)
* \brief set custom operand size of instruction from insn code
* \param Code contains size in LSB
* \return True if success
* ------------------------------------------------------------------------ */
static Boolean SetCOpSizeFromCode(Word Code)
{
return SetOpSize((Code & 1) ? eSymbolSize32Bit : eSymbolSize64Bit, &OpPart);
}
/*!------------------------------------------------------------------------
* \fn PutCode(LongWord Code, unsigned Count)
* \brief write instruction opcode to output
* \param Code opcode to write
* \param Count # of bytes to write
* ------------------------------------------------------------------------ */
static void PutCode(LongWord Code, unsigned Count)
{
BAsmCode[CodeLen++] = Code & 0xff;
while (Count > 1)
{
Code >>= 8;
Count--;
BAsmCode[CodeLen++] = Code & 0xff;
}
}
/*!------------------------------------------------------------------------
* \fn ChkNoAttrPart(void)
* \brief check for no attribute part
* \return True if no attribute
* ------------------------------------------------------------------------ */
static Boolean ChkNoAttrPart(void)
{
if (*AttrPart.str.p_str)
{
WrError(ErrNum_UseLessAttr);
return False;
}
return True;
}
/*--------------------------------------------------------------------------*/
/* Instruction De/Encoders */
/*!------------------------------------------------------------------------
* \fn DecodeFixed(Word Code)
* \brief decode instructions without argument
* \param Code machine code
* ------------------------------------------------------------------------ */
static void DecodeFixed(Word Code)
{
if (ChkArgCnt(0, 0))
PutCode(Code, !!Hi(Code));
}
/*!------------------------------------------------------------------------
* \fn DecodeFormat0(Word Code)
* \brief Decode Format 0 Instructions
* \param Code machine code
* ------------------------------------------------------------------------ */
static void DecodeFormat0(Word Code)
{
tAdrVals AdrVals;
ClearAdrVals(&AdrVals);
if (ChkArgCnt(1, 1)
&& ChkNoAttrPart()
&& EncodePCRel(&ArgStr[1], &AdrVals))
{
PutCode(Code, 1);
AppendDisp(&AdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeRET(Word Code)
* \brief Decode RET/RETT/RXP Instructions
* \param Code Machine Code
* ------------------------------------------------------------------------ */
static void DecodeRET(Word Code)
{
if (ChkArgCnt(0, 1)
&& ChkNoAttrPart())
{
tEvalResult EvalResult;
LongInt Value;
tAdrVals AdrVals;
if (ArgCnt >= 1)
Value = EvalStrIntExpressionWithResult(&ArgStr[1], SInt30, &EvalResult);
else
{
Value = 0;
EvalResult.OK = True;
EvalResult.Flags = eSymbolFlag_None;
}
ClearAdrVals(&AdrVals);
if (EncodeDisplacement(Value, &AdrVals, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_OverRange, &ArgStr[1]))
{
PutCode(Code, 1);
AppendDisp(&AdrVals);
}
}
}
/*!------------------------------------------------------------------------
* \fn DecodeCXP(Word Code)
* \brief Handle CXP Instruction
* \param Code machine code
* ------------------------------------------------------------------------ */
static void DecodeCXP(Word Code)
{
if (ChkArgCnt(1, 1)
&& ChkNoAttrPart())
{
tEvalResult EvalResult;
LongInt Value = EvalStrIntExpressionWithResult(&ArgStr[1], SInt30, &EvalResult);
tAdrVals AdrVals;
ClearAdrVals(&AdrVals);
if (EncodeDisplacement(Value, &AdrVals, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_OverRange, &ArgStr[1]))
{
PutCode(Code, 1);
AppendDisp(&AdrVals);
}
}
}
/*!------------------------------------------------------------------------
* \fn DecodeENTER(Word Code)
* \brief Handle ENTER Instruction (Format 1)
* \param Code machine code
* ------------------------------------------------------------------------ */
static void DecodeENTER(Word Code)
{
Byte RegList;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& DecodeRegList(&ArgStr[1], False, &RegList))
{
tEvalResult EvalResult;
LongInt Value = EvalStrIntExpressionWithResult(&ArgStr[2], SInt30, &EvalResult);
tAdrVals AdrVals;
ClearAdrVals(&AdrVals);
if (EncodeDisplacement(Value, &AdrVals, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_OverRange, &ArgStr[1]))
{
PutCode(Code, 1);
BAsmCode[CodeLen++] = RegList;
AppendDisp(&AdrVals);
}
}
}
/*!------------------------------------------------------------------------
* \fn DecodeEXIT(Word Code)
* \brief Handle EXIT Instruction (Format 1)
* \param Code machine code
* ------------------------------------------------------------------------ */
static void DecodeEXIT(Word Code)
{
Byte RegList;
if (ChkArgCnt(1, 1)
&& ChkNoAttrPart()
&& DecodeRegList(&ArgStr[1], True, &RegList))
{
PutCode(Code, 1);
BAsmCode[CodeLen++] = RegList;
}
}
/*!------------------------------------------------------------------------
* \fn DecodeSAVE_RESTORE(Word Code)
* \brief Decode SAVE/RESTORE Instructions
* \param Code Machine Code
* ------------------------------------------------------------------------ */
static void DecodeSAVE_RESTORE(Word Code)
{
Byte RegList;
if (ChkArgCnt(1, 1)
&& ChkNoAttrPart()
&& DecodeRegList(&ArgStr[1], !!(Code & 0x10), &RegList))
{
PutCode(Code, 1);
PutCode(RegList, 1);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeCINV(Word Code)
* \brief handle CINV instruction
* \param Code machine code
* ------------------------------------------------------------------------ */
static void DecodeCINV(Word Code)
{
tAdrVals AdrVals;
if (ChkArgCnt(2, 4)
&& ChkNoAttrPart()
&& CheckCore(1 << eCoreGen2)
&& CheckSup(True, &OpPart)
&& DecodeAdr(&ArgStr[ArgCnt], &AdrVals, MAllowReg))
{
LongWord ActCode = (((LongWord)AdrVals.Code) << 19)
| Code;
int z;
for (z = 1; z < ArgCnt; z++)
if (!as_strcasecmp(ArgStr[z].str.p_str, "A"))
ActCode |= 1ul << 17;
else if (!as_strcasecmp(ArgStr[z].str.p_str, "I"))
ActCode |= 1ul << 16;
else if (!as_strcasecmp(ArgStr[z].str.p_str, "D"))
ActCode |= 1ul << 15;
else
{
WrStrErrorPos(ErrNum_InvCacheInvMode, &ArgStr[z]);
return;
}
PutCode(ActCode, 3);
AppendIndex(&AdrVals);
AppendDisp(&AdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeLPR_SPR(Word Code)
* \brief Decode LPR/SPR Instructions (Format 2)
* \param Code Machine Code & Operand Size
* ------------------------------------------------------------------------ */
static void DecodeLPR_SPR(Word Code)
{
tAdrVals SrcAdrVals;
Word Reg;
Boolean IsSPR = (Lo(Code) == 2);
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[2], &SrcAdrVals, MAllowReg | (IsSPR ? 0 : MAllowImm))
&& DecodeCtlReg(&ArgStr[1], &Reg))
{
PutCode((((Word)SrcAdrVals.Code) << 11)
| (Reg << 7)
| (Lo(Code) << 4)
| (SizeCodeI(OpSize) << 0)
| 0x0c, 2);
AppendIndex(&SrcAdrVals);
AppendDisp(&SrcAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeScond(Word Code)
* \brief Handloe Scond Instructions
* \param Code condition & operand size
* ------------------------------------------------------------------------ */
static void DecodeScond(Word Code)
{
tAdrVals AdrVals;
if (ChkArgCnt(1, 1)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg))
{
PutCode((((Word)AdrVals.Code) << 11)
| ((Code & 0xff) << 7)
| (SizeCodeI(OpSize) << 0)
| 0x3c, 2);
AppendIndex(&AdrVals);
AppendDisp(&AdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeMOVQ(Word Code)
* \brief Handle MOVQ/ADDQ/CMPQ Instructions
* \param Code Machine Code & Operand Size
* ------------------------------------------------------------------------ */
#define MOVQ_DESTMAYIMM 0x80
static void DecodeMOVQ(Word Code)
{
tAdrVals DestAdrVals;
Boolean DestMayImm = !!(Code & MOVQ_DESTMAYIMM);
Code &= ~MOVQ_DESTMAYIMM;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg | (DestMayImm ? MAllowImm : 0)))
{
Boolean OK;
Integer Val = EvalStrIntExpression(&ArgStr[1], SInt4, &OK);
if (OK)
{
PutCode((((Word)DestAdrVals.Code) << 11)
| ((Val & 0x0f) << 7)
| (Lo(Code) << 4)
| (SizeCodeI(OpSize) << 0)
| 0x0c, 2);
AppendIndex(&DestAdrVals);
AppendDisp(&DestAdrVals);
}
}
}
/*!------------------------------------------------------------------------
* \fn DecodeACB(Word Code)
* \brief handle ACBi Instrucion
* \param Code machine code & operand size
* ------------------------------------------------------------------------ */
static void DecodeACB(Word Code)
{
tAdrVals DestAdrVals;
if (ChkArgCnt(3, 3)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
{
Boolean OK;
tAdrVals DistAdrVals;
Integer Val = EvalStrIntExpression(&ArgStr[1], SInt4, &OK);
if (OK && EncodePCRel(&ArgStr[3], &DistAdrVals))
{
PutCode((((Word)DestAdrVals.Code) << 11)
| ((Val & 0x0f) << 7)
| (Lo(Code) << 4)
| (SizeCodeI(OpSize) << 0)
| 0x0c, 2);
AppendIndex(&DestAdrVals);
AppendDisp(&DestAdrVals);
AppendDisp(&DistAdrVals);
}
}
}
/*!------------------------------------------------------------------------
* \fn DecodeFormat3(Word Code)
* \brief Decode Format 3 Instructions
* \param Code Machine Code
* ------------------------------------------------------------------------ */
static void DecodeFormat3(Word Code)
{
tAdrVals AdrVals;
if (ChkArgCnt(1, 1)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg | MAllowImm))
{
PutCode((((Word)AdrVals.Code) << 11)
| (Lo(Code) << 7)
| (SizeCodeI(OpSize) << 0)
| 0x7c, 2);
AppendIndex(&AdrVals);
AppendDisp(&AdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeFormat4(Word Code)
* \brief decode Format 4 instructions
* \param Code machine code
* ------------------------------------------------------------------------ */
#define FMT4_SRCISADDR 0x80
#define FMT4_DESTMAYIMM 0x40
static void DecodeFormat4(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
Boolean SrcIsAddr = !!(Code & FMT4_SRCISADDR),
DestMayImm = !!(Code & FMT4_DESTMAYIMM);
Code &= ~(FMT4_SRCISADDR | FMT4_DESTMAYIMM);
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | (SrcIsAddr ? 0 : MAllowImm))
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg | (DestMayImm ? MAllowImm : 0)))
{
PutCode((((Word)SrcAdrVals.Code) << 11)
| (((Word)DestAdrVals.Code) << 6)
| (Lo(Code) << 2)
| (SizeCodeI(OpSize)), 2);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeMOVS_CMPS_SKPS(Word Code)
* \brief Handle MOVSi/CMPSi/SKPSi Instructions (Format 5)
* \param Code machine code & operand size
* ------------------------------------------------------------------------ */
static void DecodeMOVS_CMPS_SKPS(Word Code)
{
if (ChkArgCnt(0, 2)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(Code))
{
Byte Options = 0;
int z;
for (z = 1; z <= ArgCnt; z++)
{
if (!as_strcasecmp(ArgStr[z].str.p_str, "B"))
Options |= 1;
else if (!as_strcasecmp(ArgStr[z].str.p_str, "U"))
{
if (Options & 6)
{
WrStrErrorPos(ErrNum_ConfStringOpt, &ArgStr[z]);
return;
}
else
Options |= 6;
}
else if (!as_strcasecmp(ArgStr[z].str.p_str, "W"))
{
if (Options & 6)
{
WrStrErrorPos(ErrNum_ConfStringOpt, &ArgStr[z]);
return;
}
else
Options |= 2;
}
else
{
WrStrErrorPos(ErrNum_UnknownStringOpt, &ArgStr[z]);
return;
}
}
PutCode((((LongWord)Options) << 16)
| ((Code & 0xff) << 10)
| (SizeCodeI(OpSize) << 8)
| 0x0e, 3);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeSETCFG(Word Code)
* \brief Handle SETCFG Instruction
* \param Code machine code
* ------------------------------------------------------------------------ */
static void DecodeSETCFG(Word Code)
{
Byte CfgOpts;
if (ChkArgCnt(1, 1)
&& ChkNoAttrPart()
&& CheckSup(True, &OpPart)
&& DecodeCfgList(&ArgStr[1], &CfgOpts))
PutCode((((LongWord)CfgOpts) << 15)
| Code, 3);
}
/*!------------------------------------------------------------------------
* \fn DecodeFormat6(Word Code)
* \brief Decode Format 6 Instructions
* \param Code machine code
* ------------------------------------------------------------------------ */
#define FMT6_SRC8BIT 0x80
static void DecodeFormat6(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
Boolean SrcIs8Bit = !!(Code & FMT6_SRC8BIT);
Code &= ~FMT6_SRC8BIT;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(SrcIs8Bit ? 0x0000 : Code)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
&& ResetOpSize() && SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
{
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| (Lo(Code) << 10)
| (SizeCodeI(OpSize) << 8)
| 0x4e, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeFormat7(Word Code)
* \brief Decode Format 7 Instructions
* \param Code machine code
* ------------------------------------------------------------------------ */
static void DecodeFormat7(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
{
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| (Lo(Code) << 10)
| (SizeCodeI(OpSize) << 8)
| 0xce, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeMOVM_CMPM(Word Code)
* \brief Decode MOVMi/CMPMi Instruction (Format 7)
* \param Code machine code & size
* ------------------------------------------------------------------------ */
static void DecodeMOVM_CMPM(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
if (ChkArgCnt(3, 3)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
{
tEvalResult EvalResult;
LongWord Count = EvalStrIntExpressionWithResult(&ArgStr[3], UInt30, &EvalResult);
if (EvalResult.OK)
{
tAdrVals CntAdrVals;
Count = (Count - 1) << OpSize;
ClearAdrVals(&CntAdrVals);
if (EncodeDisplacement(Count, &CntAdrVals, mFirstPassUnknownOrQuestionable(EvalResult.Flags) ? ErrNum_None : ErrNum_OverRange, &ArgStr[3]))
{
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| (Lo(Code) << 10)
| (SizeCodeI(OpSize) << 8)
| 0xce, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
AppendDisp(&CntAdrVals);
}
}
}
}
/*!------------------------------------------------------------------------
* \fn DecodeINSS_EXTS(Word Code)
* \brief Handle INSS/EXTS Instructions (Format 7)
* \param Code machine code & operand size
* ------------------------------------------------------------------------ */
static void DecodeINSS_EXTS(Word Code)
{
tAdrVals Arg1AdrVals, Arg2AdrVals;
if (ChkArgCnt(4, 4)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &Arg1AdrVals, MAllowReg | ((Lo(Code) == 2) ? MAllowImm : 0))
&& DecodeAdr(&ArgStr[2], &Arg2AdrVals, MAllowReg))
{
tEvalResult EvalResult;
Byte Offs, Length;
Offs = EvalStrIntExpressionWithResult(&ArgStr[3], UInt3, &EvalResult);
if (!EvalResult.OK)
return;
Length = EvalStrIntExpressionWithResult(&ArgStr[4], UInt5, &EvalResult);
if (!EvalResult.OK)
return;
if (mFirstPassUnknownOrQuestionable(EvalResult.Flags))
Length = (Length & 31) + 1;
if (ChkRange(Length, 1, 32))
{
PutCode((((LongWord)Arg1AdrVals.Code) << 19)
| (((LongWord)Arg2AdrVals.Code) << 14)
| (SizeCodeI(OpSize) << 8)
| (Lo(Code) << 10)
| 0xce, 3);
AppendIndex(&Arg1AdrVals);
AppendIndex(&Arg2AdrVals);
AppendDisp(&Arg1AdrVals);
AppendDisp(&Arg2AdrVals);
BAsmCode[CodeLen++] = ((Offs & 7) << 5) | ((Length - 1) & 31);
}
}
}
/*!------------------------------------------------------------------------
* \fn DecodeMOVExt(Word Code)
* \brief Decode MOV{X|Z}{BW|BD|WD} Instructions (Format 7)
* \param Code machine code & operand sizes
* ------------------------------------------------------------------------ */
static void DecodeMOVExt(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
Byte SrcOpSize = (Code >> 8) & 15,
DestOpSize = (Code >> 12) & 15;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& SetOpSize((tSymbolSize)SrcOpSize, &OpPart)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm))
{
OpSize = (tSymbolSize)DestOpSize;
if (DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
{
Code = ((DestOpSize == eSymbolSize32Bit) ? 6 : 5) ^ (Code & 1);
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| (Code << 10)
| (((LongWord)SrcOpSize) << 8)
| 0xce, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
}
/*!------------------------------------------------------------------------
* \fn DecodeDoubleDest(Word Code)
* \brief handle instruction with double-sized dest operand (Format 8)
* \param Code machine code
* ------------------------------------------------------------------------ */
static void DecodeDoubleDest(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowRegPair))
{
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| (Lo(Code) << 10)
| (SizeCodeI(OpSize) << 8)
| 0xce, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeCHECK_INDEX(Word Code)
* \brief Handle CHECK/CVTP/INDEX Instructions (Format 8)
* \param Code machine code & operand size
* ------------------------------------------------------------------------ */
static void DecodeCHECK_INDEX(Word Code)
{
tAdrVals BoundsAdrVals, SrcAdrVals;
Word DestReg;
Boolean IsINDEX = Lo(Code) == 0x42,
IsCVTP = Lo(Code) == 0x06;
if (ChkArgCnt(3, 3)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[2], &BoundsAdrVals, IsINDEX ? (MAllowReg | MAllowImm) : 0)
&& DecodeAdr(&ArgStr[3], &SrcAdrVals, MAllowReg | (IsCVTP ? 0 : MAllowImm))
&& DecodeReg(&ArgStr[1], &DestReg, NULL, eSymbolSize32Bit, True))
{
PutCode((((LongWord)BoundsAdrVals.Code) << 19)
| (((LongWord)SrcAdrVals.Code) << 14)
| (DestReg << 11)
| (SizeCodeI(OpSize) << 8)
| (Lo(Code) << 4)
| 0x0e, 3);
AppendIndex(&BoundsAdrVals);
AppendIndex(&SrcAdrVals);
AppendDisp(&BoundsAdrVals);
AppendDisp(&SrcAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeINS_EXT(Word Code)
* \brief Handle INS/EXT Instructions (Format 8)
* \param IsINS 1 for INS, 0 for EXT
* ------------------------------------------------------------------------ */
static void DecodeINS_EXT(Word IsINS)
{
tAdrVals Arg2AdrVals, Arg3AdrVals;
Word OffsetReg;
if (ChkArgCnt(4, 4)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(IsINS)
&& DecodeReg(&ArgStr[1], &OffsetReg, NULL, eSymbolSize32Bit, True)
&& DecodeAdr(&ArgStr[2], &Arg2AdrVals, MAllowReg | (Lo(IsINS) ? MAllowImm : 0))
&& DecodeAdr(&ArgStr[3], &Arg3AdrVals, MAllowReg))
{
tEvalResult EvalResult;
LongInt Disp = EvalStrIntExpressionWithResult(&ArgStr[4], SInt30, &EvalResult);
if (EvalResult.OK)
{
tAdrVals DispAdrVals;
ClearAdrVals(&DispAdrVals);
if (EncodeDisplacement(Disp, &DispAdrVals, ErrNum_OverRange, &ArgStr[4]))
{
PutCode((((LongWord)Arg2AdrVals.Code) << 19)
| (((LongWord)Arg3AdrVals.Code) << 14)
| (OffsetReg << 11)
| (SizeCodeI(OpSize) << 8)
| (Lo(IsINS) << 7)
| 0x2e, 3);
AppendIndex(&Arg2AdrVals);
AppendIndex(&Arg3AdrVals);
AppendDisp(&Arg2AdrVals);
AppendDisp(&Arg3AdrVals);
AppendDisp(&DispAdrVals);
}
}
}
}
/*!------------------------------------------------------------------------
* \fn DecodeFFS(Word Code)
* \brief Handle FFS Instruction
* \param Code machine code & operand size
* ------------------------------------------------------------------------ */
static void DecodeFFS(Word Code)
{
tAdrVals BaseAdrVals, OffsetAdrVals;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &BaseAdrVals, MAllowReg | MAllowImm)
&& DecodeAdr(&ArgStr[2], &OffsetAdrVals, MAllowReg))
{
PutCode((((LongWord)BaseAdrVals.Code) << 19)
| (((LongWord)OffsetAdrVals.Code) << 14)
| (Lo(Code) << 10)
| (SizeCodeI(OpSize) << 8)
| 0x6e, 3);
AppendIndex(&BaseAdrVals);
AppendIndex(&OffsetAdrVals);
AppendDisp(&BaseAdrVals);
AppendDisp(&OffsetAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeMOVSU(Word Code)
* \brief Handle MOVSU/MOVUS Instruction
* \param Code machine code & operand size
* ------------------------------------------------------------------------ */
static void DecodeMOVSU(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& CheckSup(True, &OpPart)
&& CheckCore((1 << eCoreGen1) | (1 << eCoreGen2))
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, 0)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, 0))
{
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| ((Code & 0xff) << 10)
| (SizeCodeI(OpSize) << 8)
| 0xae, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeFLOOR_ROUND_TRUNC(Word Code)
* \brief Handle FLOOR.../ROUND.../TRUNC... instructions (Format 9)
* \param Code machine code & (integer) op size
* ------------------------------------------------------------------------ */
static void DecodeFLOOR_ROUND_TRUNC(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& CheckFPUAvail(eFPU16081)
&& SetFOpSizeFromCode(Code & 0x1)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
&& ResetOpSize() && SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
{
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| (Lo(Code) << 10)
| (SizeCodeI(OpSize) << 8)
| 0x3e, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeMOVif(Word Code)
* \brief Handle MOV i->f Instructions (Format 9)
* \param Code machine code & (integer) op size
* ------------------------------------------------------------------------ */
static void DecodeMOVif(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& CheckFPUAvail(eFPU16081)
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
&& ResetOpSize() && SetFOpSizeFromCode(Code & 0x1)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
{
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| ((Code & 0xff) << 10)
| (SizeCodeI(GetOpSizeFromCode(Code)) << 8)
| 0x3e, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeFormatLFSR_SFSR(Word Code)
* \brief Handle LFSR/SFSR Instructions (Format 9)
* \param Code Machine Code & Flags
* ------------------------------------------------------------------------ */
#define FMT9_MAYIMM (1 << 15)
static void DecodeLFSR_SFSR(Word Code)
{
Boolean MayImm = !!(Code & FMT9_MAYIMM);
tAdrVals AdrVals;
Code &= ~FMT9_MAYIMM;
if (ChkArgCnt(1, 1)
&& ChkNoAttrPart()
&& CheckFPUAvail(eFPU16081)
&& SetOpSize(eSymbolSize32Bit, &OpPart)
&& DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg | (MayImm ? MAllowImm : 0)))
{
PutCode((((LongWord)AdrVals.Code) << (MayImm ? 19 : 14))
| (((LongWord)Code) << 8)
| 0x3e, 3);
AppendIndex(&AdrVals);
AppendDisp(&AdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeMOVF(Word Code)
* \brief Handle MOVFL/MOVLF Instructions (Format 9)
* \param Code Machine Code & Flags
* ------------------------------------------------------------------------ */
static void DecodeMOVF(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
Byte OpSize = (Code >> 8) & 1;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& CheckFPUAvail(eFPU16081)
&& SetFOpSizeFromCode(OpSize)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
&& ResetOpSize() && SetFOpSizeFromCode(OpSize ^ 1)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
{
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| Code, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeFormat11(Word Code)
* \brief Handle Format 11 Instructions
* \param Code Machine Code & Operand Size
* ------------------------------------------------------------------------ */
#define FMT11_DESTMAYIMM 0x80
static void DecodeFormat11(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
Boolean DestMayImm = !!(Code & FMT11_DESTMAYIMM);
Code &= ~FMT11_DESTMAYIMM;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& CheckFPUAvail(eFPU16081)
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg | (DestMayImm ? MAllowImm : 0)))
{
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| ((Code & 0xff) << 10)
| (SizeCodeF(OpSize) << 8)
| 0xbe, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeFormat12(Word Code)
* \brief Handle Format 12 Instructions
* \param Code Machine Code & Operand Size
* ------------------------------------------------------------------------ */
#define FMT12_DESTMAYIMM 0x40
#define FMT12_580 0x20
static void DecodeFormat12(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
Boolean DestMayImm = !!(Code & FMT12_DESTMAYIMM),
Req580 = !!(Code & FMT12_580);
Code &= ~(FMT12_DESTMAYIMM | FMT12_580);
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& CheckFPUAvail(Req580 ? eFPU32580 : eFPU32181)
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg | (DestMayImm ? MAllowImm : 0)))
{
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| ((Code & 0xff) << 10)
| (SizeCodeF(OpSize) << 8)
| 0xfe, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeLMR_SMR(Word Code)
* \brief Decode LMR/SMR Instructions (Format 14)
* \param Code Machine Code & Operand Size
* ------------------------------------------------------------------------ */
static void DecodeLMR_SMR(Word Code)
{
tAdrVals AdrVals;
Word Reg;
Boolean IsStore = (Code == 3);
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& CheckPMMUAvail()
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[2], &AdrVals, MAllowReg | (IsStore ? 0 : MAllowImm))
&& DecodeMMUReg(&ArgStr[1], &Reg))
{
if (!IsStore && (Reg >= 14))
WrStrErrorPos(ErrNum_Unpredictable, &ArgStr[1]);
PutCode((((LongWord)AdrVals.Code) << 19)
| ((LongWord)Reg << 15)
| (Lo(Code) << 10)
| (SizeCodeI(OpSize) << 8)
| 0x1e, 3);
AppendIndex(&AdrVals);
AppendDisp(&AdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeRDVAL_WRVAL(Word Code)
* \brief Handle RDVAL/WRVAL Instructions
* \param Code Machine code & operand size
* ------------------------------------------------------------------------ */
static void DecodeRDVAL_WRVAL(Word Code)
{
tAdrVals AdrVals;
if (ChkArgCnt(1, 1)
&& ChkNoAttrPart()
&& CheckSup(True, &OpPart)
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg))
{
PutCode((((LongWord)AdrVals.Code) << 19)
| (Lo(Code) << 10)
| (SizeCodeI(OpSize) << 8)
| 0x1e, 3);
AppendIndex(&AdrVals);
AppendDisp(&AdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeCCVci(Word Code)
* \brief Handle CCVnci Instructions (Format 15.1)
* \param Code Machine code & (integer) operand size
* ------------------------------------------------------------------------ */
static void DecodeCCVci(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& CheckCustomAvail()
&& SetCOpSizeFromCode(Code & 0x01)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
&& ResetOpSize() && SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
{
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| (Lo(Code) << 10)
| (SizeCodeI(OpSize) << 8)
| 0x36, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeCCVic(Word Code)
* \brief Handle CCVnic Instructions (Format 15.1)
* \param Code Machine code & (integer) operand size
* ------------------------------------------------------------------------ */
static void DecodeCCVic(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& CheckCustomAvail()
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
&& ResetOpSize() && SetCOpSizeFromCode(Code & 0x01)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
{
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| (Lo(Code) << 10)
| (SizeCodeI(GetOpSizeFromCode(Code)) << 8)
| 0x36, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeCCVcc(Word Code)
* \brief Handle CCVncc Instructions (Format 15.1)
* \param Code Machine Code & Flags
* ------------------------------------------------------------------------ */
static void DecodeCCVcc(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
Byte OpSize = Code & 1;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& CheckCustomAvail()
&& SetCOpSizeFromCode(OpSize)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
&& ResetOpSize() && SetCOpSizeFromCode(OpSize ^ 1)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg))
{
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| (Code << 10)
| 0x36, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeCATST(Word Code)
* \brief Decode CATSTx Instructions (Format 15.0)
* \param Code Machine Code
* ------------------------------------------------------------------------ */
static void DecodeCATST(Word Code)
{
tAdrVals AdrVals;
if (ChkArgCnt(1, 1)
&& ChkNoAttrPart()
&& SetOpSize(eSymbolSize32Bit, &OpPart)
&& DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg | MAllowImm))
{
PutCode((((LongWord)AdrVals.Code) << 19)
| (Code << 10)
| (SizeCodeI(OpSize) << 8)
| 0x16, 3);
AppendIndex(&AdrVals);
AppendDisp(&AdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeLCR_SCR(Word Code)
* \brief Handle LCR/SCR Instructions (Format 15.0)
* \param Code Machine Code & Flags
* ------------------------------------------------------------------------ */
#define FMT15_0_MAYIMM (1 << 7)
static void DecodeLCR_SCR(Word Code)
{
Boolean MayImm = !!(Code & FMT15_0_MAYIMM);
tAdrVals AdrVals;
Code &= ~FMT15_0_MAYIMM;
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& CheckCustomAvail()
&& CheckSup(True, &OpPart)
&& SetOpSize(eSymbolSize32Bit, &OpPart)
&& DecodeAdr(&ArgStr[2], &AdrVals, MAllowReg | (MayImm ? MAllowImm : 0)))
{
Boolean OK;
LongWord Reg = EvalStrIntExpression(&ArgStr[1], UInt4, &OK);
if (OK)
{
PutCode((((LongWord)AdrVals.Code) << 19)
| (Reg << 15)
| (Code << 10)
| (SizeCodeI(OpSize) << 8)
| 0x16, 3);
AppendIndex(&AdrVals);
AppendDisp(&AdrVals);
}
}
}
/*!------------------------------------------------------------------------
* \fn DecodeFormatLCSR_SCSR(Word Code)
* \brief Handle LCSR/SCSR Instructions (Format 15.1)
* \param Code Machine Code & Flags
* ------------------------------------------------------------------------ */
#define FMT15_1_MAYIMM (1 << 7)
static void DecodeLCSR_SCSR(Word Code)
{
Boolean MayImm = !!(Code & FMT15_1_MAYIMM);
tAdrVals AdrVals;
Code &= ~FMT15_1_MAYIMM;
if (ChkArgCnt(1, 1)
&& ChkNoAttrPart()
&& CheckCustomAvail()
&& SetOpSize(eSymbolSize32Bit, &OpPart)
&& DecodeAdr(&ArgStr[1], &AdrVals, MAllowReg | (MayImm ? MAllowImm : 0)))
{
PutCode((((LongWord)AdrVals.Code) << (MayImm ? 19 : 14))
| (((LongWord)Code) << 10)
| (SizeCodeI(OpSize) << 8)
| 0x36, 3);
AppendIndex(&AdrVals);
AppendDisp(&AdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeFormat15_5_7(Word Code)
* \brief Handle Format 15.5/15.7 Instructions
* \param Code Machine code & operand size
* ------------------------------------------------------------------------ */
#define FMT15_5_DESTMAYIMM 0x80
#define FMT15_7 0x40
static void DecodeFormat15_5_7(Word Code)
{
tAdrVals SrcAdrVals, DestAdrVals;
unsigned DestMayImm = (Code & FMT15_5_DESTMAYIMM) ? MAllowImm : 0,
Is7 = !!(Code & FMT15_7);
Code &= ~(FMT15_5_DESTMAYIMM | FMT15_7);
if (ChkArgCnt(2, 2)
&& ChkNoAttrPart()
&& CheckCustomAvail()
&& (!Is7 || CheckCore((1 << eCoreGen1Ext) | (1 << eCoreGen2)))
&& SetOpSizeFromCode(Code)
&& DecodeAdr(&ArgStr[1], &SrcAdrVals, MAllowReg | MAllowImm)
&& DecodeAdr(&ArgStr[2], &DestAdrVals, MAllowReg| DestMayImm))
{
PutCode((((LongWord)SrcAdrVals.Code) << 19)
| (((LongWord)DestAdrVals.Code) << 14)
| (Lo(Code) << 10)
| (SizeCodeC(OpSize) << 8)
| (Is7 << 6)
| 0xb6, 3);
AppendIndex(&SrcAdrVals);
AppendIndex(&DestAdrVals);
AppendDisp(&SrcAdrVals);
AppendDisp(&DestAdrVals);
}
}
/*!------------------------------------------------------------------------
* \fn void CodeFPU(Word Code)
* \brief Handle FPU Instruction
* ------------------------------------------------------------------------ */
static void CodeFPU(Word Code)
{
UNUSED(Code);
if (ChkArgCnt(1, 1))
{
if (!as_strcasecmp(ArgStr[1].str.p_str, "OFF"))
{
SetFlag(&FPUAvail, FPUAvailName, False);
SetMomFPU(eFPUNone);
}
else if (!as_strcasecmp(ArgStr[1].str.p_str, "ON"))
{
SetFlag(&FPUAvail, FPUAvailName, True);
if (!MomFPU)
SetMomFPU((tFPU)pCurrCPUProps->DefFPU);
}
else
{
tFPU FPU;
for (FPU = (tFPU)1; FPU < eFPUCount; FPU++)
if (!as_strcasecmp(ArgStr[1].str.p_str, FPUNames[FPU]))
{
SetFlag(&FPUAvail, FPUAvailName, True);
SetMomFPU(FPU);
break;
}
if (FPU >= eFPUCount)
WrStrErrorPos(ErrNum_InvFPUType, &ArgStr[1]);
}
}
}
/*!------------------------------------------------------------------------
* \fn void CodePMMU(Word Code)
* \brief Handle PMMU Instruction
* ------------------------------------------------------------------------ */
static void CodePMMU(Word Code)
{
UNUSED(Code);
if (ChkArgCnt(1, 1))
{
if (!as_strcasecmp(ArgStr[1].str.p_str, "OFF"))
{
SetFlag(&PMMUAvail, PMMUAvailName, False);
SetMomPMMU(ePMMUNone);
}
else if (!as_strcasecmp(ArgStr[1].str.p_str, "ON"))
{
SetFlag(&PMMUAvail, PMMUAvailName, True);
if (!MomPMMU)
SetMomPMMU((tPMMU)pCurrCPUProps->DefPMMU);
}
else
{
tPMMU PMMU;
for (PMMU = (tPMMU)1; PMMU < ePMMUCount; PMMU++)
if (!as_strcasecmp(ArgStr[1].str.p_str, PMMUNames[PMMU]))
{
SetFlag(&PMMUAvail, PMMUAvailName, True);
SetMomPMMU(PMMU);
break;
}
if (PMMU >= ePMMUCount)
WrStrErrorPos(ErrNum_InvPMMUType, &ArgStr[1]);
}
}
}
/*!------------------------------------------------------------------------
* \fn DecodeBB(Word Code)
* \brief Handle BitBLT Instructions
* \param Code Machine Code & Options
* ------------------------------------------------------------------------ */
#define BB_NOOPT (1 << 15)
typedef struct
{
char Name[3];
Byte Pos, Value;
} tBitBltOpt;
static const tBitBltOpt BitBltOpts[] =
{
{ "DA" , 17, 1 },
{ "-S" , 15, 1 },
{ "IA" , 17, 0 },
{ "S" , 15, 0 },
{ "" , 0 , 0 }
};
static void DecodeBB(Word Code)
{
if (ChkArgCnt(0, 2)
&& ChkNoAttrPart()
&& CheckCore(1 << eCoreGenE))
{
LongWord OpCode = 0x0e | ((LongWord)(Code & ~BB_NOOPT) << 8), OptMask = 0;
tStrComp *pArg;
const tBitBltOpt *pOpt;
forallargs(pArg, True)
{
for (pOpt = BitBltOpts + ((Code & BB_NOOPT) ? 2 : 0); pOpt->Name[0]; pOpt++)
if (!as_strcasecmp(pArg->str.p_str, pOpt->Name))
{
LongWord ThisMask = 1ul << pOpt->Pos;
if (OptMask & ThisMask)
{
WrStrErrorPos(ErrNum_ConfBitBltOpt, pArg);
return;
}
OptMask |= ThisMask;
OpCode = pOpt->Value ? (OpCode | ThisMask) : (OpCode & ~ThisMask);
break;
}
if (!pOpt->Name[0])
{
WrStrErrorPos(ErrNum_UnknownBitBltOpt, pArg);
return;
}
}
PutCode(OpCode, 3);
}
}
/*!------------------------------------------------------------------------
* \fn DecodeBITxT(Word Code)
* \brief Handle BITBLT instructions without argument
* \param Code Machine Code
* ------------------------------------------------------------------------ */
static void DecodeBITxT(Word Code)
{
if (ChkArgCnt(0, 0)
&& ChkNoAttrPart()
&& CheckCore(1 << eCoreGenE))
PutCode(((LongWord)Code) << 8 | 0x0e, 3);
}
/*!------------------------------------------------------------------------
* \fn DecodeTBITS(Word Code)
* \brief Handle TBITS Instruction
* \param Code Machine Code
* ------------------------------------------------------------------------ */
static void DecodeTBITS(Word Code)
{
if (ChkArgCnt(1, 1)
&& ChkNoAttrPart()
&& CheckCore(1 << eCoreGenE))
{
Boolean OK;
LongWord Arg = EvalStrIntExpression(&ArgStr[1], UInt1, &OK);
if (OK)
PutCode((Arg << 15)
| (((LongWord)Code) << 8)
| 0x0e, 3);
}
}
/*--------------------------------------------------------------------------*/
/* Instruction Lookup Table */
/*!------------------------------------------------------------------------
* \fn InitFields(void)
* \brief create lookup table
* ------------------------------------------------------------------------ */
static void AddSizeInstTable(const char *pName, unsigned SizeMask, Word Code, InstProc Proc)
{
char Name[20];
tSymbolSize Size;
for (Size = eSymbolSize8Bit; Size <= eSymbolSize32Bit; Size++)
if (SizeMask & (1 << Size))
{
as_snprintf(Name, sizeof(Name), "%s%c", pName, "BWD"[Size - eSymbolSize8Bit]);
AddInstTable(InstTable, Name, Code | (Size << 8), Proc);
}
}
static void AddFSizeInstTable(const char *pName, unsigned SizeMask, Word Code, InstProc Proc)
{
char Name[20];
tSymbolSize Size;
for (Size = eSymbolSizeFloat32Bit; Size <= eSymbolSizeFloat64Bit; Size++)
if (SizeMask & (1 << Size))
{
as_snprintf(Name, sizeof(Name), "%s%c", pName, "FL"[Size - eSymbolSizeFloat32Bit]);
AddInstTable(InstTable, Name, Code | (Size << 8), Proc);
}
}
static void AddCSizeInstTable(const char *pName, unsigned SizeMask, Word Code, InstProc Proc)
{
char Name[20];
tSymbolSize Size;
for (Size = eSymbolSize32Bit; Size <= eSymbolSize64Bit; Size++)
if (SizeMask & (1 << Size))
{
as_snprintf(Name, sizeof(Name), "%s%c", pName, "DQ"[Size - eSymbolSize32Bit]);
AddInstTable(InstTable, Name, Code | (Size << 8), Proc);
}
}
static void AddCondition(const char *pCondition, Word Code)
{
char Str[20];
as_snprintf(Str, sizeof(Str), "B%s", pCondition);
AddInstTable(InstTable, Str, (Code << 4) | 0x0a, DecodeFormat0);
as_snprintf(Str, sizeof(Str), "S%s", pCondition);
AddSizeInstTable(Str, (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), Code, DecodeScond);
}
static void AddCtl(const char *pName, Word Code, Boolean Privileged)
{
order_array_rsv_end(CtlRegs, tCtlReg);
CtlRegs[InstrZ ].pName = pName;
CtlRegs[InstrZ ].Code = Code;
CtlRegs[InstrZ++].Privileged = Privileged;
}
static void AddMMU(const char *pName, Word Code, Word Mask, Boolean Privileged)
{
order_array_rsv_end(MMURegs, tCtlReg);
MMURegs[InstrZ ].pName = pName;
MMURegs[InstrZ ].Code = Code;
MMURegs[InstrZ ].Mask = Mask;
MMURegs[InstrZ++].Privileged = Privileged;
}
static void InitFields(void)
{
InstTable = CreateInstTable(605);
SetDynamicInstTable(InstTable);
InstrZ = 0;
AddCtl("UPSR" , 0x00, True );
AddCtl("DCR" , 0x01, True );
AddCtl("BPC" , 0x02, True );
AddCtl("DSR" , 0x03, True );
AddCtl("CAR" , 0x04, True );
AddCtl("FP" , 0x08, False);
AddCtl("SP" , 0x09, False);
AddCtl("SB" , 0x0a, False);
AddCtl("USP" , 0x0b, True );
AddCtl("CFG" , 0x0c, True );
AddCtl("PSR" , 0x0d, False);
AddCtl("INTBASE", 0x0e, True );
AddCtl("MOD" , 0x0f, False);
AddCtl(NULL , 0 , False);
InstrZ = 0;
AddMMU("BPR0" , 0x00, (1 << ePMMU16082) | (1 << ePMMU32082) , True );
AddMMU("BPR1" , 0x01, (1 << ePMMU16082) | (1 << ePMMU32082) , True );
AddMMU("MSR" , 0x0a, (1 << ePMMU16082) | (1 << ePMMU32082) | (1 << ePMMU32532), True );
AddMMU("BCNT" , 0x0b, (1 << ePMMU16082) | (1 << ePMMU32082) , True );
AddMMU("PTB0" , 0x0c, (1 << ePMMU16082) | (1 << ePMMU32082) | (1 << ePMMU32382) | (1 << ePMMU32532), True );
AddMMU("PTB1" , 0x0d, (1 << ePMMU16082) | (1 << ePMMU32082) | (1 << ePMMU32382) | (1 << ePMMU32532), True );
AddMMU("EIA" , 0x0f, (1 << ePMMU16082) | (1 << ePMMU32082) , True );
AddMMU("BAR" , 0x00, (1 << ePMMU32382) , True );
AddMMU("BMR" , 0x02, (1 << ePMMU32382) , True );
AddMMU("BDR" , 0x03, (1 << ePMMU32382) , True );
AddMMU("BEAR" , 0x06, (1 << ePMMU32382) , True );
AddMMU("FEW" , 0x09, (1 << ePMMU32382) , True );
AddMMU("ASR" , 0x0a, (1 << ePMMU32382) , True );
AddMMU("TEAR" , 0x0b, (1 << ePMMU32382) | (1 << ePMMU32532), True );
/* TODO: 8 according to National docu, but 9 according to sample code */
AddMMU("MCR" , 0x09, (1 << ePMMU32532), True );
AddMMU("IVAR0" , 0x0e, (1 << ePMMU32382) | (1 << ePMMU32532), True );/* w/o */
AddMMU("IVAR1" , 0x0f, (1 << ePMMU32382) | (1 << ePMMU32532), True );/* w/o */
AddMMU(NULL , 0, 0, False);
AddCondition("EQ", 0);
AddCondition("NE", 1);
AddCondition("CS", 2);
AddCondition("CC", 3);
AddCondition("HI", 4);
AddCondition("LS", 5);
AddCondition("GT", 6);
AddCondition("LE", 7);
AddCondition("FS", 8);
AddCondition("FC", 9);
AddCondition("LO", 10);
AddCondition("HS", 11);
AddCondition("LT", 12);
AddCondition("GE", 13);
/* Format 0 */
AddInstTable(InstTable, "BR" , 0xea, DecodeFormat0);
AddInstTable(InstTable, "BSR", 0x02, DecodeFormat0);
/* Format 1 */
AddInstTable(InstTable, "BPT" , 0xf2, DecodeFixed);
AddInstTable(InstTable, "DIA" , 0xc2, DecodeFixed);
AddInstTable(InstTable, "FLAG", 0xd2, DecodeFixed);
AddInstTable(InstTable, "NOP" , NOPCode, DecodeFixed);
AddInstTable(InstTable, "RETI", 0x52, DecodeFixed);
AddInstTable(InstTable, "SVC" , 0xe2, DecodeFixed);
AddInstTable(InstTable, "WAIT", 0xb2, DecodeFixed);
AddInstTable(InstTable, "RET" , 0x12, DecodeRET);
AddInstTable(InstTable, "RETT", 0x42, DecodeRET);
AddInstTable(InstTable, "RXP" , 0x32, DecodeRET);
AddInstTable(InstTable, "SAVE", 0x62, DecodeSAVE_RESTORE);
AddInstTable(InstTable, "RESTORE", 0x72, DecodeSAVE_RESTORE);
AddInstTable(InstTable, "CINV", 0x271e, DecodeCINV);
AddInstTable(InstTable, "CXP" , 0x22, DecodeCXP);
AddInstTable(InstTable, "ENTER", 0x82, DecodeENTER);
AddInstTable(InstTable, "EXIT", 0x92, DecodeEXIT);
/* Format 2 */
AddSizeInstTable("ADDQ" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0, DecodeMOVQ);
AddSizeInstTable("LPR" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 6, DecodeLPR_SPR);
AddSizeInstTable("SPR" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 2, DecodeLPR_SPR);
AddSizeInstTable("MOVQ" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 5, DecodeMOVQ);
AddSizeInstTable("ACB" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 4, DecodeACB);
AddSizeInstTable("CMPQ" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 1 | MOVQ_DESTMAYIMM, DecodeMOVQ);
/* Format 3 */
AddInstTable(InstTable, "JUMP" , 0x04 | (eSymbolSize32Bit << 8), DecodeFormat3);
AddInstTable(InstTable, "JSR" , 0x0c | (eSymbolSize32Bit << 8), DecodeFormat3);
AddSizeInstTable("ADJSP" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0a, DecodeFormat3);
AddSizeInstTable("BICPSR", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit), 0x02, DecodeFormat3);
AddSizeInstTable("BISPSR", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit), 0x06, DecodeFormat3);
AddSizeInstTable("CASE" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFormat3);
AddInstTable(InstTable, "CXPD" , 0x00 | (eSymbolSize32Bit << 8), DecodeFormat3);
/* Format 4 */
AddSizeInstTable("MOV" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x05, DecodeFormat4);
AddSizeInstTable("ADD" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x00, DecodeFormat4);
AddSizeInstTable("ADDC", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x04, DecodeFormat4);
AddInstTable(InstTable, "ADDR", (eSymbolSize32Bit << 8) | FMT4_SRCISADDR | 0x09, DecodeFormat4);
AddSizeInstTable("AND" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0a, DecodeFormat4);
AddSizeInstTable("BIC" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x02, DecodeFormat4);
AddSizeInstTable("CMP" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), FMT4_DESTMAYIMM | 0x01, DecodeFormat4);
AddSizeInstTable("OR" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x06, DecodeFormat4);
AddSizeInstTable("SUB" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeFormat4);
AddSizeInstTable("SUBC", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0c, DecodeFormat4);
AddSizeInstTable("TBIT", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0d, DecodeFormat4);
AddSizeInstTable("XOR" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFormat4);
/* Format 5 */
AddSizeInstTable("MOVS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x00, DecodeMOVS_CMPS_SKPS);
AddSizeInstTable("CMPS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x01, DecodeMOVS_CMPS_SKPS);
AddSizeInstTable("SKPS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x03, DecodeMOVS_CMPS_SKPS);
AddInstTable(InstTable, "MOVST", (eSymbolSize8Bit << 8) | 0x20, DecodeMOVS_CMPS_SKPS);
AddInstTable(InstTable, "CMPST", (eSymbolSize8Bit << 8) | 0x21, DecodeMOVS_CMPS_SKPS);
AddInstTable(InstTable, "SKPST", (eSymbolSize8Bit << 8) | 0x23, DecodeMOVS_CMPS_SKPS);
AddInstTable(InstTable, "SETCFG", 0xb0e, DecodeSETCFG);
/* Format 6 */
AddSizeInstTable("ABS" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0c, DecodeFormat6);
AddSizeInstTable("ADDP" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0f, DecodeFormat6);
AddSizeInstTable("ASH" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), FMT6_SRC8BIT | 0x01, DecodeFormat6);
AddSizeInstTable("CBIT" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x02, DecodeFormat6);
AddSizeInstTable("CBITI" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x03, DecodeFormat6);
AddSizeInstTable("COM" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0d, DecodeFormat6);
AddSizeInstTable("IBIT" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFormat6);
AddSizeInstTable("LSH" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), FMT6_SRC8BIT | 0x05, DecodeFormat6);
AddSizeInstTable("NEG" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeFormat6);
AddSizeInstTable("NOT" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x09, DecodeFormat6);
AddSizeInstTable("ROT" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), FMT6_SRC8BIT | 0x00, DecodeFormat6);
AddSizeInstTable("SBIT" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x06, DecodeFormat6);
AddSizeInstTable("SBITI" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x07, DecodeFormat6);
AddSizeInstTable("SUBP" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0b, DecodeFormat6);
/* Format 7 */
AddSizeInstTable("DIV" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0f, DecodeFormat7);
AddSizeInstTable("MOD" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFormat7);
AddSizeInstTable("MUL" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeFormat7);
AddSizeInstTable("QUO" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0c, DecodeFormat7);
AddSizeInstTable("REM" , (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0d, DecodeFormat7);
AddInstTable(InstTable, "MOVXBW", (eSymbolSize8Bit << 8) | (eSymbolSize16Bit << 12) | 1, DecodeMOVExt);
AddInstTable(InstTable, "MOVXBD", (eSymbolSize8Bit << 8) | (eSymbolSize32Bit << 12) | 1, DecodeMOVExt);
AddInstTable(InstTable, "MOVXWD", (eSymbolSize16Bit << 8) | (eSymbolSize32Bit << 12) | 1, DecodeMOVExt);
AddInstTable(InstTable, "MOVZBW", (eSymbolSize8Bit << 8) | (eSymbolSize16Bit << 12) | 0, DecodeMOVExt);
AddInstTable(InstTable, "MOVZBD", (eSymbolSize8Bit << 8) | (eSymbolSize32Bit << 12) | 0, DecodeMOVExt);
AddInstTable(InstTable, "MOVZWD", (eSymbolSize16Bit << 8) | (eSymbolSize32Bit << 12) | 0, DecodeMOVExt);
AddSizeInstTable("MOVM", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x00, DecodeMOVM_CMPM);
AddSizeInstTable("CMPM", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x01, DecodeMOVM_CMPM);
AddSizeInstTable("DEI", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0b, DecodeDoubleDest);
AddSizeInstTable("MEI", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x09, DecodeDoubleDest);
AddSizeInstTable("EXTS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x03, DecodeINSS_EXTS);
AddSizeInstTable("INSS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x02, DecodeINSS_EXTS);
/* Format 8 */
AddSizeInstTable("CHECK", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeCHECK_INDEX);
AddInstTable(InstTable, "CVTP", (eSymbolSize32Bit << 8) | 0x06, DecodeCHECK_INDEX);
AddSizeInstTable("INDEX", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x42, DecodeCHECK_INDEX);
AddSizeInstTable("EXT", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0, DecodeINS_EXT);
AddSizeInstTable("INS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 1, DecodeINS_EXT);
AddSizeInstTable("FFS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x01, DecodeFFS);
AddSizeInstTable("MOVSU", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x3, DecodeMOVSU);
AddSizeInstTable("MOVUS", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x7, DecodeMOVSU);
/* Format 9 */
AddSizeInstTable("FLOORF", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0f, DecodeFLOOR_ROUND_TRUNC);
AddSizeInstTable("FLOORL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeFLOOR_ROUND_TRUNC);
AddSizeInstTable("ROUNDF", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x09, DecodeFLOOR_ROUND_TRUNC);
AddSizeInstTable("ROUNDL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeFLOOR_ROUND_TRUNC);
AddSizeInstTable("TRUNCF", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0b, DecodeFLOOR_ROUND_TRUNC);
AddSizeInstTable("TRUNCL", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0a, DecodeFLOOR_ROUND_TRUNC);
AddInstTable(InstTable, "MOVBF", 0x01 | (eSymbolSize8Bit << 8), DecodeMOVif);
AddInstTable(InstTable, "MOVWF", 0x01 | (eSymbolSize16Bit << 8), DecodeMOVif);
AddInstTable(InstTable, "MOVDF", 0x01 | (eSymbolSize32Bit << 8), DecodeMOVif);
AddInstTable(InstTable, "MOVBL", 0x00 | (eSymbolSize8Bit << 8), DecodeMOVif);
AddInstTable(InstTable, "MOVWL", 0x00 | (eSymbolSize16Bit << 8), DecodeMOVif);
AddInstTable(InstTable, "MOVDL", 0x00 | (eSymbolSize32Bit << 8), DecodeMOVif);
AddInstTable(InstTable, "LFSR", 0x0f | FMT9_MAYIMM, DecodeLFSR_SFSR);
AddInstTable(InstTable, "SFSR", 0x37, DecodeLFSR_SFSR);
AddInstTable(InstTable, "MOVFL" , 0x1b3e, DecodeMOVF);
AddInstTable(InstTable, "MOVLF" , 0x163e, DecodeMOVF);
/* Format 11 */
AddFSizeInstTable("ABS", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x0d, DecodeFormat11);
AddFSizeInstTable("ADD", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x00, DecodeFormat11);
AddFSizeInstTable("CMP", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x02 | FMT11_DESTMAYIMM, DecodeFormat11);
AddFSizeInstTable("DIV", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x08, DecodeFormat11);
AddFSizeInstTable("MOV", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x01, DecodeFormat11);
AddFSizeInstTable("MUL", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x0c, DecodeFormat11);
AddFSizeInstTable("NEG", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x05, DecodeFormat11);
AddFSizeInstTable("SUB", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x04, DecodeFormat11);
/* Format 12 - only newer FPUs? */
AddFSizeInstTable("DOT" , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x03 | FMT12_DESTMAYIMM, DecodeFormat12);
AddFSizeInstTable("LOGB" , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x05, DecodeFormat12);
AddFSizeInstTable("POLY" , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x02 | FMT12_DESTMAYIMM, DecodeFormat12);
AddFSizeInstTable("SCALB", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x04, DecodeFormat12);
AddFSizeInstTable("REM" , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), 0x00, DecodeFormat12);
AddFSizeInstTable("SQRT" , (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), FMT12_580 | 0x01, DecodeFormat12);
AddFSizeInstTable("ATAN2", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), FMT12_580 | 0x0c, DecodeFormat12);
AddFSizeInstTable("SICOS", (1 << eSymbolSizeFloat32Bit) | (1 << eSymbolSizeFloat64Bit), FMT12_580 | 0x0d, DecodeFormat12);
/* Format 14 */
AddInstTable(InstTable, "LMR" , 0x02 | (eSymbolSize32Bit << 8), DecodeLMR_SMR);
AddInstTable(InstTable, "SMR" , 0x03 | (eSymbolSize32Bit << 8), DecodeLMR_SMR);
AddInstTable(InstTable, "RDVAL", 0x00 | (eSymbolSize32Bit << 8), DecodeRDVAL_WRVAL);
AddInstTable(InstTable, "WRVAL", 0x01 | (eSymbolSize32Bit << 8), DecodeRDVAL_WRVAL);
AddInstTable(InstTable, "REG" , 0, CodeREG);
AddInstTable(InstTable, "BYTE" , eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString , DecodeIntelDB);
AddInstTable(InstTable, "WORD" , eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString , DecodeIntelDW);
AddInstTable(InstTable, "DOUBLE" , eIntPseudoFlag_AllowInt | eIntPseudoFlag_AllowString , DecodeIntelDD);
AddInstTable(InstTable, "FLOAT" , eIntPseudoFlag_AllowFloat , DecodeIntelDD);
AddInstTable(InstTable, "LONG" , eIntPseudoFlag_AllowFloat , DecodeIntelDQ);
AddInstTable(InstTable, "FPU" , 0, CodeFPU);
AddInstTable(InstTable, "PMMU" , 0, CodePMMU);
/* Format 15.0 */
AddInstTable(InstTable, "LCR", 0x0a | FMT15_0_MAYIMM, DecodeLCR_SCR);
AddInstTable(InstTable, "SCR", 0x0b , DecodeLCR_SCR);
AddInstTable(InstTable, "CATST0", 0x00, DecodeCATST);
AddInstTable(InstTable, "CATST1", 0x01, DecodeCATST);
/* Format 15.1 */
AddSizeInstTable("CCV0Q", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0e, DecodeCCVci);
AddSizeInstTable("CCV0D", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0f, DecodeCCVci);
AddSizeInstTable("CCV1Q", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0a, DecodeCCVci);
AddSizeInstTable("CCV1D", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x0b, DecodeCCVci);
AddSizeInstTable("CCV2Q", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x08, DecodeCCVci);
AddSizeInstTable("CCV2D", (1 << eSymbolSize8Bit) | (1 << eSymbolSize16Bit) | (1 << eSymbolSize32Bit), 0x09, DecodeCCVci);
AddInstTable(InstTable, "CCV3BQ", (eSymbolSize8Bit << 8) | 0x00, DecodeCCVic);
AddInstTable(InstTable, "CCV3WQ", (eSymbolSize16Bit << 8) | 0x00, DecodeCCVic);
AddInstTable(InstTable, "CCV3DQ", (eSymbolSize32Bit << 8) | 0x00, DecodeCCVic);
AddInstTable(InstTable, "CCV3BD", (eSymbolSize8Bit << 8) | 0x01, DecodeCCVic);
AddInstTable(InstTable, "CCV3WD", (eSymbolSize16Bit << 8) | 0x01, DecodeCCVic);
AddInstTable(InstTable, "CCV3DD", (eSymbolSize32Bit << 8) | 0x01, DecodeCCVic);
AddInstTable(InstTable, "CCV4DQ", 0x07, DecodeCCVcc);
AddInstTable(InstTable, "CCV5QD", 0x04, DecodeCCVcc);
AddInstTable(InstTable, "LCSR", 0x01 | FMT15_1_MAYIMM, DecodeLCSR_SCSR);
AddInstTable(InstTable, "SCSR", 0x06, DecodeLCSR_SCSR);
/* Format 15.5/15.7 */
AddCSizeInstTable("CCAL0", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x00, DecodeFormat15_5_7);
AddCSizeInstTable("CMOV0", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x01, DecodeFormat15_5_7);
AddCSizeInstTable("CCMP" , (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_5_DESTMAYIMM | 0x02, DecodeFormat15_5_7);
AddCSizeInstTable("CCMP1", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_5_DESTMAYIMM | 0x03, DecodeFormat15_5_7);
AddCSizeInstTable("CCAL1", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x04, DecodeFormat15_5_7);
AddCSizeInstTable("CMOV2", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x05, DecodeFormat15_5_7);
AddCSizeInstTable("CCAL3", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x08, DecodeFormat15_5_7);
AddCSizeInstTable("CMOV3", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x09, DecodeFormat15_5_7);
AddCSizeInstTable("CCAL2", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x0c, DecodeFormat15_5_7);
AddCSizeInstTable("CMOV1", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), 0x0d, DecodeFormat15_5_7);
AddCSizeInstTable("CCAL4", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x00, DecodeFormat15_5_7);
AddCSizeInstTable("CMOV4", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x01, DecodeFormat15_5_7);
AddCSizeInstTable("CCAL8", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x02, DecodeFormat15_5_7);
AddCSizeInstTable("CCAL9", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x03, DecodeFormat15_5_7);
AddCSizeInstTable("CCAL5", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x04, DecodeFormat15_5_7);
AddCSizeInstTable("CMOV6", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x05, DecodeFormat15_5_7);
AddCSizeInstTable("CCAL7", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x08, DecodeFormat15_5_7);
AddCSizeInstTable("CMOV7", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x09, DecodeFormat15_5_7);
AddCSizeInstTable("CCAL6", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x0c, DecodeFormat15_5_7);
AddCSizeInstTable("CMOV5", (1 << eSymbolSize32Bit) | (1 << eSymbolSize64Bit), FMT15_7 | 0x0d, DecodeFormat15_5_7);
/* BITBLT */
AddInstTable(InstTable, "BBAND" , 0x12b, DecodeBB);
AddInstTable(InstTable, "BBOR" , 0x019, DecodeBB);
AddInstTable(InstTable, "BBXOR" , 0x039, DecodeBB);
AddInstTable(InstTable, "BBFOR" , BB_NOOPT | 0x031, DecodeBB);
AddInstTable(InstTable, "BBSTOD" , 0x011, DecodeBB);
AddInstTable(InstTable, "BITWT" , 0x21, DecodeBITxT);
AddInstTable(InstTable, "EXTBLT" , 0x17, DecodeBITxT);
AddInstTable(InstTable, "MOVMPB" , 0x1c, DecodeBITxT);
AddInstTable(InstTable, "MOVMPW" , 0x1d, DecodeBITxT);
AddInstTable(InstTable, "MOVMPD" , 0x1f, DecodeBITxT);
AddInstTable(InstTable, "SBITS" , 0x37, DecodeBITxT);
AddInstTable(InstTable, "SBITPS" , 0x2f, DecodeBITxT);
AddInstTable(InstTable, "TBITS" , 0x27, DecodeTBITS);
}
/*!------------------------------------------------------------------------
* \fn DeinitFields(void)
* \brief destroy/cleanup lookup table
* ------------------------------------------------------------------------ */
static void DeinitFields(void)
{
DestroyInstTable(InstTable);
order_array_free(CtlRegs);
order_array_free(MMURegs);
}
/*--------------------------------------------------------------------------*/
/* Interface Functions */
/*!------------------------------------------------------------------------
* \fn MakeCode_NS32K(void)
* \brief encode machine instruction
* ------------------------------------------------------------------------ */
static void MakeCode_NS32K(void)
{
CodeLen = 0; DontPrint = False;
OpSize = eSymbolSizeUnknown;
/* to be ignored */
if (Memo("")) return;
/* Pseudo Instructions */
if (DecodeIntelPseudo(TargetBigEndian))
return;
if (!LookupInstTable(InstTable, OpPart.str.p_str))
WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
}
/*!------------------------------------------------------------------------
* \fn InternSymbol_NS32K(char *pArg, TempResult *pResult)
* \brief handle built-in symbols on NS32000
* \param pArg source argument
* \param pResult result buffer
* ------------------------------------------------------------------------ */
static void InternSymbol_NS32K(char *pArg, TempResult *pResult)
{
Word Reg;
tSymbolSize Size;
if (DecodeRegCore(pArg, &Reg, &Size))
{
pResult->Typ = TempReg;
pResult->DataSize = Size;
pResult->Contents.RegDescr.Reg = Reg;
pResult->Contents.RegDescr.Dissect = DissectReg_NS32K;
pResult->Contents.RegDescr.compare = NULL;
}
}
/*!------------------------------------------------------------------------
* \fn InitCode_NS32K(void)
* \brief target-specific initializations before starting a pass
* ------------------------------------------------------------------------ */
static void InitCode_NS32K(void)
{
SetMomFPU(eFPUNone);
SetMomPMMU(ePMMUNone);
}
/*!------------------------------------------------------------------------
* \fn IsDef_NS32K(void)
* \brief check whether insn makes own use of label
* \return True if yes
* ------------------------------------------------------------------------ */
static Boolean IsDef_NS32K(void)
{
return Memo("REG");
}
/*!------------------------------------------------------------------------
* \fn SwitchTo_NS32K(void *pUser)
* \brief prepare to assemble code for this target
* \param pUser CPU properties
* ------------------------------------------------------------------------ */
static Boolean ChkMoreZeroArg(void)
{
return (ArgCnt > 0);
}
static void SwitchTo_NS32K(void *pUser)
{
const TFamilyDescr *pDescr = FindFamilyByName("NS32000");
TurnWords = True;
SetIntConstMode(eIntConstModeIntel);
SaveIsOccupiedFnc = ChkMoreZeroArg;
RestoreIsOccupiedFnc = ChkMoreZeroArg;
pCurrCPUProps = (const tCPUProps*)pUser;
/* default selection of "typical" companion FPU/PMMU: */
SetMomFPU((tFPU)pCurrCPUProps->DefFPU);
SetMomPMMU((tPMMU)pCurrCPUProps->DefPMMU);
PCSymbol = "*"; HeaderID = pDescr->Id;
NOPCode = 0xa2;
DivideChars = ",";
HasAttrs = True; AttrChars = ".";
ValidSegs = (1 << SegCode);
Grans[SegCode] = 1; ListGrans[SegCode] = 1; SegInits[SegCode] = 0;
SegLimits[SegCode] = IntTypeDefs[pCurrCPUProps->MemIntType].Max;
MakeCode = MakeCode_NS32K;
IsDef = IsDef_NS32K;
DissectReg = DissectReg_NS32K;
InternSymbol = InternSymbol_NS32K;
SwitchFrom = DeinitFields;
IntConstModeIBMNoTerm = True;
QualifyQuote = QualifyQuote_SingleQuoteConstant;
InitFields();
onoff_supmode_add();
onoff_bigendian_add();
if (!onoff_test_and_set(e_onoff_reg_custom))
SetFlag(&CustomAvail, CustomAvailSymName, False);
AddONOFF(CustomAvailCmdName, &CustomAvail, CustomAvailSymName, False);
}
/*!------------------------------------------------------------------------
* \fn codens32000_init(void)
* \brief register target to AS
* ------------------------------------------------------------------------ */
static const tCPUProps CPUProps[] =
{
{ "NS16008", eCoreGen1 , eFPU16081, ePMMU16082, UInt24 },
{ "NS32008", eCoreGen1 , eFPU32081, ePMMU32082, UInt24 },
{ "NS08032", eCoreGen1 , eFPU32081, ePMMU32082, UInt24 },
{ "NS16032", eCoreGen1 , eFPU16081, ePMMU16082, UInt24 },
{ "NS32016", eCoreGen1 , eFPU32081, ePMMU32082, UInt24 },
{ "NS32032", eCoreGen1 , eFPU32081, ePMMU32082, UInt24 },
{ "NS32332", eCoreGen1Ext, eFPU32381, ePMMU32382, UInt32 },
{ "NS32CG16",eCoreGenE , eFPU32181, ePMMU32082, UInt24 },
{ "NS32532", eCoreGen2 , eFPU32381, ePMMU32532, UInt32 },
{ NULL , eCoreNone , eFPUNone , ePMMUNone , UInt1 }
};
void codens32k_init(void)
{
const tCPUProps *pRun;
for (pRun = CPUProps; pRun->pName; pRun++)
(void)AddCPUUser(pRun->pName, SwitchTo_NS32K, (void*)pRun, NULL);
AddInitPassProc(InitCode_NS32K);
}