/* codexcore.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* Codegenerator XCore */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <ctype.h>
#include <string.h>
#include "nls.h"
#include "be_le.h"
#include "strutil.h"
#include "bpemu.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmallg.h"
#include "headids.h"
#include "codepseudo.h"
#include "intpseudo.h"
#include "asmitree.h"
#include "codevars.h"
#include "errmsg.h"
#include "codexcore.h"
/*--------------------------------------------------------------------------*/
/* Types */
typedef struct
{
Word Opcode1, Opcode2;
} lr2r_Order;
/*--------------------------------------------------------------------------*/
/* Variables */
static CPUVar CPUXS1;
static lr2r_Order *lr2r_Orders;
/*--------------------------------------------------------------------------*/
/* Common Decoder Subroutines */
static unsigned UpVal(unsigned Val1, unsigned Val3, unsigned Val9, unsigned Val27)
{
return (((Val1 >> 2) & 3) * 1)
+ (((Val3 >> 2) & 3) * 3)
+ (((Val9 >> 2) & 3) * 9)
+ (((Val27 >> 2) & 3) * 27);
}
/*!------------------------------------------------------------------------
* \fn ParseReg(const char *pArg, unsigned *pResult)
* \brief check whether argument is a CPU register
* \param pArg argument
* \param pResult register number if yes
* \return True if yes
* ------------------------------------------------------------------------ */
static Boolean ParseReg(const char *pArg, unsigned *pResult)
{
char *pEnd;
if ((strlen(pArg
) < 2) || (as_toupper
(*pArg
) != 'R'))
return False;
*pResult
= strtoul(pArg
+ 1, &pEnd
, 10);
return (!*pEnd && (*pResult <= 11));
}
/*!------------------------------------------------------------------------
* \fn DissectReg_XCore(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
* \brief dissect register symbols - XCORE variant
* \param pDest destination buffer
* \param DestSize destination buffer size
* \param Value numeric register value
* \param InpSize register size
* ------------------------------------------------------------------------ */
static void DissectReg_XCore(char *pDest, size_t DestSize, tRegInt Value, tSymbolSize InpSize)
{
switch (InpSize)
{
case eSymbolSize8Bit:
as_snprintf(pDest, DestSize, "R%u", (unsigned)Value);
break;
default:
as_snprintf(pDest, DestSize, "%d-%u", (int)InpSize, (unsigned)Value);
}
}
/*!------------------------------------------------------------------------
* \fn ParseArgReg(int Index, unsigned *pResult, Boolean MustBeReg)
* \brief check whether argument is a CPU register or register alias
* \param Index index of argument
* \param register number if yes
* \param MustBeReg expecting register as argument
* \return register eval result
* ------------------------------------------------------------------------ */
static tRegEvalResult ParseArgReg(int Index, unsigned *pResult, Boolean MustBeReg)
{
tRegDescr RegDescr;
tEvalResult EvalResult;
tRegEvalResult RegEvalResult;
if (ParseReg(ArgStr[Index].str.p_str, pResult))
return eIsReg;
RegEvalResult = EvalStrRegExpressionAsOperand(&ArgStr[Index], &RegDescr, &EvalResult, eSymbolSize8Bit, MustBeReg);
*pResult = RegDescr.Reg;
return RegEvalResult;
}
/*--------------------------------------------------------------------------*/
/* Instruction Decoders */
static void Code_3r(Word Index)
{
unsigned Op1, Op2, Op3;
if (ChkArgCnt(3, 3)
&& ParseArgReg(1, &Op1, True)
&& ParseArgReg(2, &Op2, True)
&& ParseArgReg(3, &Op3, True))
{
WAsmCode[0] = Index
| ((Op3 & 3) << 0)
| ((Op2 & 3) << 2)
| ((Op1 & 3) << 4)
| (UpVal(Op3, Op2, Op1, 0) << 6);
CodeLen = 2;
}
}
static void Code_2rus(Word Index)
{
unsigned Op1, Op2, Op3;
Boolean OK;
if (ChkArgCnt(3, 3)
&& ParseArgReg(1, &Op1, True)
&& ParseArgReg(2, &Op2, True))
{
tSymbolFlags Flags;
Op3 = EvalStrIntExpressionWithFlags(&ArgStr[3], UInt4, &OK, &Flags);
if (mFirstPassUnknown(Flags))
Op3 &= 7;
if (OK)
{
if (Op3 > 11) WrStrErrorPos(ErrNum_OverRange, &ArgStr[3]);
else
{
WAsmCode[0] = Index
| ((Op3 & 3) << 0)
| ((Op2 & 3) << 2)
| ((Op1 & 3) << 4)
| (UpVal(Op3, Op2, Op1, 0) << 6);
CodeLen = 2;
}
}
}
}
static void Code_2r(Word Index)
{
unsigned Op1, Op2;
if (ChkArgCnt(2, 2)
&& ParseArgReg(1, &Op1, True)
&& ParseArgReg(2, &Op2, True))
{
unsigned Up = UpVal(Op2, Op1, 0, 0) + 27;
WAsmCode[0] = Index
| ((Op2 & 3) << 0)
| ((Op1 & 3) << 2)
| ((Up & 0x1f) << 6)
| (Up & 0x20);
CodeLen = 2;
}
}
static void Code_l3r(Word Index)
{
unsigned Op1, Op2, Op3;
if (ChkArgCnt(3, 3)
&& ParseArgReg(1, &Op1, True)
&& ParseArgReg(2, &Op2, True)
&& ParseArgReg(3, &Op3, True))
{
WAsmCode[0] = 0xf800
| ((Op3 & 3) << 0)
| ((Op2 & 3) << 2)
| ((Op1 & 3) << 4)
| (UpVal(Op3, Op2, Op1, 0) << 6);
WAsmCode[1] = Index;
CodeLen = 4;
}
}
static void Code_l2rus(Word Index)
{
unsigned Op1, Op2, Op3;
Boolean OK;
if (ChkArgCnt(3, 3)
&& ParseArgReg(1, &Op1, True)
&& ParseArgReg(2, &Op2, True))
{
tSymbolFlags Flags;
Op3 = EvalStrIntExpressionWithFlags(&ArgStr[3], UInt4, &OK, &Flags);
if (mFirstPassUnknown(Flags))
Op3 &= 7;
if (OK)
{
if (Op3 > 11) WrStrErrorPos(ErrNum_OverRange, &ArgStr[3]);
else
{
WAsmCode[0] = 0xf800
| ((Op3 & 3) << 0)
| ((Op2 & 3) << 2)
| ((Op1 & 3) << 4)
| (UpVal(Op3, Op2, Op1, 0) << 6);
WAsmCode[1] = Index;
CodeLen = 4;
}
}
}
}
static void Code_1r(Word Index)
{
unsigned Op1;
if (ChkArgCnt(1, 1) && ParseArgReg(1, &Op1, True))
{
WAsmCode[0] = Index | Op1;
CodeLen = 2;
}
}
static void Code_l2r(Word Index)
{
unsigned Op1, Op2;
if (ChkArgCnt(2, 2)
&& ParseArgReg(1, &Op1, True)
&& ParseArgReg(2, &Op2, True))
{
unsigned Up = UpVal(Op2, Op1, 0, 0) + 27;
WAsmCode[0] = 0xf800 | ((Index & 1) << 4)
| ((Op2 & 3) << 0)
| ((Op1 & 3) << 2)
| ((Up & 0x1f) << 6)
| (Up & 0x20);
WAsmCode[1] = Index & (~1);
CodeLen = 4;
}
}
static void Code_u10(Word Index)
{
if (ChkArgCnt(1, 1))
{
LongWord Op1;
Boolean OK;
Op1 = EvalStrIntExpression(&ArgStr[1], UInt20, &OK);
if (OK)
{
if (Op1 > 0x3ff)
{
WAsmCode[CodeLen >> 1] = 0xf000 | ((Op1 >> 10) & 0x3ff);
CodeLen += 2;
}
WAsmCode[CodeLen >> 1] = Index | (Op1 & 0x3ff);
CodeLen += 2;
}
}
}
static void Code_u6(Word Index)
{
if (!ChkArgCnt(1, 1));
else
{
LongWord Op1;
Boolean OK;
Op1 = EvalStrIntExpression(&ArgStr[1], UInt16, &OK);
if (OK)
{
if (Op1 > 0x3f)
{
WAsmCode[CodeLen >> 1] = 0xf000 | ((Op1 >> 6) & 0x3ff);
CodeLen += 2;
}
WAsmCode[CodeLen >> 1] = Index | (Op1 & 0x3f);
CodeLen += 2;
}
}
}
static void Code_ru6(Word Index)
{
unsigned Op1;
if (ChkArgCnt(2, 2) && ParseArgReg(1, &Op1, True))
{
LongWord Op2;
Boolean OK;
Op2 = EvalStrIntExpression(&ArgStr[2], UInt16, &OK);
if (OK)
{
if (Op2 > 0x3f)
{
WAsmCode[CodeLen >> 1] = 0xf000 | ((Op2 >> 6) & 0x3ff);
CodeLen += 2;
}
WAsmCode[CodeLen >> 1] = Index | (Op1 << 6) | (Op2 & 0x3f);
CodeLen += 2;
}
}
}
static void Code_rus(Word Index)
{
unsigned Op1;
if (ChkArgCnt(2, 2) && ParseArgReg(1, &Op1, True))
{
unsigned Op2;
Boolean OK;
tSymbolFlags Flags;
Op2 = EvalStrIntExpressionWithFlags(&ArgStr[2], UInt4, &OK, &Flags);
if (mFirstPassUnknown(Flags))
Op2 &= 7;
if (OK)
{
if (Op2 > 11) WrStrErrorPos(ErrNum_OverRange, &ArgStr[2]);
else
{
unsigned Up = UpVal(Op2, Op1, 0, 0) + 27;
WAsmCode[0] = Index
| ((Op2 & 3) << 0)
| ((Op1 & 3) << 2)
| ((Up & 0x1f) << 6)
| (Up & 0x20);
CodeLen = 2;
}
}
}
}
static void Code_0r(Word Index)
{
if (ChkArgCnt(0, 0))
{
WAsmCode[0] = Index;
CodeLen = 2;
}
}
static void Code_l4r(Word Index)
{
unsigned Op1, Op2, Op3, Op4;
if (ChkArgCnt(4, 4)
&& ParseArgReg(1, &Op1, True)
&& ParseArgReg(2, &Op2, True)
&& ParseArgReg(3, &Op3, True)
&& ParseArgReg(4, &Op4, True))
{
WAsmCode[0] = 0xf800
| ((Op3 & 3) << 0)
| ((Op2 & 3) << 2)
| ((Op1 & 3) << 4)
| (UpVal(Op3, Op2, Op1, 0) << 6);
WAsmCode[1] = Index | Op4;
CodeLen = 4;
}
}
static void Code_l5r(Word Index)
{
unsigned Op1, Op2, Op3, Op4, Op5;
if (ChkArgCnt(5, 5)
&& ParseArgReg(1, &Op1, True)
&& ParseArgReg(2, &Op4, True)
&& ParseArgReg(3, &Op2, True)
&& ParseArgReg(4, &Op3, True)
&& ParseArgReg(5, &Op5, True))
{
unsigned Up = UpVal(Op5, Op4, 0, 0) + 27;
WAsmCode[0] = 0xf800
| ((Op3 & 3) << 0)
| ((Op2 & 3) << 2)
| ((Op1 & 3) << 4)
| (UpVal(Op3, Op2, Op1, 0) << 6);
WAsmCode[1] = Index
| ((Op5 & 3) << 0)
| ((Op4 & 3) << 2)
| ((Up & 0x1f) << 6)
| (Up & 0x20);
CodeLen = 4;
}
}
static void Code_l6r(Word Index)
{
unsigned Op1, Op2, Op3, Op4, Op5, Op6;
if (ChkArgCnt(6, 6)
&& ParseArgReg(1, &Op1, True)
&& ParseArgReg(2, &Op4, True)
&& ParseArgReg(3, &Op2, True)
&& ParseArgReg(4, &Op3, True)
&& ParseArgReg(5, &Op5, True)
&& ParseArgReg(6, &Op6, True))
{
WAsmCode[0] = 0xf800
| ((Op3 & 3) << 0)
| ((Op2 & 3) << 2)
| ((Op1 & 3) << 4)
| (UpVal(Op3, Op2, Op1, 0) << 6);
WAsmCode[1] = Index
| ((Op6 & 3) << 0)
| ((Op5 & 3) << 2)
| ((Op4 & 3) << 4)
| (UpVal(Op6, Op5, Op4, 0) << 6);
CodeLen = 4;
}
}
static void Code_branch_core(Word Code, int DistArgIndex)
{
LongInt Delta;
Boolean OK;
tSymbolFlags Flags;
/* assume short branch for distance computation */
Delta = EvalStrIntExpressionWithFlags(&ArgStr[DistArgIndex], UInt32, &OK, &Flags) - (EProgCounter() + 2);
if (mFirstPassUnknown(Flags))
Delta &= 0x1fffe;
/* distance must be even */
if (Delta & 1) WrError(ErrNum_NotAligned);
/* short branch possible? */
else if ((Delta >= -126) && (Delta <= 126))
{
Delta /= 2;
WAsmCode[0] = Code;
if (Delta < 0)
{
WAsmCode[0] |= 0x0400;
Delta = -Delta;
}
WAsmCode[0] |= Delta & 0x3f;
CodeLen = 2;
}
/* must use long: */
else
{
/* correct delta for longer instruction */
Delta -= 2;
if ((Delta < -131070) || (Delta >= 131070)) WrError(ErrNum_JmpDistTooBig);
else
{
Delta /= 2;
WAsmCode[1] = Code;
if (Delta < 0)
{
WAsmCode[1] |= 0x0400;
Delta = -Delta;
}
WAsmCode[1] |= Delta & 0x3f;
WAsmCode[0] = 0xf00 | ((Delta >> 6) & 0x3ff);
CodeLen = 4;
}
}
}
static void Code_BRU(Word Index)
{
unsigned Op1;
UNUSED(Index);
if (ChkArgCnt(1, 1))
{
switch (ParseArgReg(1, &Op1, False))
{
case eIsReg:
WAsmCode[0] = 0x2fe0 | Op1;
CodeLen = 2;
break;
case eIsNoReg:
Code_branch_core(0x7300, 1);
break;
case eRegAbort:
break;
}
}
}
static void Code_cbranch(Word Index)
{
unsigned Op1;
if (ChkArgCnt(2, 2) && ParseArgReg(1, &Op1, True))
Code_branch_core(Index | (Op1 << 6), 2);
}
static void Code_r2r(Word Index)
{
unsigned Op1, Op2;
if (ChkArgCnt(2, 2)
&& ParseArgReg(1, &Op1, True)
&& ParseArgReg(2, &Op2, True))
{
unsigned Up = UpVal(Op1, Op2, 0, 0) + 27;
WAsmCode[0] = Index
| ((Op1 & 3) << 0)
| ((Op2 & 3) << 2)
| ((Up & 0x1f) << 6)
| (Up & 0x20);
CodeLen = 2;
}
}
static void Code_lr2r(Word Index)
{
unsigned Op1, Op2;
lr2r_Order *pOrder = lr2r_Orders + Index;
if (ChkArgCnt(2, 2)
&& ParseArgReg(1, &Op1, True)
&& ParseArgReg(2, &Op2, True))
{
unsigned Up = UpVal(Op1, Op2, 0, 0) + 27;
WAsmCode[0] = pOrder->Opcode1
| ((Op1 & 3) << 0)
| ((Op2 & 3) << 2)
| ((Up & 0x1f) << 6)
| (Up & 0x20);
WAsmCode[1] = pOrder->Opcode2;
CodeLen = 4;
}
}
/*--------------------------------------------------------------------------*/
/* Dynamic Code Table Handling */
static void Add_lr2r(const char *NName, Word NCode1, Word NCode2)
{
order_array_rsv_end(lr2r_Orders, lr2r_Order);
lr2r_Orders[InstrZ].Opcode1 = NCode1;
lr2r_Orders[InstrZ].Opcode2 = NCode2;
AddInstTable(InstTable, NName, InstrZ++, Code_lr2r);
}
static void InitFields(void)
{
InstTable = CreateInstTable(207);
AddInstTable(InstTable, "REG", 0, CodeREG);
AddInstTable(InstTable, "ADD" , 0x1000, Code_3r);
AddInstTable(InstTable, "AND" , 0x3800, Code_3r);
AddInstTable(InstTable, "EQ" , 0x3000, Code_3r);
AddInstTable(InstTable, "LD16S" , 0x8000, Code_3r);
AddInstTable(InstTable, "LD8U" , 0x8800, Code_3r);
AddInstTable(InstTable, "LDW" , 0x4800, Code_3r);
AddInstTable(InstTable, "LSS" , 0xc000, Code_3r);
AddInstTable(InstTable, "LSU" , 0xc800, Code_3r);
AddInstTable(InstTable, "OR" , 0x4000, Code_3r);
AddInstTable(InstTable, "SHL" , 0x2000, Code_3r);
AddInstTable(InstTable, "SHR" , 0x2800, Code_3r);
AddInstTable(InstTable, "SUB" , 0x1800, Code_3r);
AddInstTable(InstTable, "TSETR" , 0xb800, Code_3r);
AddInstTable(InstTable, "ADDI" , 0x9000, Code_2rus);
AddInstTable(InstTable, "EQI" , 0xb000, Code_2rus);
AddInstTable(InstTable, "LDWI" , 0x0800, Code_2rus);
AddInstTable(InstTable, "SHLI" , 0xa000, Code_2rus);
AddInstTable(InstTable, "SHRI" , 0xa800, Code_2rus);
AddInstTable(InstTable, "STWI" , 0x0000, Code_2rus);
AddInstTable(InstTable, "SUBI" , 0x9800, Code_2rus);
AddInstTable(InstTable, "ANDNOT" , 0x2800, Code_2r);
AddInstTable(InstTable, "CHKCT" , 0xc800, Code_2r);
AddInstTable(InstTable, "EEF" , 0x2810, Code_2r);
AddInstTable(InstTable, "EET" , 0x2010, Code_2r);
AddInstTable(InstTable, "ENDIN" , 0x9010, Code_2r);
AddInstTable(InstTable, "GETST" , 0x0010, Code_2r);
AddInstTable(InstTable, "GETTS" , 0x3800, Code_2r);
AddInstTable(InstTable, "IN" , 0xb000, Code_2r);
AddInstTable(InstTable, "INCT" , 0x8010, Code_2r);
AddInstTable(InstTable, "INSHR" , 0xb010, Code_2r);
AddInstTable(InstTable, "INT" , 0x8810, Code_2r);
AddInstTable(InstTable, "MKMSK" , 0xa000, Code_2r);
AddInstTable(InstTable, "NEG" , 0x9000, Code_2r);
AddInstTable(InstTable, "NOT" , 0x8800, Code_2r);
AddInstTable(InstTable, "OUTCT" , 0x4800, Code_2r);
AddInstTable(InstTable, "PEEK" , 0xb800, Code_2r);
AddInstTable(InstTable, "SEXT" , 0x3000, Code_2r);
AddInstTable(InstTable, "TESTCT" , 0xb810, Code_2r);
AddInstTable(InstTable, "TESTWCT", 0xc010, Code_2r);
AddInstTable(InstTable, "TINITCP", 0x1800, Code_2r);
AddInstTable(InstTable, "TINITDP", 0x0800, Code_2r);
AddInstTable(InstTable, "TINITPC", 0x0000, Code_2r);
AddInstTable(InstTable, "TINITSP", 0x1000, Code_2r);
AddInstTable(InstTable, "TSETMR" , 0x1810, Code_2r);
AddInstTable(InstTable, "ZEXT" , 0x4000, Code_2r);
AddInstTable(InstTable, "ASHR" , 0x17ec, Code_l3r);
AddInstTable(InstTable, "LDA16F" , 0x2fec, Code_l3r);
AddInstTable(InstTable, "REMU" , 0xcfec, Code_l3r);
AddInstTable(InstTable, "CRC" , 0xafec, Code_l3r);
AddInstTable(InstTable, "LDAWB" , 0x27ec, Code_l3r);
AddInstTable(InstTable, "ST16" , 0x87ec, Code_l3r);
AddInstTable(InstTable, "DIVS" , 0x47ec, Code_l3r);
AddInstTable(InstTable, "LDAWF" , 0x1fec, Code_l3r);
AddInstTable(InstTable, "ST8" , 0x8fec, Code_l3r);
AddInstTable(InstTable, "DIVU" , 0x4fec, Code_l3r);
AddInstTable(InstTable, "MUL" , 0x3fec, Code_l3r);
AddInstTable(InstTable, "STW" , 0x07ec, Code_l3r);
AddInstTable(InstTable, "LDA16B" , 0x37ec, Code_l3r);
AddInstTable(InstTable, "REMS" , 0xc7ec, Code_l3r);
AddInstTable(InstTable, "XOR" , 0x0fec, Code_l3r);
AddInstTable(InstTable, "ASHRI" , 0x97ec, Code_l2rus);
AddInstTable(InstTable, "LDAWBI" , 0xa7ec, Code_l2rus);
AddInstTable(InstTable, "OUTPW" , 0x97ed, Code_l2rus);
AddInstTable(InstTable, "INPW" , 0x97ee, Code_l2rus);
AddInstTable(InstTable, "LDAWFI" , 0x9fec, Code_l2rus);
AddInstTable(InstTable, "BAU" , 0x27f0, Code_1r);
AddInstTable(InstTable, "EEU" , 0x07f0, Code_1r);
AddInstTable(InstTable, "SETSP" , 0x2ff0, Code_1r);
AddInstTable(InstTable, "BLA" , 0x27e0, Code_1r);
AddInstTable(InstTable, "FREER" , 0x17e0, Code_1r);
AddInstTable(InstTable, "SETV" , 0x47f0, Code_1r);
AddInstTable(InstTable, "KCALL" , 0x27e0, Code_1r);
AddInstTable(InstTable, "SYNCR" , 0x87f0, Code_1r);
AddInstTable(InstTable, "CLRPT" , 0x87e0, Code_1r);
AddInstTable(InstTable, "MJOIN" , 0x17f0, Code_1r);
AddInstTable(InstTable, "TSTART" , 0x1fe0, Code_1r);
AddInstTable(InstTable, "DGETREG", 0x3fe0, Code_1r);
AddInstTable(InstTable, "MSYNC" , 0x1ff0, Code_1r);
AddInstTable(InstTable, "WAITEF" , 0x0ff0, Code_1r);
AddInstTable(InstTable, "ECALLF" , 0x4fe0, Code_1r);
AddInstTable(InstTable, "SETCP" , 0x37f0, Code_1r);
AddInstTable(InstTable, "WAITET" , 0x0fe0, Code_1r);
AddInstTable(InstTable, "ECALLT" , 0x4ff0, Code_1r);
AddInstTable(InstTable, "SETDP" , 0x37e0, Code_1r);
AddInstTable(InstTable, "EDU" , 0x07e0, Code_1r);
AddInstTable(InstTable, "SETEV" , 0x3ff0, Code_1r);
AddInstTable(InstTable, "BITREV" , 0x07ec | 0, Code_l2r);
AddInstTable(InstTable, "GETD" , 0x1fec | 1, Code_l2r);
AddInstTable(InstTable, "SETC" , 0x2fec | 1, Code_l2r);
AddInstTable(InstTable, "BYTEREV", 0x07ec | 1, Code_l2r);
AddInstTable(InstTable, "GETN" , 0x37ec | 1, Code_l2r);
AddInstTable(InstTable, "TESTLCL", 0x27ec | 0, Code_l2r);
AddInstTable(InstTable, "CLZ" , 0x0fec | 0, Code_l2r);
AddInstTable(InstTable, "GETPS" , 0x17ec | 1, Code_l2r);
AddInstTable(InstTable, "TINITLR", 0x17ec | 1, Code_l2r);
AddInstTable(InstTable, "BLACP" , 0xe000, Code_u10);
AddInstTable(InstTable, "BLRF" , 0xd000, Code_u10);
AddInstTable(InstTable, "LDAPF" , 0xd800, Code_u10);
AddInstTable(InstTable, "BLRB" , 0xd400, Code_u10);
AddInstTable(InstTable, "LDAPB" , 0xdc00, Code_u10);
AddInstTable(InstTable, "LDWCPL" , 0xe400, Code_u10);
AddInstTable(InstTable, "BLAT" , 0x7340, Code_u6);
AddInstTable(InstTable, "EXTDP" , 0x7380, Code_u6);
AddInstTable(InstTable, "KRESTSP", 0x7bc0, Code_u6);
AddInstTable(InstTable, "BRBU" , 0x7700, Code_u6);
AddInstTable(InstTable, "EXTSP" , 0x7780, Code_u6);
AddInstTable(InstTable, "LDAWCP" , 0x7f40, Code_u6);
AddInstTable(InstTable, "BRFU" , 0x7300, Code_u6);
AddInstTable(InstTable, "GETSR" , 0x7f00, Code_u6);
AddInstTable(InstTable, "RETSP" , 0x77c0, Code_u6);
AddInstTable(InstTable, "CLRSR" , 0x7b00, Code_u6);
AddInstTable(InstTable, "KCALLI" , 0x73c0, Code_u6);
AddInstTable(InstTable, "SETSR" , 0x7b40, Code_u6);
AddInstTable(InstTable, "ENTSP" , 0x7740, Code_u6);
AddInstTable(InstTable, "KENTSP" , 0x7b80, Code_u6);
AddInstTable(InstTable, "BRBF" , 0x7c00, Code_ru6);
AddInstTable(InstTable, "LDAWSP" , 0x6400, Code_ru6);
AddInstTable(InstTable, "SETCI" , 0xe800, Code_ru6);
AddInstTable(InstTable, "BRBT" , 0x7400, Code_ru6);
AddInstTable(InstTable, "LDC" , 0x6800, Code_ru6);
AddInstTable(InstTable, "STWDP" , 0x5000, Code_ru6);
AddInstTable(InstTable, "BRFF" , 0x7800, Code_ru6);
AddInstTable(InstTable, "LDWCP" , 0x6c00, Code_ru6);
AddInstTable(InstTable, "STWSP" , 0x5400, Code_ru6);
AddInstTable(InstTable, "BRFT" , 0x7000, Code_ru6);
AddInstTable(InstTable, "LDWDP" , 0x5800, Code_ru6);
AddInstTable(InstTable, "LDAWDP" , 0x6000, Code_ru6);
AddInstTable(InstTable, "LDWSP" , 0x5c00, Code_ru6);
AddInstTable(InstTable, "CHKCTI" , 0xc810, Code_rus);
AddInstTable(InstTable, "MKMSKI" , 0xa010, Code_rus);
AddInstTable(InstTable, "SEXTI" , 0x3010, Code_rus);
AddInstTable(InstTable, "GETR" , 0x8000, Code_rus);
AddInstTable(InstTable, "OUTCTI" , 0x4810, Code_rus);
AddInstTable(InstTable, "ZEXTI" , 0x4010, Code_rus);
AddInstTable(InstTable, "CLRE" , 0x07ed, Code_0r);
AddInstTable(InstTable, "GETID" , 0x17ee, Code_0r);
AddInstTable(InstTable, "SETKEP" , 0x07ff, Code_0r);
AddInstTable(InstTable, "DCALL" , 0x07fc, Code_0r);
AddInstTable(InstTable, "GETKEP" , 0x17ef, Code_0r);
AddInstTable(InstTable, "SSYNC" , 0x07ee, Code_0r);
AddInstTable(InstTable, "DENTSP" , 0x17ec, Code_0r);
AddInstTable(InstTable, "GETKSP" , 0x17fc, Code_0r);
AddInstTable(InstTable, "STET" , 0x0ffd, Code_0r);
AddInstTable(InstTable, "DRESTSP", 0x17ed, Code_0r);
AddInstTable(InstTable, "KRET" , 0x07fd, Code_0r);
AddInstTable(InstTable, "STSED" , 0x0ffc, Code_0r);
AddInstTable(InstTable, "DRET" , 0x07fe, Code_0r);
AddInstTable(InstTable, "LDET" , 0x17fe, Code_0r);
AddInstTable(InstTable, "STSPC" , 0x0fed, Code_0r);
AddInstTable(InstTable, "FREET" , 0x07ef, Code_0r);
AddInstTable(InstTable, "LDSED" , 0x17fd, Code_0r);
AddInstTable(InstTable, "STSSR" , 0x0fef, Code_0r);
AddInstTable(InstTable, "GETED" , 0x0ffe, Code_0r);
AddInstTable(InstTable, "LDSPC" , 0x0fec, Code_0r);
AddInstTable(InstTable, "WAITEU" , 0x07ec, Code_0r);
AddInstTable(InstTable, "GETET" , 0x0fff, Code_0r);
AddInstTable(InstTable, "LDSSR" , 0x0fee, Code_0r);
AddInstTable(InstTable, "CRC8" , 0x07e0, Code_l4r);
AddInstTable(InstTable, "MACCS" , 0x0fe0, Code_l4r);
AddInstTable(InstTable, "MACCU" , 0x07f0, Code_l4r);
AddInstTable(InstTable, "LADD" , 0x0010, Code_l5r);
AddInstTable(InstTable, "LDIVU" , 0x0000, Code_l5r);
AddInstTable(InstTable, "LSUB" , 0x0100, Code_l5r);
AddInstTable(InstTable, "LMUL" , 0x0000, Code_l6r);
AddInstTable(InstTable, "OUT" , 0xa800, Code_r2r);
AddInstTable(InstTable, "OUTT" , 0x0810, Code_r2r);
AddInstTable(InstTable, "SETPSC" , 0xc000, Code_r2r);
AddInstTable(InstTable, "OUTSHR" , 0xa810, Code_r2r);
AddInstTable(InstTable, "SETD" , 0x1010, Code_r2r);
AddInstTable(InstTable, "SETPT" , 0x3810, Code_r2r);
InstrZ = 0;
Add_lr2r("SETCLK" , 0xf810, 0x0fec);
Add_lr2r("SETPS" , 0xf800, 0x1fec);
Add_lr2r("SETTW" , 0xf810, 0x27ec);
Add_lr2r("SETN" , 0xf800, 0x37ec);
Add_lr2r("SETRDY" , 0xf800, 0x2fec);
AddInstTable(InstTable, "BRU" , 0x7300, Code_BRU);
AddInstTable(InstTable, "BRF" , 0x7800, Code_cbranch);
AddInstTable(InstTable, "BRT" , 0x7000, Code_cbranch);
}
static void DeinitFields(void)
{
DestroyInstTable(InstTable);
order_array_free(lr2r_Orders);
}
/*--------------------------------------------------------------------------*/
/* Callbacks */
static void MakeCode_XCore(void)
{
CodeLen = 0;
DontPrint = False;
/* Null Instruction */
if ((*OpPart.str.p_str == '\0') && (ArgCnt == 0))
return;
/* Pseudo Instructions */
if (DecodeIntelPseudo(True))
return;
/* Odd Program Counter ? */
if (Odd(EProgCounter())) WrError(ErrNum_AddrNotAligned);
/* everything from hash table */
if (!LookupInstTable(InstTable, OpPart.str.p_str))
WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
}
/*!------------------------------------------------------------------------
* \fn InternSymbol_XCore(char *pArg, TempResult *pResult)
* \brief handle built-in (register) symbols for XCORE
* \param pArg source argument
* \param pResult result buffer
* ------------------------------------------------------------------------ */
static void InternSymbol_XCore(char *pArg, TempResult *pResult)
{
unsigned RegNum;
if (ParseReg(pArg, &RegNum))
{
pResult->Typ = TempReg;
pResult->DataSize = eSymbolSize8Bit;
pResult->Contents.RegDescr.Reg = RegNum;
pResult->Contents.RegDescr.Dissect = DissectReg_XCore;
pResult->Contents.RegDescr.compare = NULL;
}
}
static Boolean IsDef_XCore(void)
{
return Memo("REG");
}
static void SwitchFrom_XCore(void)
{
DeinitFields();
}
static void SwitchTo_XCore(void)
{
const TFamilyDescr *pDescr;
TurnWords = False;
SetIntConstMode(eIntConstModeMoto);
pDescr = FindFamilyByName("XCore");
PCSymbol = "$"; HeaderID = pDescr->Id; NOPCode = 0x0000;
DivideChars = ","; HasAttrs = False;
ValidSegs = (1 << SegCode);
Grans[SegCode] = 1; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
SegLimits[SegCode] = 0xffffffffl;
MakeCode = MakeCode_XCore;
InternSymbol = InternSymbol_XCore;
DissectReg = DissectReg_XCore;
IsDef = IsDef_XCore;
SwitchFrom = SwitchFrom_XCore; InitFields();
}
/*--------------------------------------------------------------------------*/
/* Initialisation */
void codexcore_init(void)
{
CPUXS1 = AddCPU("XS1", SwitchTo_XCore);
}