/* code3206x.c */
/*****************************************************************************/
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* */
/* AS-Portierung */
/* */
/* Codegenerator TMS320C6x */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <string.h>
#include <ctype.h>
#include "be_le.h"
#include "strutil.h"
#include "bpemu.h"
#include "nls.h"
#include "asmdef.h"
#include "asmsub.h"
#include "asmpars.h"
#include "asmcode.h"
#include "errmsg.h"
#include "ieeefloat.h"
#include "codepseudo.h"
#include "asmitree.h"
#include "codevars.h"
#include "onoff_common.h"
#include "nlmessages.h"
#include "chartrans.h"
#include "as.rsc"
/*---------------------------------------------------------------------------*/
typedef enum
{
NoUnit
, L1
, L2
, S1
, S2
, M1
, M2
, D1
, D2
, LastUnit
, UnitCnt
} TUnit
;
#ifdef __cplusplus
# include "code3206x.hpp"
#endif
typedef struct
{
LongInt OpCode
;
LongInt SrcMask
, SrcMask2
, DestMask
;
Byte CrossUsed
; /* Bit 0 -->X1 benutzt, Bit 1 -->X2 benutzt */
Byte AddrUsed
; /* Bit 0 -->Addr1 benutzt, Bit 1 -->Addr2 benutzt
Bit 2 -->LdSt1 benutzt, Bit 3 -->LdSt2 benutzt */
Byte LongUsed
; /* Bit 0 -->lange Quelle, Bit 1-->langes Ziel */
Boolean AbsBranch
;
Boolean StoreUsed
, LongSrc
, LongDest
;
TUnit U
;
} InstrRec
;
typedef struct
{
LongInt Code
;
} FixedOrder
;
typedef struct
{
LongInt Code
;
Boolean WithImm
;
} CmpOrder
;
typedef struct
{
LongInt Code
;
LongInt Scale
;
} MemOrder
;
typedef struct
{
LongInt Code
;
Boolean DSign
,SSign1
,SSign2
;
Boolean MayImm
;
} MulOrder
;
typedef struct
{
const char *Name
;
LongInt Code
;
Boolean Rd
,Wr
;
} CtrlReg
;
static const char UnitNames
[UnitCnt
][3] =
{
" ", "L1", "L2", "S1", "S2", "M1", "M2", "D1", "D2", " "
};
#define MaxParCnt 8
#define FirstUnit L1
enum
{
ModNone
= -1,
ModReg
= 0,
ModLReg
= 1,
ModImm
= 2
};
#define MModReg (1 << ModReg)
#define MModLReg (1 << ModLReg)
#define MModImm (1 << ModImm)
static ShortInt AdrMode
;
static CPUVar CPU32060
;
static Boolean ThisPar
, ThisCross
, ThisStore
, ThisAbsBranch
;
static Byte ThisAddr
, ThisLong
;
static LongInt ThisSrc
, ThisSrc2
, ThisDest
;
static LongInt Condition
;
static TUnit ThisUnit
;
static LongWord UnitFlag
, ThisInst
;
static Integer ParCnt
;
static LongWord PacketAddr
;
static InstrRec
*ParRecs
;
static FixedOrder
*LinAddOrders
;
static CmpOrder
*CmpOrders
;
static MemOrder
*MemOrders
;
static MulOrder
*MulOrders
;
static CtrlReg
*CtrlRegs
;
/*-------------------------------------------------------------------------*/
static Boolean CheckOpt
(char *Asc
)
{
Boolean Flag
, erg
= True
;
int l
= strlen(Asc
);
if (!strcmp(Asc
, "||"))
ThisPar
= True
;
else if ((*Asc
== '[') && (Asc
[l
- 1] == ']'))
{
Asc
++;
Asc
[l
- 2] = '\0';
l
-= 2;
if (*Asc
== '!')
{
Asc
++;
l
--;
Condition
= 1;
}
else
Condition
= 0;
Flag
= True
;
if (l
!= 2)
Flag
= False
;
else if (as_toupper
(*Asc
) == 'A')
{
if ((Asc
[1] >= '1') && (Asc
[1] <= '2'))
Condition
+= (Asc
[1] - '0' + 3) << 1;
else
Flag
= False
;
}
else if (as_toupper
(*Asc
) == 'B')
{
if ((Asc
[1] >= '0') && (Asc
[1] <= '2'))
Condition
+= (Asc
[1] - '0' + 1) << 1;
else
Flag
= False
;
}
if (!Flag
)
WrXError
(ErrNum_InvReg
, Asc
);
erg
= Flag
;
}
else
erg
= False
;
return erg
;
}
static Boolean ReiterateOpPart
(void)
{
char *p
;
int z
;
if (!CheckOpt
(OpPart.
str.
p_str))
return False
;
if (ArgCnt
<1)
{
WrError
(ErrNum_WrongArgCnt
);
return False
;
}
p
= FirstBlank
(ArgStr
[1].
str.
p_str);
if (!p
)
{
StrCompCopy
(&OpPart
, &ArgStr
[1]);
for (z
= 2; z
<= ArgCnt
; z
++)
StrCompCopy
(&ArgStr
[z
- 1], &ArgStr
[z
]);
ArgCnt
--;
}
else
{
StrCompSplitLeft
(&ArgStr
[1], &OpPart
, p
);
KillPrefBlanksStrComp
(&ArgStr
[1]);
}
NLS_UpString
(OpPart.
str.
p_str);
p
= strchr(OpPart.
str.
p_str, '.');
if (!p
)
*AttrPart.
str.
p_str = '\0';
else
{
strcpy(AttrPart.
str.
p_str, p
+ 1);
*p
= '\0';
}
return True
;
}
/*-------------------------------------------------------------------------*/
static void AddSrc
(LongWord Reg
)
{
LongWord Mask
= 1 << Reg
;
if (!(ThisSrc
& Mask
))
ThisSrc
|= Mask
;
else
ThisSrc2
|= Mask
;
}
static void AddLSrc
(LongWord Reg
)
{
AddSrc
(Reg
);
AddSrc
(Reg
+ 1);
ThisLong
|= 1;
}
static void AddDest
(LongWord Reg
)
{
ThisDest
|= (1 << Reg
);
}
static void AddLDest
(LongWord Reg
)
{
ThisDest
|= (3 << Reg
);
ThisLong
|= 2;
}
static LongInt FindReg
(LongInt Mask
)
{
int z
;
for (z
= 0; z
< 32; z
++)
{
if (Mask
& 1)
break;
Mask
= Mask
>> 1;
}
return z
;
}
static char *RegName
(LongInt Num
)
{
static char s
[5];
Num
&= 31;
as_snprintf
(s
, sizeof(s
), "%c%ld", 'A' + (Num
>> 4), (long) (Num
& 15));
return s
;
}
static Boolean DecodeSReg
(char *Asc
, LongWord
*Reg
, Boolean Quarrel
)
{
char *end
;
Byte RVal
;
Boolean TFlag
;
TFlag
= True
;
switch (as_toupper
(*Asc
))
{
case 'A':
*Reg
= 0; break;
case 'B':
*Reg
= 16; break;
default:
TFlag
= False
;
}
if (TFlag
)
{
RVal
= strtol(Asc
+ 1, &end
, 10);
if (*end
!= '\0')
TFlag
= False
;
else if
(RVal
>15) TFlag
= False
;
else
*Reg
+= RVal
;
}
if ((!TFlag
) && (Quarrel
))
WrXError
(ErrNum_InvReg
, Asc
);
return TFlag
;
}
static Boolean DecodeReg
(char *Asc
, LongWord
*Reg
, Boolean
*PFlag
, Boolean Quarrel
)
{
char *p
;
LongWord NextReg
;
p
= strchr(Asc
, ':');
if (p
== 0)
{
*PFlag
= False
;
return DecodeSReg
(Asc
, Reg
, Quarrel
);
}
else
{
*PFlag
= True
;
*p
= '\0';
if (!DecodeSReg
(Asc
, &NextReg
, Quarrel
))
return False
;
else if (!DecodeSReg
(p
+ 1, Reg
, Quarrel
))
return False
;
else if ((Odd
(*Reg
)) || (NextReg
!= (*Reg
) + 1) || ((((*Reg
) ^ NextReg
) & 0x10) != 0))
{
if (Quarrel
)
WrXError
(ErrNum_InvRegPair
, Asc
);
return False
;
}
else
return True
;
}
}
static Boolean DecodeCtrlReg
(char *Asc
, LongWord
*Erg
, Boolean Write
)
{
int z
;
for (z
= 0; CtrlRegs
[z
].
Name; z
++)
if (!as_strcasecmp
(Asc
, CtrlRegs
[z
].
Name))
{
*Erg
= CtrlRegs
[z
].
Code;
return (Write
&& CtrlRegs
[z
].
Wr) || ((!Write
) && CtrlRegs
[z
].
Rd);
}
return False
;
}
/* Was bedeutet das r-Feld im Adressoperanden mit kurzem Offset ???
und wie ist das genau mit der Skalierung gemeint ??? */
static Boolean DecodeMem
(const tStrComp
*pArg
, LongWord
*Erg
, LongWord Scale
)
{
LongInt DispAcc
, Mode
;
LongWord BaseReg
, IndReg
;
int l
;
char Counter
;
char *p
, EmptyStr
[] = "";
Boolean OK
;
tStrComp Arg
, DispArg
, RegArg
;
StrCompRefRight
(&Arg
, pArg
, 0);
/* das muss da sein */
if (*pArg
->str.
p_str != '*')
{
WrError
(ErrNum_InvAddrMode
);
return False
;
}
StrCompIncRefLeft
(&Arg
, 1);
/* teilen */
p
= strchr(Arg.
str.
p_str, '[');
Counter
= ']';
if (!p
)
{
p
= strchr(Arg.
str.
p_str, '(');
Counter
= ')';
}
if (p
)
{
if (Arg.
str.
p_str[strlen(Arg.
str.
p_str) - 1] != Counter
)
{
WrError
(ErrNum_InvAddrMode
);
return False
;
}
StrCompSplitRef
(&RegArg
, &DispArg
, &Arg
, p
);
StrCompShorten
(&DispArg
, 1);
}
else
{
RegArg
= Arg
;
StrCompMkTemp
(&DispArg
, EmptyStr
, 0);
}
/* Registerfeld entschluesseln */
l
= strlen(RegArg.
str.
p_str);
Mode
= 1; /* Default ist *+R */
if (*RegArg.
str.
p_str == '+')
{
StrCompIncRefLeft
(&RegArg
, 1);
Mode
= 1;
if (*RegArg.
str.
p_str == '+')
{
StrCompIncRefLeft
(&RegArg
, 1);
Mode
= 9;
}
}
else if (*RegArg.
str.
p_str == '-')
{
StrCompIncRefLeft
(&RegArg
, 1);
Mode
= 0;
if (*RegArg.
str.
p_str == '-')
{
StrCompIncRefLeft
(&RegArg
, 1);
Mode
= 8;
}
}
else if (RegArg.
str.
p_str[l
- 1] == '+')
{
if (RegArg.
str.
p_str[l
- 2] != '+')
{
WrError
(ErrNum_InvAddrMode
);
return False
;
}
StrCompShorten
(&RegArg
, 2);
Mode
= 11;
}
else if (RegArg.
str.
p_str[l
- 1] == '-')
{
if (RegArg.
str.
p_str[l
- 2] != '-')
{
WrError
(ErrNum_InvAddrMode
);
return False
;
}
StrCompShorten
(&RegArg
, 2);
Mode
= 10;
}
if (!DecodeSReg
(RegArg.
str.
p_str, &BaseReg
, False
))
{
WrStrErrorPos
(ErrNum_InvReg
, &RegArg
);
return False
;
}
AddSrc
(BaseReg
);
/* kein Offsetfeld ? --> Skalierungsgroesse bei Autoinkrement/De-
krement, sonst 0 */
if (*DispArg.
str.
p_str == '\0')
DispAcc
= (Mode
< 2) ? 0 : Scale
;
/* Register als Offsetfeld? Dann Bit 2 in Modus setzen */
else if (DecodeSReg
(DispArg.
str.
p_str, &IndReg
, False
))
{
if ((IndReg
^ BaseReg
) > 15)
{
WrError
(ErrNum_InvAddrMode
);
return False
;
}
Mode
+= 4;
AddSrc
(DispAcc
= IndReg
);
}
/* ansonsten normaler Offset */
else
{
tSymbolFlags Flags
;
DispAcc
= EvalStrIntExpressionWithFlags
(&DispArg
, UInt15
, &OK
, &Flags
);
if (!OK
)
return False
;
if (mFirstPassUnknown
(Flags
))
DispAcc
&= 7;
if (Counter
== ')')
{
if (DispAcc
% Scale
!= 0)
{
WrError
(ErrNum_NotAligned
);
return False
;
}
else
DispAcc
/= Scale
;
}
}
/* Benutzung des Adressierers markieren */
ThisAddr
|= (BaseReg
> 15) ? 2 : 1;
/* Wenn Offset>31, muessen wir Variante 2 benutzen */
if (((Mode
& 4) == 0) && (DispAcc
> 31))
{
if ((BaseReg
< 0x1e) || (Mode
!= 1)) WrError
(ErrNum_InvAddrMode
);
else
{
*Erg
= ((DispAcc
& 0x7fff) << 8) + ((BaseReg
& 1) << 7) + 12;
return True
;
}
}
else
{
*Erg
= (BaseReg
<< 18) + ((DispAcc
& 0x1f) << 13) + (Mode
<< 9)
+ ((BaseReg
& 0x10) << 3) + 4;
return True
;
}
return False
;
}
static Boolean DecodeAdr
(const tStrComp
*pArg
, Byte Mask
, Boolean Signed
, LongWord
*AdrVal
)
{
Boolean OK
;
AdrMode
= ModNone
;
if (DecodeReg
(pArg
->str.
p_str, AdrVal
, &OK
, False
))
{
AdrMode
= (OK
) ? ModLReg
: ModReg
;
}
else
{
*AdrVal
= Signed
?
EvalStrIntExpression
(pArg
, SInt5
, &OK
) & 0x1f :
EvalStrIntExpression
(pArg
, UInt5
, &OK
);
if (OK
)
AdrMode
= ModImm
;
}
if ((AdrMode
!= ModNone
) && (((1 << AdrMode
) & Mask
) == 0))
{
WrError
(ErrNum_InvAddrMode
);
AdrMode
= ModNone
;
return False
;
}
else return True
;
}
static Boolean ChkUnit
(LongWord Reg
, TUnit U1
, TUnit U2
)
{
UnitFlag
= Ord
(Reg
>15);
if (ThisUnit
== NoUnit
)
{
ThisUnit
= (Reg
>15) ? U2
: U1
;
return True
;
}
else if (((ThisUnit
== U1
) && (Reg
< 16)) || ((ThisUnit
== U2
) && (Reg
>15)))
return True
;
else
{
WrError
(ErrNum_UndefAttr
);
return False
;
}
}
static TUnit UnitCode
(char c
)
{
switch (c
)
{
case 'L': return L1
;
case 'S': return S1
;
case 'D': return D1
;
case 'M': return M1
;
default: return NoUnit
;
}
}
static Boolean UnitUsed
(TUnit TestUnit
)
{
Integer z
;
for (z
= 0; z
< ParCnt
; z
++)
if (ParRecs
[z
].
U == TestUnit
)
return True
;
return False
;
}
static Boolean IsCross
(LongWord Reg
)
{
return (Reg
>> 4) != UnitFlag
;
}
static void SetCross
(LongWord Reg
)
{
ThisCross
= ((Reg
>> 4) != UnitFlag
);
}
static Boolean DecideUnit
(LongWord Reg
, const char *Units
)
{
Integer z
;
TUnit TestUnit
;
if (ThisUnit
== NoUnit
)
{
z
= 0;
while ((Units
[z
] != '\0') && (ThisUnit
== NoUnit
))
{
TestUnit
= UnitCode
(Units
[z
]);
if (Reg
>= 16) TestUnit
++;
if (!UnitUsed
(TestUnit
))
ThisUnit
= TestUnit
;
z
++;
}
if (ThisUnit
== NoUnit
)
{
ThisUnit
= UnitCode
(*Units
);
if (Reg
> 16)
TestUnit
++;
}
}
UnitFlag
= (ThisUnit
- FirstUnit
) & 1;
if (IsCross
(Reg
))
{
WrError
(ErrNum_UndefAttr
);
return False
;
}
else
return True
;
}
static void SwapReg
(LongWord
*r1
, LongWord
*r2
)
{
LongWord tmp
;
tmp
= (*r1
);
*r1
= (*r2
);
*r2
= tmp
;
}
static Boolean DecodePseudo
(void)
{
Boolean OK
;
unsigned dword_index
;
tStrComp
*pArg
;
LongInt Size
;
if (Memo
("SINGLE"))
{
if (ChkArgCnt
(1, ArgCntMax
))
{
OK
= True
;
forallargs
(pArg
, OK
)
{
double Float
= EvalStrFloatExpression
(pArg
, Float32
, &OK
);
if (OK
)
{
dword_index
= CodeLen
>> 2;
Double_2_ieee4
(Float
, (Byte
*) (DAsmCode
+ dword_index
), HostBigEndian
);
CodeLen
+= 4;
}
}
if (!OK
) CodeLen
= 0;
}
return True
;
}
if (Memo
("DOUBLE"))
{
if (ChkArgCnt
(1, ArgCntMax
))
{
double Float
;
OK
= True
;
forallargs
(pArg
, OK
)
{
Float
= EvalStrFloatExpression
(pArg
, Float64
, &OK
);
if (OK
)
{
dword_index
= CodeLen
>> 2;
Double_2_ieee8
(Float
, (Byte
*) (DAsmCode
+ dword_index
), HostBigEndian
);
if (!HostBigEndian
)
{
DAsmCode
[dword_index
+ 2] = DAsmCode
[dword_index
+ 0];
DAsmCode
[dword_index
+ 0] = DAsmCode
[dword_index
+ 1];
DAsmCode
[dword_index
+ 1] = DAsmCode
[dword_index
+ 2];
}
CodeLen
+= 8;
}
}
if (!OK
) CodeLen
= 0;
}
return True
;
}
if (Memo
("DATA"))
{
if (ChkArgCnt
(1, ArgCntMax
))
{
TempResult t
;
int cnt
= 0;
as_tempres_ini
(&t
);
OK
= True
;
forallargs
(pArg
, OK
)
{
EvalStrExpression
(pArg
, &t
);
switch (t.
Typ)
{
case TempString
:
{
unsigned z2
;
LongWord Trans
;
if (MultiCharToInt
(&t
, 4))
goto ToInt
;
if (as_chartrans_xlate_nonz_dynstr
(CurrTransTable
->p_table
, &t.
Contents.
str, pArg
))
OK
= False
;
else
for (z2
= 0; z2
< t.
Contents.
str.
len; z2
++)
{
Trans
= t.
Contents.
str.
p_str[z2
] & 0xff;
if (Packing
)
{
if ((z2
& 3) == 0) DAsmCode
[cnt
++] = 0;
DAsmCode
[cnt
- 1] += Trans
<< (8 * (3 - (z2
& 3)));
}
else
DAsmCode
[cnt
++] = Trans
;
}
break;
}
case TempInt
:
ToInt
:
#ifdef HAS64
if (!RangeCheck
(t.
Contents.
Int, Int32
))
{
OK
= False
;
WrStrErrorPos
(ErrNum_OverRange
, pArg
);
}
else
#endif
DAsmCode
[cnt
++] = t.
Contents.
Int;
break;
case TempFloat
:
if (!FloatRangeCheck
(t.
Contents.
Float, Float32
))
{
OK
= False
;
WrStrErrorPos
(ErrNum_OverRange
, pArg
);
}
else
{
Double_2_ieee4
(t.
Contents.
Float, (Byte
*) (DAsmCode
+ cnt
), HostBigEndian
);
cnt
++;
}
break;
default:
OK
= False
;
}
}
if (OK
)
CodeLen
= cnt
<< 2;
as_tempres_free
(&t
);
}
return True
;
}
if (Memo
("BSS"))
{
if (ChkArgCnt
(1, 1))
{
tSymbolFlags Flags
;
Size
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], UInt24
, &OK
, &Flags
);
if (mFirstPassUnknown
(Flags
)) WrError
(ErrNum_FirstPassCalc
);
if (OK
&& !mFirstPassUnknown
(Flags
))
{
DontPrint
= True
;
if (!Size
) WrError
(ErrNum_NullResMem
);
CodeLen
= Size
;
BookKeeping
();
}
}
return True
;
}
return False
;
}
static Boolean CodeL
(LongWord OpCode
, LongWord Dest
, LongWord Src1
, LongWord Src2
)
{
ThisInst
= 0x18 + (OpCode
<< 5) + (UnitFlag
<< 1) + (Ord
(ThisCross
) << 12)
+ (Dest
<< 23) + (Src2
<< 18) + (Src1
<< 13);
return True
;
}
static Boolean CodeM
(LongWord OpCode
, LongWord Dest
, LongWord Src1
, LongWord Src2
)
{
ThisInst
= 0x00 + (OpCode
<< 7) + (UnitFlag
<< 1) + (Ord
(ThisCross
) << 12)
+ (Dest
<< 23) + (Src2
<< 18) + (Src1
<< 13);
return True
;
}
static Boolean CodeS
(LongWord OpCode
, LongWord Dest
, LongWord Src1
, LongWord Src2
)
{
ThisInst
= 0x20 + (OpCode
<< 6) + (UnitFlag
<< 1) + (Ord
(ThisCross
) << 12)
+ (Dest
<< 23) + (Src2
<< 18) + (Src1
<< 13);
return True
;
}
static Boolean CodeD
(LongWord OpCode
, LongWord Dest
, LongWord Src1
, LongWord Src2
)
{
ThisInst
= 0x40 + (OpCode
<< 7) + (UnitFlag
<< 1)
+ (Dest
<< 23) + (Src2
<< 18) + (Src1
<< 13);
return True
;
}
/*-------------------------------------------------------------------------*/
static Boolean __erg
;
static void DecodeIDLE
(Word Index
)
{
UNUSED
(Index
);
if (!ChkArgCnt
(0, 0));
else if ((ThisCross
) || (ThisUnit
!= NoUnit
)) WrError
(ErrNum_UndefAttr
);
else
{
ThisInst
= 0x0001e000;
__erg
= True
;
}
}
static void DecodeNOP
(Word Index
)
{
LongInt Count
;
Boolean OK
;
UNUSED
(Index
);
if (!ChkArgCnt
(0, 1));
else if ((ThisCross
) || (ThisUnit
!= NoUnit
)) WrError
(ErrNum_UndefAttr
);
else
{
if (ArgCnt
== 0)
{
OK
= True
;
Count
= 0;
}
else
{
tSymbolFlags Flags
;
Count
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], UInt4
, &OK
, &Flags
);
Count
= mFirstPassUnknown
(Flags
) ? 0 : Count
- 1;
OK
= ChkRange
(Count
, 0, 8);
}
if (OK
)
{
ThisInst
= Count
<< 13;
__erg
= True
;
}
}
}
static void DecodeMul
(Word Index
)
{
LongWord DReg
, S1Reg
, S2Reg
;
MulOrder
*POrder
= MulOrders
+ Index
;
if (ChkArgCnt
(3, 3))
{
if ((DecodeAdr
(&ArgStr
[3], MModReg
, POrder
->DSign
, &DReg
))
&& (ChkUnit
(DReg
, M1
, M2
)))
{
if (DecodeAdr
(&ArgStr
[2], MModReg
, POrder
->SSign2
, &S2Reg
))
{
AddSrc
(S2Reg
);
DecodeAdr
(&ArgStr
[1], (POrder
->MayImm
? MModImm
: 0) + MModReg
, POrder
->SSign1
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
:
if ((ThisCross
) && (!IsCross
(S2Reg
)) && (!IsCross
(S1Reg
))) WrError
(ErrNum_InvAddrMode
);
else if ((IsCross
(S2Reg
)) && (IsCross
(S1Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
if (IsCross
(S1Reg
))
SwapReg
(&S1Reg
, &S2Reg
);
SetCross
(S2Reg
);
AddSrc
(S1Reg
);
__erg
= CodeM
(POrder
->Code
, DReg
, S1Reg
, S2Reg
);
}
break;
case ModImm
:
__erg
= Memo
("MPY") ?
CodeM
(POrder
->Code
- 1, DReg
, S1Reg
, S2Reg
) :
CodeM
(POrder
->Code
+ 3, DReg
, S1Reg
, S2Reg
);
break;
}
}
}
}
}
static void DecodeMemO
(Word Index
)
{
LongWord DReg
, S1Reg
;
MemOrder
*POrder
= MemOrders
+ Index
;
Boolean OK
, IsStore
;
if (ChkArgCnt
(2, 2))
{
const tStrComp
*pArg1
, *pArg2
;
IsStore
= (*OpPart.
str.
p_str) == 'S';
pArg1
= IsStore
? &ArgStr
[2] : &ArgStr
[1];
pArg2
= IsStore
? &ArgStr
[1] : &ArgStr
[2];
if (IsStore
)
ThisStore
= True
;
if (DecodeAdr
(pArg2
, MModReg
, False
, &DReg
))
{
if (IsStore
)
AddSrc
(DReg
);
ThisAddr
|= (DReg
> 15) ? 8 : 4;
/* Zielregister 4 Takte verzoegert, nicht als Dest eintragen */
OK
= DecodeMem
(pArg1
, &S1Reg
, POrder
->Scale
);
if (OK
)
{
OK
= (S1Reg
& 8) ?
ChkUnit
(0x1e, D1
, D2
) :
ChkUnit
((S1Reg
>> 18) & 31, D1
, D2
);
}
if (OK
)
{
ThisInst
= S1Reg
+ (DReg
<< 23) + (POrder
->Code
<< 4)
+ ((DReg
& 16) >> 3);
__erg
= True
;
}
}
}
}
static void DecodeSTP
(Word Index
)
{
LongWord S2Reg
;
UNUSED
(Index
);
if (ChkArgCnt
(1, 1)
&& ChkUnit
(0x10, S1
, S2
))
{
if (DecodeAdr
(&ArgStr
[1], MModReg
, False
, &S2Reg
))
{
if ((ThisCross
) || (S2Reg
< 16)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
);
__erg
= CodeS
(0x0c, 0, 0, S2Reg
);
}
}
}
}
static void DecodeABS
(Word Index
)
{
Boolean DPFlag
, S1Flag
;
LongWord DReg
, S1Reg
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 2)
&& DecodeReg
(ArgStr
[2].
str.
p_str, &DReg
, &DPFlag
, True
)
&& ChkUnit
(DReg
, L1
, L2
)
&& DecodeReg
(ArgStr
[1].
str.
p_str, &S1Reg
, &S1Flag
, True
))
{
if (DPFlag
!= S1Flag
) WrError
(ErrNum_InvAddrMode
);
else if ((ThisCross
) && ((S1Reg
>> 4) == UnitFlag
)) WrError
(ErrNum_InvAddrMode
);
else
{
SetCross
(S1Reg
);
if (DPFlag
)
{
__erg
= CodeL
(0x38, DReg
, 0, S1Reg
);
AddLSrc
(S1Reg
);
AddLDest
(DReg
);
}
else
{
__erg
= CodeL
(0x1a, DReg
, 0, S1Reg
);
AddSrc
(S1Reg
);
AddDest
(DReg
);
}
}
}
}
static void DecodeADD
(Word Index
)
{
LongWord S1Reg
, S2Reg
, DReg
;
Boolean OK
;
UNUSED
(Index
);
if (ChkArgCnt
(3, 3))
{
DecodeAdr
(&ArgStr
[3], MModReg
+ MModLReg
, True
, &DReg
);
UnitFlag
= DReg
>> 4;
switch (AdrMode
)
{
case ModLReg
: /* ADD ?,?,long */
AddLDest
(DReg
);
DecodeAdr
(&ArgStr
[1], MModReg
+ MModLReg
+ MModImm
, True
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
: /* ADD int,?,long */
AddSrc
(S1Reg
);
DecodeAdr
(&ArgStr
[2], MModReg
+ MModLReg
, True
, &S2Reg
);
switch (AdrMode
)
{
case ModReg
: /* ADD int,int,long */
if (ChkUnit
(DReg
, L1
, L2
))
{
if ((ThisCross
) && (!IsCross
(S1Reg
)) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else if ((IsCross
(S1Reg
)) && (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
);
if (IsCross
(S1Reg
))
SwapReg
(&S1Reg
, &S2Reg
);
SetCross
(S2Reg
);
__erg
= CodeL
(0x23, DReg
, S1Reg
, S2Reg
);
}
}
break;
case ModLReg
:/* ADD int,long,long */
if (ChkUnit
(DReg
, L1
, L2
))
{
if (IsCross
(S2Reg
)) WrError
(ErrNum_InvAddrMode
);
else if ((ThisCross
) && (!IsCross
(S1Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S2Reg
);
SetCross
(S1Reg
);
__erg
= CodeL
(0x21, DReg
, S1Reg
, S2Reg
);
}
}
break;
}
break;
case ModLReg
: /* ADD long,?,long */
AddLSrc
(S1Reg
);
DecodeAdr
(&ArgStr
[2], MModReg
+ MModImm
, True
, &S2Reg
);
switch (AdrMode
)
{
case ModReg
: /* ADD long,int,long */
if (ChkUnit
(DReg
, L1
, L2
))
{
if (IsCross
(S1Reg
)) WrError
(ErrNum_InvAddrMode
);
else if ((ThisCross
) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
);
SetCross
(S2Reg
);
__erg
= CodeL
(0x21, DReg
, S2Reg
, S1Reg
);
}
}
break;
case ModImm
: /* ADD long,imm,long */
if (ChkUnit
(DReg
, L1
, L2
))
{
if (IsCross
(S1Reg
)) WrError
(ErrNum_InvAddrMode
);
else if (ThisCross
) WrError
(ErrNum_InvAddrMode
);
else
__erg
= CodeL
(0x20, DReg
, S2Reg
, S1Reg
);
}
break;
}
break;
case ModImm
: /* ADD imm,?,long */
if (DecodeAdr
(&ArgStr
[2], MModLReg
, True
, &S2Reg
))
{ /* ADD imm,long,long */
if (ChkUnit
(DReg
, L1
, L2
))
{
if (IsCross
(S2Reg
)) WrError
(ErrNum_InvAddrMode
);
else if (ThisCross
) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S2Reg
);
__erg
= CodeL
(0x20, DReg
, S1Reg
, S2Reg
);
}
}
}
break;
}
break;
case ModReg
: /* ADD ?,?,int */
AddDest
(DReg
);
DecodeAdr
(&ArgStr
[1], MModReg
+ MModImm
, True
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
: /* ADD int,?,int */
AddSrc
(S1Reg
);
DecodeAdr
(&ArgStr
[2], MModReg
+ MModImm
, True
, &S2Reg
);
switch (AdrMode
)
{
case ModReg
: /* ADD int,int,int */
AddSrc
(S2Reg
);
if (((DReg
^ S1Reg
) > 15) && ((DReg
^ S2Reg
)>15)) WrError
(ErrNum_InvAddrMode
);
else if ((ThisCross
) && ((DReg
^ S1Reg
) < 16) && ((DReg
^ S2Reg
) < 15)) WrError
(ErrNum_InvAddrMode
);
else
{
if ((S1Reg
^ DReg
) > 15)
SwapReg
(&S1Reg
, &S2Reg
);
OK
= DecideUnit
(DReg
, ((S2Reg
^ DReg
)>15) ? "LS" : "LSD");
if (OK
)
{
switch (ThisUnit
)
{
case L1
: case L2
: /* ADD.Lx int,int,int */
__erg
= CodeL
(0x03, DReg
, S1Reg
, S2Reg
);
break;
case S1
: case S2
: /* ADD.Sx int,int,int */
__erg
= CodeS
(0x07, DReg
, S1Reg
, S2Reg
);
break;
case D1
: case D2
: /* ADD.Dx int,int,int */
__erg
= CodeD
(0x10, DReg
, S1Reg
, S2Reg
);
break;
default:
WrError
(ErrNum_CannotUseUnit
);
}
}
}
break;
case ModImm
: /* ADD int,imm,int */
if ((ThisCross
) && ((S1Reg
^ DReg
) < 16)) WrError
(ErrNum_InvAddrMode
);
else
{
SetCross
(S1Reg
);
if (DecideUnit
(DReg
, "LS"))
switch (ThisUnit
)
{
case L1
: case L2
:
__erg
= CodeL
(0x02, DReg
, S2Reg
, S1Reg
);
break;
case S1
: case S2
:
__erg
= CodeS
(0x06, DReg
, S2Reg
, S1Reg
);
break;
default:
WrError
(ErrNum_CannotUseUnit
);
}
}
break;
}
break;
case ModImm
: /* ADD imm,?,int */
if (DecodeAdr
(&ArgStr
[2], MModReg
, True
, &S2Reg
))
{
AddSrc
(S2Reg
);
if ((ThisCross
) && ((S2Reg
^ DReg
) < 16)) WrError
(ErrNum_InvAddrMode
);
else
{
SetCross
(S2Reg
);
if (DecideUnit
(DReg
, "LS"))
switch (ThisUnit
)
{
case L1
: case L2
:
__erg
= CodeL
(0x02, DReg
, S1Reg
, S2Reg
);
break;
case S1
: case S2
:
__erg
= CodeS
(0x06, DReg
, S1Reg
, S2Reg
);
break;
default:
WrError
(ErrNum_CannotUseUnit
);
}
}
}
break;
}
break;
}
}
}
static void DecodeADDU
(Word Index
)
{
LongWord DReg
, S1Reg
, S2Reg
;
UNUSED
(Index
);
if (ChkArgCnt
(3, 3))
{
DecodeAdr
(&ArgStr
[3], MModReg
+ MModLReg
, False
, &DReg
);
switch (AdrMode
)
{
case ModReg
: /* ADDU ?,?,int */
if (ChkUnit
(DReg
, D1
, D2
))
{
AddDest
(DReg
);
DecodeAdr
(&ArgStr
[1], MModReg
+ MModImm
, False
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
: /* ADDU int,?,int */
if (IsCross
(S1Reg
)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S1Reg
);
if (DecodeAdr
(&ArgStr
[2], MModImm
, False
, &S2Reg
))
__erg
= CodeD
(0x12, DReg
, S2Reg
, S1Reg
);
}
break;
case ModImm
: /* ADDU imm,?,int */
if (DecodeAdr
(&ArgStr
[2], MModReg
, False
, &S2Reg
))
{
if (IsCross
(S2Reg
)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
);
__erg
= CodeD
(0x12, DReg
, S1Reg
, S2Reg
);
}
}
break;
}
}
break;
case ModLReg
: /* ADDU ?,?,long */
if (ChkUnit
(DReg
, L1
, L2
))
{
AddLDest
(DReg
);
DecodeAdr
(&ArgStr
[1], MModReg
+ MModLReg
, False
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
: /* ADDU int,?,long */
AddSrc
(S1Reg
);
DecodeAdr
(&ArgStr
[2], MModReg
+ MModLReg
, False
, &S2Reg
);
switch (AdrMode
)
{
case ModReg
: /* ADDU int,int,long */
if ((IsCross
(S1Reg
)) && (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else if ((ThisCross
) && (((S1Reg
^ DReg
) < 16) && ((S2Reg
^ DReg
) < 16))) WrError
(ErrNum_InvAddrMode
);
else
{
if ((S1Reg
^ DReg
) > 15)
SwapReg
(&S1Reg
, &S2Reg
);
SetCross
(S2Reg
);
__erg
= CodeL
(0x2b, DReg
, S1Reg
, S2Reg
);
}
break;
case ModLReg
: /* ADDU int,long,long */
if (IsCross
(S2Reg
)) WrError
(ErrNum_InvAddrMode
);
else if ((ThisCross
) && ((S1Reg
^ DReg
) < 16)) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S2Reg
);
SetCross
(S1Reg
);
__erg
= CodeL
(0x29, DReg
, S1Reg
, S2Reg
);
}
break;
}
break;
case ModLReg
:
if (IsCross
(S1Reg
)) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S1Reg
);
if (DecodeAdr
(&ArgStr
[2], MModReg
, False
, &S2Reg
))
{
if ((ThisCross
) && ((S2Reg
^ DReg
) < 16)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
); SetCross
(S2Reg
);
__erg
= CodeL
(0x29, DReg
, S2Reg
, S1Reg
);
}
}
}
break;
}
}
break;
}
}
}
static void DecodeSUB
(Word Index
)
{
LongWord DReg
, S1Reg
, S2Reg
;
Boolean OK
;
UNUSED
(Index
);
if (ChkArgCnt
(3, 3))
{
DecodeAdr
(&ArgStr
[3], MModReg
+ MModLReg
, True
, &DReg
);
switch (AdrMode
)
{
case ModReg
:
AddDest
(DReg
);
DecodeAdr
(&ArgStr
[1], MModReg
+ MModImm
, True
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
:
AddSrc
(S1Reg
);
DecodeAdr
(&ArgStr
[2], MModReg
+ MModImm
, True
, &S2Reg
);
switch (AdrMode
)
{
case ModReg
:
if ((ThisCross
) && ((S1Reg
^ DReg
) < 16) && ((S2Reg
^ DReg
) < 16)) WrError
(ErrNum_InvAddrMode
);
else if (((S1Reg
^ DReg
) > 15) && ((S2Reg
^ DReg
) > 15)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
);
ThisCross
= ((S1Reg
^ DReg
) > 15) || ((S2Reg
^ DReg
) > 15);
if ((S1Reg
^ DReg
) > 15) OK
= DecideUnit
(DReg
, "L");
else if ((S2Reg
^ DReg
) > 15) OK
= DecideUnit
(DReg
, "LS");
else OK
= DecideUnit
(DReg
, "LSD");
if (OK
)
switch (ThisUnit
)
{
case L1
: case L2
:
if ((S1Reg
^ DReg
) > 15) __erg
= CodeL
(0x17, DReg
, S1Reg
, S2Reg
);
else __erg
= CodeL
(0x07, DReg
, S1Reg
, S2Reg
);
break;
case S1
: case S2
:
__erg
= CodeS
(0x17, DReg
, S1Reg
, S2Reg
);
break;
case D1
: case D2
:
__erg
= CodeD
(0x11, DReg
, S2Reg
, S1Reg
);
break;
default:
WrError
(ErrNum_CannotUseUnit
);
}
}
break;
case ModImm
:
if (ChkUnit
(DReg
, D1
, D2
))
{
if ((ThisCross
) || ((S1Reg
^ DReg
) > 15)) WrError
(ErrNum_InvAddrMode
);
else __erg
= CodeD
(0x13, DReg
, S2Reg
, S1Reg
);
}
break;
}
break;
case ModImm
:
if (DecodeAdr
(&ArgStr
[2], MModReg
, True
, &S2Reg
))
{
if ((ThisCross
) && ((S2Reg
^ DReg
) < 16)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
);
if (DecideUnit
(DReg
, "LS"))
switch (ThisUnit
)
{
case L1
: case L2
:
__erg
= CodeL
(0x06, DReg
, S1Reg
, S2Reg
);
break;
case S1
: case S2
:
__erg
= CodeS
(0x16, DReg
, S1Reg
, S2Reg
);
break;
default:
WrError
(ErrNum_CannotUseUnit
);
}
}
}
break;
}
break;
case ModLReg
:
AddLDest
(DReg
);
if (ChkUnit
(DReg
, L1
, L2
))
{
DecodeAdr
(&ArgStr
[1], MModImm
+ MModReg
, True
, &S1Reg
);
switch (AdrMode
)
{
case ModImm
:
if (DecodeAdr
(&ArgStr
[2], MModLReg
, True
, &S2Reg
))
{
if ((ThisCross
) || (/*NOT*/ IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S2Reg
);
__erg
= CodeL
(0x24, DReg
, S1Reg
, S2Reg
);
}
}
break;
case ModReg
:
AddSrc
(S1Reg
);
if (DecodeAdr
(&ArgStr
[2], MModReg
, True
, &S2Reg
))
{
if ((ThisCross
) && (!IsCross
(S1Reg
)) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else if ((IsCross
(S1Reg
)) && (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
);
ThisCross
= (IsCross
(S1Reg
)) || (IsCross
(S2Reg
));
/* what did I do here? */
__erg
= IsCross
(S1Reg
) ?
CodeL
(0x37, DReg
, S1Reg
, S2Reg
) :
CodeL
(0x47, DReg
, S1Reg
, S2Reg
);
}
}
break;
}
}
break;
}
}
}
static void DecodeSUBU
(Word Index
)
{
LongWord S1Reg
, S2Reg
, DReg
;
UNUSED
(Index
);
if (ChkArgCnt
(3, 3)
&& DecodeAdr
(&ArgStr
[3], MModLReg
, False
, &DReg
)
&& ChkUnit
(DReg
, L1
, L2
))
{
AddLDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModReg
, False
, &S1Reg
))
{
AddSrc
(S1Reg
);
if (DecodeAdr
(&ArgStr
[2], MModReg
, False
, &S2Reg
))
{
if ((ThisCross
) && (!IsCross
(S1Reg
)) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else if ((IsCross
(S1Reg
)) && (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
);
ThisCross
= IsCross
(S1Reg
) || IsCross
(S2Reg
);
__erg
= IsCross
(S1Reg
) ?
CodeL
(0x3f, DReg
, S1Reg
, S2Reg
) :
CodeL
(0x2f, DReg
, S1Reg
, S2Reg
);
}
}
}
}
}
static void DecodeSUBC
(Word Index
)
{
LongWord DReg
, S1Reg
, S2Reg
;
UNUSED
(Index
);
if (ChkArgCnt
(3, 3)
&& DecodeAdr
(&ArgStr
[3], MModReg
, False
, &DReg
)
&& ChkUnit
(DReg
, L1
, L2
))
{
AddLDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModReg
, False
, &S1Reg
))
{
if (DecodeAdr
(&ArgStr
[2], MModReg
, False
, &S2Reg
))
{
if ((ThisCross
) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else if (IsCross
(S1Reg
)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
);
SetCross
(S2Reg
);
__erg
= CodeL
(0x4b, DReg
, S1Reg
, S2Reg
);
}
}
}
}
}
static void DecodeLinAdd
(Word Index
)
{
LongWord DReg
, S1Reg
, S2Reg
;
FixedOrder
*POrder
= LinAddOrders
+ Index
;
if (!ChkArgCnt
(3, 3));
else if (ThisCross
) WrError
(ErrNum_InvAddrMode
);
else
{
if ((DecodeAdr
(&ArgStr
[3], MModReg
, True
, &DReg
))
&& (ChkUnit
(DReg
, D1
, D2
)))
{
AddDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModReg
, True
, &S2Reg
))
{
if (IsCross
(S2Reg
)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
);
DecodeAdr
(&ArgStr
[2], MModReg
+ MModImm
, False
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
:
if (IsCross
(S1Reg
)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S1Reg
);
__erg
= CodeD
(POrder
->Code
, DReg
, S1Reg
, S2Reg
);
}
break;
case ModImm
:
__erg
= CodeD
(POrder
->Code
+ 2, DReg
, S1Reg
, S2Reg
);
break;
}
}
}
}
}
}
static void DecodeADDK
(Word Index
)
{
LongInt Value
;
LongWord DReg
;
Boolean OK
;
UNUSED
(Index
);
if (ChkArgCnt
(2, 2)
&& DecodeAdr
(&ArgStr
[2], MModReg
, False
, &DReg
)
&& ChkUnit
(DReg
, S1
, S2
))
{
AddDest
(DReg
);
Value
= EvalStrIntExpression
(&ArgStr
[1], SInt16
, &OK
);
if (OK
)
{
ThisInst
= 0x50 + (UnitFlag
<< 1) + ((Value
& 0xffff) << 7) + (DReg
<< 23);
__erg
= True
;
}
}
}
static void DecodeADD2_SUB2
(Word Index
)
{
LongWord DReg
, S1Reg
, S2Reg
;
Boolean OK
;
Index
= (Index
<< 5) + 1;
if (ChkArgCnt
(3, 3)
&& DecodeAdr
(&ArgStr
[3], MModReg
, True
, &DReg
)
&& ChkUnit
(DReg
, S1
, S2
))
{
AddDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModReg
, True
, &S1Reg
))
{
AddSrc
(S1Reg
);
if (DecodeAdr
(&ArgStr
[2], MModReg
, True
, &S2Reg
))
{
if ((ThisCross
) && (!IsCross
(S1Reg
)) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else if ((IsCross
(S1Reg
)) && (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
OK
= True
; AddSrc
(S2Reg
);
if (IsCross
(S1Reg
))
{
if (Index
> 1)
{
WrError
(ErrNum_InvAddrMode
);
OK
= False
;
}
else SwapReg
(&S1Reg
, &S2Reg
);
}
if (OK
)
{
SetCross
(S2Reg
);
__erg
= CodeS
(Index
, DReg
, S1Reg
, S2Reg
);
}
}
}
}
}
}
static void DecodeMV
(Word Index
)
{
LongWord SReg
, DReg
;
UNUSED
(Index
);
/* MV src,dst == ADD 0,src,dst */
if (ChkArgCnt
(2, 2))
{
DecodeAdr
(&ArgStr
[2], MModReg
+ MModLReg
, True
, &DReg
);
UnitFlag
= DReg
>> 4;
switch (AdrMode
)
{
case ModLReg
: /* MV ?,long */
AddLDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModLReg
, True
, &SReg
))
{ /* MV long,long */
if (ChkUnit
(DReg
, L1
, L2
))
{
if (IsCross
(SReg
)) WrError
(ErrNum_InvAddrMode
);
else if (ThisCross
) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(SReg
);
__erg
= CodeL
(0x20, DReg
, 0, SReg
);
}
}
}
break;
case ModReg
: /* MV ?,int */
AddDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModReg
, True
, &SReg
))
{
AddSrc
(SReg
);
if ((ThisCross
) && ((SReg
^ DReg
) < 16)) WrError
(ErrNum_InvAddrMode
);
else
{
SetCross
(SReg
);
if (DecideUnit
(DReg
, "LSD"))
switch (ThisUnit
)
{
case L1
: case L2
:
__erg
= CodeL
(0x02, DReg
, 0, SReg
);
break;
case S1
: case S2
:
__erg
= CodeS
(0x06, DReg
, 0, SReg
);
break;
case D1
: case D2
:
__erg
= CodeD
(0x12, DReg
, 0, SReg
);
break;
default:
WrError
(ErrNum_CannotUseUnit
);
}
}
}
break;
}
}
}
static void DecodeNEG
(Word Index
)
{
LongWord DReg
, SReg
;
UNUSED
(Index
);
/* NEG src,dst == SUB 0,src,dst */
if (ChkArgCnt
(2, 2))
{
DecodeAdr
(&ArgStr
[2], MModReg
+ MModLReg
, True
, &DReg
);
switch (AdrMode
)
{
case ModReg
:
AddDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModReg
, True
, &SReg
))
{
if ((ThisCross
) && ((SReg
^ DReg
) < 16)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(SReg
);
if (DecideUnit
(DReg
, "LS"))
switch (ThisUnit
)
{
case L1
: case L2
:
__erg
= CodeL
(0x06, DReg
, 0, SReg
);
break;
case S1
: case S2
:
__erg
= CodeS
(0x16, DReg
, 0, SReg
);
break;
default:
WrError
(ErrNum_CannotUseUnit
);
}
}
}
break;
case ModLReg
:
AddLDest
(DReg
);
if (ChkUnit
(DReg
, L1
, L2
))
{
if (DecodeAdr
(&ArgStr
[1], MModLReg
, True
, &SReg
))
{
if ((ThisCross
) || (IsCross
(SReg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(SReg
);
__erg
= CodeL
(0x24, DReg
, 0, SReg
);
}
}
}
break;
}
}
}
static void DecodeLogic
(Word Index
)
{
LongWord S1Reg
, S2Reg
, DReg
;
LongWord Code1
, Code2
;
Boolean OK
, WithImm
;
Code1
= Lo
(Index
);
Code2
= Hi
(Index
);
if (ChkArgCnt
(3, 3))
{
if (DecodeAdr
(&ArgStr
[3], MModReg
, True
, &DReg
))
{
AddDest
(DReg
);
DecodeAdr
(&ArgStr
[1], MModImm
+ MModReg
, True
, &S1Reg
);
WithImm
= False
;
switch (AdrMode
)
{
case ModImm
:
OK
= DecodeAdr
(&ArgStr
[2], MModReg
, True
, &S2Reg
);
if (OK
) AddSrc
(S2Reg
);
WithImm
= True
;
break;
case ModReg
:
AddSrc
(S1Reg
);
OK
= DecodeAdr
(&ArgStr
[2], MModImm
+ MModReg
, True
, &S2Reg
);
switch (AdrMode
)
{
case ModImm
:
SwapReg
(&S1Reg
, &S2Reg
);
WithImm
= True
;
break;
case ModReg
:
AddSrc
(S2Reg
);
WithImm
= False
;
break;
default:
OK
= False
;
}
break;
default:
OK
= False
;
}
if ((OK
) && (DecideUnit
(DReg
, "LS")))
{
if ((!WithImm
) && (IsCross
(S1Reg
)) && (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else if ((ThisCross
) && (!IsCross
(S2Reg
)) && ((WithImm
) || (!IsCross
(S1Reg
)))) WrError
(ErrNum_InvAddrMode
);
else
{
if ((!WithImm
) && (IsCross
(S1Reg
)))
SwapReg
(&S1Reg
, &S2Reg
);
SetCross
(S2Reg
);
switch (ThisUnit
)
{
case L1
: case L2
:
__erg
= CodeL
(Code1
- Ord
(WithImm
), DReg
, S1Reg
, S2Reg
);
break;
case S1
: case S2
:
__erg
= CodeS
(Code2
- Ord
(WithImm
), DReg
, S1Reg
, S2Reg
);
break;
default:
WrError
(ErrNum_CannotUseUnit
);
}
}
}
}
}
}
static void DecodeNOT
(Word Index
)
{
LongWord SReg
, DReg
;
UNUSED
(Index
);
/* NOT src,dst == XOR -1,src,dst */
if (ChkArgCnt
(2, 2))
{
if (DecodeAdr
(&ArgStr
[2], MModReg
, True
, &DReg
))
{
AddDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModReg
, True
, &SReg
))
{
AddSrc
(SReg
);
if (DecideUnit
(DReg
, "LS"))
{
if ((ThisCross
) && (!IsCross
(SReg
))) WrError
(ErrNum_InvAddrMode
);
else
{
SetCross
(SReg
);
switch (ThisUnit
)
{
case L1
: case L2
:
__erg
= CodeL
(0x6e, DReg
, 0x1f, SReg
);
break;
case S1
: case S2
:
__erg
= CodeS
(0x0a, DReg
, 0x1f, SReg
);
break;
default:
WrError
(ErrNum_CannotUseUnit
);
}
}
}
}
}
}
}
static void DecodeZERO
(Word Index
)
{
LongWord DReg
;
UNUSED
(Index
);
/* ZERO dst == SUB dst,dst,dst */
if (ChkArgCnt
(1, 1))
{
DecodeAdr
(&ArgStr
[1], MModReg
+ MModLReg
, True
, &DReg
);
if ((ThisCross
) || (IsCross
(DReg
))) WrError
(ErrNum_InvAddrMode
);
else
switch (AdrMode
)
{
case ModReg
:
AddDest
(DReg
);
AddSrc
(DReg
);
if (DecideUnit
(DReg
, "LSD"))
switch (ThisUnit
)
{
case L1
: case L2
:
__erg
= CodeL
(0x17, DReg
, DReg
, DReg
);
break;
case S1
: case S2
:
__erg
= CodeS
(0x17, DReg
, DReg
, DReg
);
break;
case D1
: case D2
:
__erg
= CodeD
(0x11, DReg
, DReg
, DReg
);
break;
default:
WrError
(ErrNum_CannotUseUnit
);
}
break;
case ModLReg
:
AddLDest
(DReg
);
AddLSrc
(DReg
);
if (ChkUnit
(DReg
, L1
, L2
))
__erg
= CodeL
(0x37, DReg
, DReg
, DReg
);
break;
}
}
}
static void DecodeCLR_EXT_EXTU_SET
(Word Code
)
{
LongWord DReg
, S1Reg
, S2Reg
, HReg
;
Boolean OK
, IsEXT
= (Code
== 0x2f48);
if (ChkArgCnt
(3, 4))
{
if ((DecodeAdr
(&ArgStr
[ArgCnt
], MModReg
, IsEXT
, &DReg
))
&& (ChkUnit
(DReg
, S1
, S2
)))
{
AddDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModReg
, IsEXT
, &S2Reg
))
{
AddSrc
(S2Reg
);
if (ArgCnt
== 3)
{
if (DecodeAdr
(&ArgStr
[2], MModReg
, False
, &S1Reg
))
{
if (IsCross
(S1Reg
)) WrError
(ErrNum_InvAddrMode
);
else if ((ThisCross
) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
SetCross
(S2Reg
);
__erg
= CodeS
(Hi
(Code
), DReg
, S1Reg
, S2Reg
);
}
}
}
else if ((ThisCross
) || (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
S1Reg
= EvalStrIntExpression
(&ArgStr
[2], UInt5
, &OK
);
if (OK
)
{
HReg
= EvalStrIntExpression
(&ArgStr
[3], UInt5
, &OK
);
if (OK
)
{
ThisInst
= (DReg
<< 23) + (S2Reg
<< 18) + (S1Reg
<< 13)
+ (HReg
<< 8) + (UnitFlag
<< 1) + Lo
(Code
);
__erg
= True
;
}
}
}
}
}
}
}
static void DecodeCmp
(Word Index
)
{
const CmpOrder
*pOrder
= CmpOrders
+ Index
;
LongWord DReg
, S1Reg
, S2Reg
;
if (ChkArgCnt
(3, 3)
&& DecodeAdr
(&ArgStr
[3], MModReg
, False
, &DReg
)
&& ChkUnit
(DReg
, L1
, L2
))
{
AddDest
(DReg
);
DecodeAdr
(&ArgStr
[1], MModReg
+ MModImm
, pOrder
->WithImm
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
:
AddSrc
(S1Reg
);
DecodeAdr
(&ArgStr
[2], MModReg
+ MModLReg
, pOrder
->WithImm
, &S2Reg
);
switch (AdrMode
)
{
case ModReg
:
if ((IsCross
(S1Reg
)) && (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else if ((ThisCross
) && (!IsCross
(S1Reg
)) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
);
if (IsCross
(S1Reg
)) SwapReg
(&S1Reg
, &S2Reg
);
SetCross
(S2Reg
);
__erg
= CodeL
(pOrder
->Code
+ 3, DReg
, S1Reg
, S2Reg
);
}
break;
case ModLReg
:
if (IsCross
(S2Reg
)) WrError
(ErrNum_InvAddrMode
);
else if ((ThisCross
) && (!IsCross
(S1Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S2Reg
); SetCross
(S1Reg
);
__erg
= CodeL
(pOrder
->Code
+ 1, DReg
, S1Reg
, S2Reg
);
}
break;
}
break;
case ModImm
:
DecodeAdr
(&ArgStr
[2], MModReg
+ MModLReg
, pOrder
->WithImm
, &S2Reg
);
switch (AdrMode
)
{
case ModReg
:
if ((ThisCross
) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
); SetCross
(S2Reg
);
__erg
= CodeL
(pOrder
->Code
+ 2, DReg
, S1Reg
, S2Reg
);
}
break;
case ModLReg
:
if ((ThisCross
) || (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S2Reg
);
__erg
= CodeL
(pOrder
->Code
, DReg
, S1Reg
, S2Reg
);
}
break;
}
break;
}
}
}
static void DecodeLMBD
(Word Code
)
{
LongWord DReg
, S1Reg
, S2Reg
;
UNUSED
(Code
);
if (ChkArgCnt
(3, 3)
&& DecodeAdr
(&ArgStr
[3], MModReg
, False
, &DReg
)
&& ChkUnit
(DReg
, L1
, L2
))
{
AddDest
(DReg
);
if (DecodeAdr
(&ArgStr
[2], MModReg
, False
, &S2Reg
))
{
if ((ThisCross
) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
SetCross
(S2Reg
);
if (DecodeAdr
(&ArgStr
[1], MModImm
+ MModReg
, False
, &S1Reg
))
{
if (AdrMode
== ModReg
)
AddSrc
(S1Reg
);
__erg
= CodeL
(0x6a + Ord
(AdrMode
== ModImm
), DReg
, S1Reg
, S2Reg
);
}
}
}
}
}
static void DecodeNORM
(Word Code
)
{
LongWord DReg
, S2Reg
;
UNUSED
(Code
);
if (ChkArgCnt
(2, 2)
&& DecodeAdr
(&ArgStr
[2], MModReg
, False
, &DReg
)
&& ChkUnit
(DReg
, L1
, L2
))
{
AddDest
(DReg
);
DecodeAdr
(&ArgStr
[1], MModReg
+ MModLReg
, True
, &S2Reg
);
switch (AdrMode
)
{
case ModReg
:
if ((ThisCross
) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
SetCross
(S2Reg
); AddSrc
(S2Reg
);
__erg
= CodeL
(0x63, DReg
, 0, S2Reg
);
}
break;
case ModLReg
:
if ((ThisCross
) || (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S2Reg
);
__erg
= CodeL
(0x60, DReg
, 0, S2Reg
);
}
break;
}
}
}
static void DecodeSADD
(Word Code
)
{
LongWord DReg
, S1Reg
, S2Reg
;
UNUSED
(Code
);
if (ChkArgCnt
(3, 3)
&& DecodeAdr
(&ArgStr
[3], MModReg
+ MModLReg
, True
, &DReg
)
&& ChkUnit
(DReg
, L1
, L2
))
{
switch (AdrMode
)
{
case ModReg
:
AddDest
(DReg
);
DecodeAdr
(&ArgStr
[1], MModReg
+ MModImm
, True
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
:
AddSrc
(S1Reg
);
DecodeAdr
(&ArgStr
[2], MModReg
+ MModImm
, True
, &S2Reg
);
switch (AdrMode
)
{
case ModReg
:
if ((ThisCross
) && (!IsCross
(S1Reg
)) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else if ((IsCross
(S1Reg
)) && (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
);
if (IsCross
(S1Reg
)) SwapReg
(&S1Reg
, &S2Reg
);
SetCross
(S2Reg
);
__erg
= CodeL
(0x13, DReg
, S1Reg
, S2Reg
);
}
break;
case ModImm
:
if ((ThisCross
) && (!IsCross
(S1Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
SetCross
(S1Reg
);
__erg
= CodeL
(0x12, DReg
, S2Reg
, S1Reg
);
}
break;
}
break;
case ModImm
:
if (DecodeAdr
(&ArgStr
[2], MModReg
, True
, &S2Reg
))
{
if ((ThisCross
) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
SetCross
(S2Reg
);
__erg
= CodeL
(0x12, DReg
, S1Reg
, S2Reg
);
}
}
break;
}
break;
case ModLReg
:
AddLDest
(DReg
);
DecodeAdr
(&ArgStr
[1], MModReg
+ MModLReg
+ MModImm
, True
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
:
AddSrc
(S1Reg
);
if (DecodeAdr
(&ArgStr
[2], MModLReg
, True
, &S2Reg
))
{
if ((ThisCross
) && (!IsCross
(S1Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S2Reg
); SetCross
(S1Reg
);
__erg
= CodeL
(0x31, DReg
, S1Reg
, S2Reg
);
}
}
break;
case ModLReg
:
if (IsCross
(S1Reg
)) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S1Reg
);
DecodeAdr
(&ArgStr
[2], MModReg
+ MModImm
, True
, &S2Reg
);
switch (AdrMode
)
{
case ModReg
:
if ((ThisCross
) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
); SetCross
(S2Reg
);
__erg
= CodeL
(0x31, DReg
, S2Reg
, S1Reg
);
}
break;
case ModImm
:
__erg
= CodeL
(0x30, DReg
, S2Reg
, S1Reg
);
break;
}
}
break;
case ModImm
:
if (DecodeAdr
(&ArgStr
[2], MModLReg
, True
, &S2Reg
))
{
if (IsCross
(S2Reg
)) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S2Reg
);
__erg
= CodeL
(0x30, DReg
, S1Reg
, S2Reg
);
}
}
break;
}
break;
}
}
}
static void DecodeSAT
(Word Code
)
{
LongWord DReg
, S2Reg
;
UNUSED
(Code
);
if (ChkArgCnt
(2, 2)
&& DecodeAdr
(&ArgStr
[2], MModReg
, True
, &DReg
)
&& ChkUnit
(DReg
, L1
, L2
))
{
AddDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModLReg
, True
, &S2Reg
))
{
if ((ThisCross
) || (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S2Reg
);
__erg
= CodeL
(0x40, DReg
, 0, S2Reg
);
}
}
}
}
static void DecodeMVC
(Word Code
)
{
LongWord S1Reg
, CReg
;
UNUSED
(Code
);
if ((ThisUnit
!= NoUnit
) && (ThisUnit
!= S2
)) WrError
(ErrNum_InvAddrMode
);
else if (ChkArgCnt
(2, 2))
{
int z
;
z
= 0;
ThisUnit
= S2
;
UnitFlag
= 1;
if (DecodeCtrlReg
(ArgStr
[1].
str.
p_str, &CReg
, False
))
z
= 2;
else if (DecodeCtrlReg
(ArgStr
[2].
str.
p_str, &CReg
, True
))
z
= 1;
else
WrStrErrorPos
(ErrNum_InvCtrlReg
, &ArgStr
[1]);
if (z
> 0)
{
if (DecodeAdr
(&ArgStr
[z
], MModReg
, False
, &S1Reg
))
{
if ((ThisCross
) && ((z
== 2) || (IsCross
(S1Reg
)))) WrError
(ErrNum_InvAddrMode
);
else
{
if (z
== 1)
{
AddSrc
(S1Reg
);
SetCross
(S1Reg
);
__erg
= CodeS
(0x0e, CReg
, 0, S1Reg
);
}
else
{
AddDest
(S1Reg
);
__erg
= CodeS
(0x0f, S1Reg
, 0, CReg
);
}
}
}
}
}
}
static void DecodeMVK
(Word Code
)
{
LongWord DReg
, S1Reg
;
Boolean OK
;
if (ChkArgCnt
(2, 2))
{
if (DecodeAdr
(&ArgStr
[2], MModReg
, True
, &DReg
))
if (ChkUnit
(DReg
, S1
, S2
))
{
if (Memo
("MVKLH"))
S1Reg
= EvalStrIntExpression
(&ArgStr
[1], Int16
, &OK
);
else if (Memo
("MVKL"))
S1Reg
= EvalStrIntExpression
(&ArgStr
[1], SInt16
, &OK
);
else
S1Reg
= EvalStrIntExpression
(&ArgStr
[1], Int32
, &OK
);
if (OK
)
{
AddDest
(DReg
);
ThisInst
= (DReg
<< 23) + (((S1Reg
>> Hi
(Code
)) & 0xffff) << 7) + (UnitFlag
<< 1) + Lo
(Code
);
__erg
= True
;
}
}
}
}
static void DecodeSHL
(Word Code
)
{
LongWord DReg
, S1Reg
, S2Reg
;
UNUSED
(Code
);
if (ChkArgCnt
(3, 3))
{
DecodeAdr
(&ArgStr
[3], MModReg
+ MModLReg
, True
, &DReg
);
if ((AdrMode
!= ModNone
) && (ChkUnit
(DReg
, S1
, S2
)))
switch (AdrMode
)
{
case ModReg
:
AddDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModReg
, True
, &S2Reg
))
{
if ((ThisCross
) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
);
SetCross
(S2Reg
);
DecodeAdr
(&ArgStr
[2], MModReg
+ MModImm
, False
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
:
if (IsCross
(S1Reg
)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S1Reg
);
__erg
= CodeS
(0x33, DReg
, S1Reg
, S2Reg
);
}
break;
case ModImm
:
__erg
= CodeS
(0x32, DReg
, S1Reg
, S2Reg
);
break;
}
}
}
break;
case ModLReg
:
AddLDest
(DReg
);
DecodeAdr
(&ArgStr
[1], MModReg
+ MModLReg
, True
, &S2Reg
);
switch (AdrMode
)
{
case ModReg
:
if ((ThisCross
) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
); SetCross
(S2Reg
);
DecodeAdr
(&ArgStr
[2], MModImm
+ MModReg
, False
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
:
if (IsCross
(S1Reg
)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S1Reg
);
__erg
= CodeS
(0x13, DReg
, S1Reg
, S2Reg
);
}
break;
case ModImm
:
__erg
= CodeS
(0x12, DReg
, S1Reg
, S2Reg
);
break;
}
}
break;
case ModLReg
:
if ((ThisCross
) || (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S2Reg
);
DecodeAdr
(&ArgStr
[2], MModImm
+ MModReg
, False
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
:
if (IsCross
(S1Reg
)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S1Reg
);
__erg
= CodeS
(0x31, DReg
, S1Reg
, S2Reg
);
}
break;
case ModImm
:
__erg
= CodeS
(0x30, DReg
, S1Reg
, S2Reg
);
break;
}
}
break;
}
break;
}
}
}
static void DecodeSHR_SHRU
(Word Code
)
{
LongWord DReg
, S1Reg
, S2Reg
;
Boolean HasSign
= Code
!= 0;
if (ChkArgCnt
(3, 3))
{
DecodeAdr
(&ArgStr
[3], MModReg
+ MModLReg
, HasSign
, &DReg
);
if ((AdrMode
!= ModNone
) && (ChkUnit
(DReg
, S1
, S2
)))
switch (AdrMode
)
{
case ModReg
:
AddDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModReg
, HasSign
, &S2Reg
))
{
if ((ThisCross
) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
); SetCross
(S2Reg
);
DecodeAdr
(&ArgStr
[2], MModReg
+ MModImm
, False
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
:
if (IsCross
(S1Reg
)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S1Reg
);
__erg
= CodeS
(0x27 + Code
, DReg
, S1Reg
, S2Reg
);
}
break;
case ModImm
:
__erg
= CodeS
(0x26 + Code
, DReg
, S1Reg
, S2Reg
);
break;
}
}
}
break;
case ModLReg
:
AddLDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModLReg
, HasSign
, &S2Reg
))
{
if ((ThisCross
) || (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S2Reg
);
DecodeAdr
(&ArgStr
[2], MModReg
+ MModImm
, False
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
:
if (IsCross
(S1Reg
)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S1Reg
);
__erg
= CodeS
(0x25 + Code
, DReg
, S1Reg
, S2Reg
);
}
break;
case ModImm
:
__erg
= CodeS
(0x24 + Code
, DReg
, S1Reg
, S2Reg
);
break;
}
}
}
break;
}
}
}
static void DecodeSSHL
(Word Code
)
{
LongWord DReg
, S1Reg
, S2Reg
;
UNUSED
(Code
);
if (ChkArgCnt
(3, 3))
{
if (DecodeAdr
(&ArgStr
[3], MModReg
, True
, &DReg
))
if (ChkUnit
(DReg
, S1
, S2
))
{
AddDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModReg
, True
, &S2Reg
))
{
if ((ThisCross
) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
); SetCross
(S2Reg
);
DecodeAdr
(&ArgStr
[2], MModReg
+ MModImm
, False
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
:
if (IsCross
(S1Reg
)) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S1Reg
);
__erg
= CodeS
(0x23, DReg
, S1Reg
, S2Reg
);
}
break;
case ModImm
:
__erg
= CodeS
(0x22, DReg
, S1Reg
, S2Reg
);
break;
}
}
}
}
}
}
static void DecodeSSUB
(Word Code
)
{
LongWord DReg
, S1Reg
, S2Reg
;
UNUSED
(Code
);
if (ChkArgCnt
(3, 3))
{
DecodeAdr
(&ArgStr
[3], MModReg
+ MModLReg
, True
, &DReg
);
if ((AdrMode
!= ModNone
) && (ChkUnit
(DReg
, L1
, L2
)))
switch (AdrMode
)
{
case ModReg
:
AddDest
(DReg
);
DecodeAdr
(&ArgStr
[1], MModReg
+ MModImm
, True
, &S1Reg
);
switch (AdrMode
)
{
case ModReg
:
AddSrc
(S1Reg
);
if (DecodeAdr
(&ArgStr
[2], MModReg
, True
, &S2Reg
))
{
if ((ThisCross
) && (!IsCross
(S1Reg
)) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else if ((IsCross
(S1Reg
)) && (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else if (IsCross
(S1Reg
))
{
ThisCross
= True
;
__erg
= CodeL
(0x1f, DReg
, S1Reg
, S2Reg
);
}
else
{
SetCross
(S2Reg
);
__erg
= CodeL
(0x0f, DReg
, S1Reg
, S2Reg
);
}
}
break;
case ModImm
:
if (DecodeAdr
(&ArgStr
[2], MModReg
, True
, &S2Reg
))
{
if ((ThisCross
) && (!IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddSrc
(S2Reg
); SetCross
(S2Reg
);
__erg
= CodeL
(0x0e, DReg
, S1Reg
, S2Reg
);
}
}
break;
}
break;
case ModLReg
:
AddLDest
(DReg
);
if (DecodeAdr
(&ArgStr
[1], MModImm
, True
, &S1Reg
))
{
if (DecodeAdr
(&ArgStr
[2], MModLReg
, True
, &S2Reg
))
{
if ((ThisCross
) || (IsCross
(S2Reg
))) WrError
(ErrNum_InvAddrMode
);
else
{
AddLSrc
(S2Reg
);
__erg
= CodeL
(0x2c, DReg
, S1Reg
, S2Reg
);
}
}
}
break;
}
}
}
/* Spruenge */
static void DecodeB
(Word Code
)
{
LongWord S2Reg
, Code1
;
LongInt Dist
;
Boolean WithImm
, OK
;
UNUSED
(Code
);
if (ArgCnt
!= 1) WrError
(ErrNum_InvAddrMode
);
else if (ThisCross
) WrError
(ErrNum_InvAddrMode
);
else if ((ThisUnit
!= NoUnit
) && (ThisUnit
!= S1
) && (ThisUnit
!= S2
)) WrError
(ErrNum_InvAddrMode
);
else
{
OK
= True
;
S2Reg
= 0;
WithImm
= False
;
Code1
= 0;
if (!as_strcasecmp
(ArgStr
[1].
str.
p_str, "IRP"))
{
Code1
= 0x03;
S2Reg
= 0x06;
}
else if (!as_strcasecmp
(ArgStr
[1].
str.
p_str, "NRP"))
{
Code1
= 0x03;
S2Reg
= 0x07;
}
else if (DecodeReg
(ArgStr
[1].
str.
p_str, &S2Reg
, &OK
, False
))
{
if (OK
) WrError
(ErrNum_InvAddrMode
);
OK
= !OK
;
Code1
= 0x0d;
}
else
WithImm
= OK
= True
;
if (OK
)
{
if (WithImm
)
{
tSymbolFlags Flags
;
if (ThisUnit
== NoUnit
)
ThisUnit
= (UnitUsed
(S1
)) ? S2
: S1
;
UnitFlag
= Ord
(ThisUnit
== S2
);
/* branches relative to fetch packet */
Dist
= EvalStrIntExpressionWithFlags
(&ArgStr
[1], Int32
, &OK
, &Flags
) - (PacketAddr
& (~
31));
if (OK
)
{
if ((Dist
& 3) != 0) WrError
(ErrNum_NotAligned
);
else if (!mSymbolQuestionable
(Flags
) && ((Dist
> 0x3fffff) || (Dist
< -0x400000))) WrError
(ErrNum_JmpDistTooBig
);
else
{
ThisInst
= 0x10 + ((Dist
& 0x007ffffc) << 5) + (UnitFlag
<< 1);
ThisAbsBranch
= True
;
__erg
= True
;
}
}
}
else
{
if (ChkUnit
(0x10, S1
, S2
))
{
SetCross
(S2Reg
);
__erg
= CodeS
(Code1
, 0, 0, S2Reg
);
}
}
}
}
}
static Boolean DecodeInst
(void)
{
__erg
= False
;
/* ueber Tabelle: */
if (LookupInstTable
(InstTable
, OpPart.
str.
p_str))
return __erg
;
WrStrErrorPos
(ErrNum_UnknownInstruction
, &OpPart
);
return False
;
}
static void ChkPacket
(void)
{
LongWord EndAddr
, Mask
;
LongInt z
, z1
, z2
;
Integer RegReads
[32];
char TestUnit
[4];
int BranchCnt
;
/* nicht ueber 8er-Grenze */
EndAddr
= PacketAddr
+ ((ParCnt
<< 2) - 1);
if ((PacketAddr
>> 5) != (EndAddr
>> 5))
WrError
(ErrNum_PackCrossBoundary
);
/* doppelte Units,Crosspaths,Adressierer,Zielregister */
for (z1
= 0; z1
< ParCnt
; z1
++)
for (z2
= z1
+ 1; z2
< ParCnt
; z2
++)
if ((ParRecs
[z1
].
OpCode >> 28) == (ParRecs
[z2
].
OpCode >> 28))
{
/* doppelte Units */
if ((ParRecs
[z1
].
U != NoUnit
) && (ParRecs
[z1
].
U == ParRecs
[z2
].
U))
WrXError
(ErrNum_UnitMultipleUsed
, UnitNames
[ParRecs
[z1
].
U]);
/* Crosspaths */
z
= ParRecs
[z1
].
CrossUsed & ParRecs
[z2
].
CrossUsed;
if (z
!= 0)
{
*TestUnit
= z
+ '0';
TestUnit
[1] = 'X';
TestUnit
[2] = '\0';
WrXError
(ErrNum_UnitMultipleUsed
, TestUnit
);
}
z
= ParRecs
[z1
].
AddrUsed & ParRecs
[z2
].
AddrUsed;
/* Adressgeneratoren */
if ((z
& 1) == 1) WrXError
(ErrNum_UnitMultipleUsed
, "Addr. A");
if ((z
& 2) == 2) WrXError
(ErrNum_UnitMultipleUsed
, "Addr. B");
/* Hauptspeicherpfade */
if ((z
& 4) == 4) WrXError
(ErrNum_UnitMultipleUsed
, "LdSt. A");
if ((z
& 8) == 8) WrXError
(ErrNum_UnitMultipleUsed
, "LdSt. B");
/* ueberlappende Zielregister */
z
= ParRecs
[z1
].
DestMask & ParRecs
[z2
].
DestMask;
if (z
!= 0)
WrXError
(ErrNum_OverlapDests
, RegName
(FindReg
(z
)));
if ((ParRecs
[z1
].
U & 1) == (ParRecs
[z2
].
U & 1))
{
TestUnit
[0] = ParRecs
[z1
].
U - NoUnit
- 1 + 'A';
TestUnit
[1] = '\0';
/* mehrere Long-Reads */
if ((ParRecs
[z1
].
LongSrc) && (ParRecs
[z2
].
LongSrc))
WrXError
(ErrNum_MultipleLongRead
, TestUnit
);
/* mehrere Long-Writes */
if ((ParRecs
[z1
].
LongDest) && (ParRecs
[z2
].
LongDest))
WrXError
(ErrNum_MultipleLongWrite
, TestUnit
);
/* Long-Read mit Store */
if ((ParRecs
[z1
].
StoreUsed) && (ParRecs
[z2
].
LongSrc))
WrXError
(ErrNum_LongReadWithStore
, TestUnit
);
if ((ParRecs
[z2
].
StoreUsed) && (ParRecs
[z1
].
LongSrc))
WrXError
(ErrNum_LongReadWithStore
, TestUnit
);
}
}
for (z2
= 0; z2
< 32; z2
++)
RegReads
[z2
] = 0;
for (z1
= 0; z1
< ParCnt
; z1
++)
{
Mask
= 1;
for (z2
= 0; z2
< 32; z2
++)
{
if ((ParRecs
[z1
].
SrcMask & Mask
) != 0)
RegReads
[z2
]++;
if ((ParRecs
[z1
].
SrcMask2 & Mask
) != 0)
RegReads
[z2
]++;
Mask
= Mask
<< 1;
}
}
/* Register mehr als 4mal gelesen */
for (z1
= 0; z1
< 32; z1
++)
if (RegReads
[z1
] > 4)
WrXError
(ErrNum_TooManyRegisterReads
, RegName
(z1
));
/* more than one branch to an absolute address */
BranchCnt
= 0;
for (z1
= 0; z1
< ParCnt
; z1
++)
if (ParRecs
[z1
].
AbsBranch)
BranchCnt
++;
if (BranchCnt
> 1)
WrError
(ErrNum_TooManyBranchesInExPacket
);
}
static void MakeCode_3206X
(void)
{
CodeLen
= 0; DontPrint
= False
;
/* zu ignorierendes */
if ((*OpPart.
str.
p_str == '\0') && (*LabPart.
str.
p_str == '\0'))
return;
/* Pseudoanweisungen */
if (DecodePseudo
())
return;
/* Flags zuruecksetzen */
ThisPar
= False
;
Condition
= 0;
/* Optionen aus Label holen */
if (*LabPart.
str.
p_str != '\0')
if ((!strcmp(LabPart.
str.
p_str, "||")) || (*LabPart.
str.
p_str == '['))
if (!CheckOpt
(LabPart.
str.
p_str))
return;
/* eventuell falsche Mnemonics verwerten */
if (!strcmp(OpPart.
str.
p_str, "||"))
if (!ReiterateOpPart
())
return;
if (*OpPart.
str.
p_str == '[')
if (!ReiterateOpPart
())
return;
if (Memo
(""))
return;
/* Attribut auswerten */
ThisUnit
= NoUnit
;
ThisCross
= False
;
if (*AttrPart.
str.
p_str)
{
if (as_toupper
(AttrPart.
str.
p_str[strlen(AttrPart.
str.
p_str) - 1]) == 'X')
{
ThisCross
= True
;
AttrPart.
str.
p_str[strlen(AttrPart.
str.
p_str) - 1] = '\0';
}
if (*AttrPart.
str.
p_str == '\0') ThisUnit
= NoUnit
;
else
for (; ThisUnit
!= LastUnit
; ThisUnit
++)
if (!as_strcasecmp
(AttrPart.
str.
p_str, UnitNames
[ThisUnit
]))
break;
if (ThisUnit
== LastUnit
)
{
WrError
(ErrNum_UndefAttr
);
return;
}
if (((ThisUnit
== D1
) || (ThisUnit
== D2
)) && (ThisCross
))
{
WrError
(ErrNum_InvAddrMode
);
return;
}
}
/* falls nicht parallel, vorherigen Stack durchpruefen und verwerfen */
if ((!ThisPar
) && (ParCnt
> 0))
{
ChkPacket
();
ParCnt
= 0;
PacketAddr
= EProgCounter
();
}
/* dekodieren */
ThisSrc
= 0;
ThisSrc2
= 0;
ThisDest
= 0;
ThisAddr
= 0;
ThisStore
= ThisAbsBranch
= False
;
ThisLong
= 0;
if (!DecodeInst
())
return;
/* einsortieren */
ParRecs
[ParCnt
].
OpCode = (Condition
<< 28) + ThisInst
;
ParRecs
[ParCnt
].
U = ThisUnit
;
if (ThisCross
)
switch (ThisUnit
)
{
case L1
: case S1
: case M1
: case D1
:
ParRecs
[ParCnt
].
CrossUsed = 1;
break;
default:
ParRecs
[ParCnt
].
CrossUsed = 2;
}
else
ParRecs
[ParCnt
].
CrossUsed = 0;
ParRecs
[ParCnt
].
AddrUsed = ThisAddr
;
ParRecs
[ParCnt
].
SrcMask = ThisSrc
;
ParRecs
[ParCnt
].
SrcMask2 = ThisSrc2
;
ParRecs
[ParCnt
].
DestMask = ThisDest
;
ParRecs
[ParCnt
].
LongSrc = ((ThisLong
& 1) == 1);
ParRecs
[ParCnt
].
LongDest = ((ThisLong
& 2) == 2);
ParRecs
[ParCnt
].
StoreUsed = ThisStore
;
ParRecs
[ParCnt
].
AbsBranch = ThisAbsBranch
;
ParCnt
++;
/* wenn mehr als eine Instruktion, Ressourcenkonflikte abklopfen und
vorherige Instruktion zuruecknehmen */
if (ParCnt
> 1)
{
RetractWords
(4);
DAsmCode
[CodeLen
>> 2] = ParRecs
[ParCnt
- 2].
OpCode | 1;
CodeLen
+= 4;
}
/* aktuelle Instruktion auswerfen: fuer letzte kein Parallelflag setzen */
DAsmCode
[CodeLen
>> 2] = ParRecs
[ParCnt
- 1].
OpCode;
CodeLen
+= 4;
}
/*-------------------------------------------------------------------------*/
static void AddLinAdd
(const char *NName
, LongInt NCode
)
{
order_array_rsv_end
(LinAddOrders
, FixedOrder
);
LinAddOrders
[InstrZ
].
Code = NCode
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeLinAdd
);
}
static void AddCmp
(const char *NName
, LongInt NCode
)
{
order_array_rsv_end
(CmpOrders
, CmpOrder
);
CmpOrders
[InstrZ
].
WithImm = NName
[strlen(NName
) - 1] != 'U';
CmpOrders
[InstrZ
].
Code = NCode
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeCmp
);
}
static void AddMem
(const char *NName
, LongInt NCode
, LongInt NScale
)
{
order_array_rsv_end
(MemOrders
, MemOrder
);
MemOrders
[InstrZ
].
Code = NCode
;
MemOrders
[InstrZ
].
Scale = NScale
;
AddInstTable
(InstTable
,NName
, InstrZ
++, DecodeMemO
);
}
static void AddMul
(const char *NName
, LongInt NCode
,
Boolean NDSign
, Boolean NSSign1
, Boolean NSSign2
, Boolean NMay
)
{
order_array_rsv_end
(MulOrders
, MulOrder
);
MulOrders
[InstrZ
].
Code = NCode
;
MulOrders
[InstrZ
].
DSign = NDSign
;
MulOrders
[InstrZ
].
SSign1 = NSSign1
;
MulOrders
[InstrZ
].
SSign2 = NSSign2
;
MulOrders
[InstrZ
].
MayImm = NMay
;
AddInstTable
(InstTable
, NName
, InstrZ
++, DecodeMul
);
}
static void AddCtrl
(const char *NName
, LongInt NCode
,
Boolean NWr
, Boolean NRd
)
{
order_array_rsv_end
(CtrlRegs
, CtrlReg
);
CtrlRegs
[InstrZ
].
Name = NName
;
CtrlRegs
[InstrZ
].
Code = NCode
;
CtrlRegs
[InstrZ
].
Wr = NWr
;
CtrlRegs
[InstrZ
++].
Rd = NRd
;
}
static void InitFields
(void)
{
InstTable
= CreateInstTable
(203);
AddInstTable
(InstTable
, "IDLE", 0, DecodeIDLE
);
AddInstTable
(InstTable
, "NOP", 0, DecodeNOP
);
AddInstTable
(InstTable
, "STP", 0, DecodeSTP
);
AddInstTable
(InstTable
, "ABS", 0, DecodeABS
);
AddInstTable
(InstTable
, "ADD", 0, DecodeADD
);
AddInstTable
(InstTable
, "ADDU", 0, DecodeADDU
);
AddInstTable
(InstTable
, "SUB", 0, DecodeSUB
);
AddInstTable
(InstTable
, "SUBU", 0, DecodeSUBU
);
AddInstTable
(InstTable
, "SUBC", 0, DecodeSUBC
);
AddInstTable
(InstTable
, "ADDK", 0, DecodeADDK
);
AddInstTable
(InstTable
, "ADD2", 0, DecodeADD2_SUB2
);
AddInstTable
(InstTable
, "SUB2", 1, DecodeADD2_SUB2
);
AddInstTable
(InstTable
, "AND", 0x1f7b, DecodeLogic
);
AddInstTable
(InstTable
, "OR", 0x1b7f, DecodeLogic
);
AddInstTable
(InstTable
, "XOR", 0x0b6f, DecodeLogic
);
AddInstTable
(InstTable
, "MV", 0, DecodeMV
);
AddInstTable
(InstTable
, "NEG", 0, DecodeNEG
);
AddInstTable
(InstTable
, "NOT", 0, DecodeNOT
);
AddInstTable
(InstTable
, "ZERO", 0, DecodeZERO
);
AddInstTable
(InstTable
, "CLR", 0x3fc8, DecodeCLR_EXT_EXTU_SET
);
AddInstTable
(InstTable
, "EXT", 0x2f48, DecodeCLR_EXT_EXTU_SET
);
AddInstTable
(InstTable
, "EXTU", 0x2b08, DecodeCLR_EXT_EXTU_SET
);
AddInstTable
(InstTable
, "SET", 0x3b88, DecodeCLR_EXT_EXTU_SET
);
AddInstTable
(InstTable
, "LMBD", 0, DecodeLMBD
);
AddInstTable
(InstTable
, "NORM", 0, DecodeNORM
);
AddInstTable
(InstTable
, "SADD", 0, DecodeSADD
);
AddInstTable
(InstTable
, "SAT", 0, DecodeSAT
);
AddInstTable
(InstTable
, "MVC", 0, DecodeMVC
);
AddInstTable
(InstTable
, "MVKL", 0x0028, DecodeMVK
);
AddInstTable
(InstTable
, "MVK", 0x0028, DecodeMVK
);
AddInstTable
(InstTable
, "MVKH", 0x1068, DecodeMVK
);
AddInstTable
(InstTable
, "MVKLH", 0x0068, DecodeMVK
);
AddInstTable
(InstTable
, "SHL", 0, DecodeSHL
);
AddInstTable
(InstTable
, "SHR", 16, DecodeSHR_SHRU
);
AddInstTable
(InstTable
, "SHRU", 0, DecodeSHR_SHRU
);
AddInstTable
(InstTable
, "SSHL", 0, DecodeSSHL
);
AddInstTable
(InstTable
, "SSUB", 0, DecodeSSUB
);
AddInstTable
(InstTable
, "B", 0, DecodeB
);
InstrZ
= 0;
AddLinAdd
("ADDAB", 0x30); AddLinAdd
("ADDAH", 0x34); AddLinAdd
("ADDAW", 0x38);
AddLinAdd
("SUBAB", 0x31); AddLinAdd
("SUBAH", 0x35); AddLinAdd
("SUBAW", 0x39);
InstrZ
= 0;
AddCmp
("CMPEQ", 0x50); AddCmp
("CMPGT", 0x44); AddCmp
("CMPGTU", 0x4c);
AddCmp
("CMPLT", 0x54); AddCmp
("CMPLTU", 0x5c);
InstrZ
= 0;
AddMem
("LDB", 2, 1); AddMem
("LDH", 4, 2); AddMem
("LDW", 6, 4);
AddMem
("LDBU", 1, 1); AddMem
("LDHU", 0, 2); AddMem
("STB", 3, 1);
AddMem
("STH", 5, 2); AddMem
("STW", 7, 4);
InstrZ
= 0;
AddMul
("MPY" , 0x19, True
, True
, True
, True
);
AddMul
("MPYU" , 0x1f, False
, False
, False
, False
);
AddMul
("MPYUS" , 0x1d, True
, False
, True
, False
);
AddMul
("MPYSU" , 0x1b, True
, True
, False
, True
);
AddMul
("MPYH" , 0x01, True
, True
, True
, False
);
AddMul
("MPYHU" , 0x07, False
, False
, False
, False
);
AddMul
("MPYHUS" , 0x05, True
, False
, True
, False
);
AddMul
("MPYHSU" , 0x03, True
, True
, False
, False
);
AddMul
("MPYHL" , 0x09, True
, True
, True
, False
);
AddMul
("MPYHLU" , 0x0f, False
, False
, False
, False
);
AddMul
("MPYHULS", 0x0d, True
, False
, True
, False
);
AddMul
("MPYHSLU", 0x0b, True
, True
, False
, False
);
AddMul
("MPYLH" , 0x11, True
, True
, True
, False
);
AddMul
("MPYLHU" , 0x17, False
, False
, False
, False
);
AddMul
("MPYLUHS", 0x15, True
, False
, True
, False
);
AddMul
("MPYLSHU", 0x13, True
, True
, False
, False
);
AddMul
("SMPY" , 0x1a, True
, True
, True
, False
);
AddMul
("SMPYHL" , 0x0a, True
, True
, True
, False
);
AddMul
("SMPYLH" , 0x12, True
, True
, True
, False
);
AddMul
("SMPYH" , 0x02, True
, True
, True
, False
);
InstrZ
= 0;
AddCtrl
("AMR" , 0, True
, True
);
AddCtrl
("CSR" , 1, True
, True
);
AddCtrl
("IFR" , 2, False
, True
);
AddCtrl
("ISR" , 2, True
, False
);
AddCtrl
("ICR" , 3, True
, False
);
AddCtrl
("IER" , 4, True
, True
);
AddCtrl
("ISTP" , 5, True
, True
);
AddCtrl
("IRP" , 6, True
, True
);
AddCtrl
("NRP" , 7, True
, True
);
AddCtrl
("IN" , 8, False
, True
);
AddCtrl
("OUT" , 9, True
, True
);
AddCtrl
("PCE1" , 16, False
, True
);
AddCtrl
("PDATA_O", 15, True
, True
);
AddCtrl
(NULL
, 0, False
, False
);
}
static void DeinitFields
(void)
{
DestroyInstTable
(InstTable
);
order_array_free
(LinAddOrders
);
order_array_free
(CmpOrders
);
order_array_free
(MemOrders
);
order_array_free
(MulOrders
);
order_array_free
(CtrlRegs
);
}
/*------------------------------------------------------------------------*/
static Boolean IsDef_3206X
(void)
{
return (!strcmp(LabPart.
str.
p_str, "||")) || (*LabPart.
str.
p_str == '[');
}
static void SwitchFrom_3206X
(void)
{
if (ParCnt
> 1)
ChkPacket
();
DeinitFields
();
if (ParRecs
)
{
free(ParRecs
);
ParRecs
= NULL
;
}
}
static Boolean Chk34Arg
(void)
{
return (ArgCnt
>= 3);
}
static void SwitchTo_3206X
(void)
{
TurnWords
= False
;
SetIntConstMode
(eIntConstModeIntel
);
SetIsOccupiedFnc
= Chk34Arg
;
PCSymbol
= "$";
HeaderID
= 0x47;
NOPCode
= 0x00000000;
DivideChars
= ",";
HasAttrs
= True
;
AttrChars
= ".";
ValidSegs
= 1 << SegCode
;
Grans
[SegCode
] = 1; ListGrans
[SegCode
] = 4; SegInits
[SegCode
] = 0;
SegLimits
[SegCode
] = (LargeWord
)IntTypeDefs
[UInt32
].
Max;
MakeCode
= MakeCode_3206X
;
IsDef
= IsDef_3206X
;
SwitchFrom
= SwitchFrom_3206X
;
ParRecs
= (InstrRec
*)malloc(sizeof(InstrRec
) * MaxParCnt
);
InitFields
();
onoff_packing_add
(True
);
ParCnt
= 0;
PacketAddr
= 0;
}
void code3206x_init
(void)
{
CPU32060
= AddCPU
("32060", SwitchTo_3206X
);
}