From 333b605b2afd472b823aeda0adf0e8b1ea9843c0 Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Mon, 27 May 2019 02:41:51 +0100 Subject: initial commit from asl-1.41r8.tar.gz --- code3206x.c | 2313 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2313 insertions(+) create mode 100644 code3206x.c (limited to 'code3206x.c') diff --git a/code3206x.c b/code3206x.c new file mode 100644 index 0000000..de0be1b --- /dev/null +++ b/code3206x.c @@ -0,0 +1,2313 @@ +/* code3206x.c */ +/*****************************************************************************/ +/* AS-Portierung */ +/* */ +/* Codegenerator TMS320C6x */ +/* */ +/* Historie: 24. 2.1997 Grundsteinlegung */ +/* 22. 5.1998 Schoenheitsoperatioenen fuer K&R-Compiler */ +/* 3. 1.1999 ChkPC-Anpassung */ +/* 23. 1.1999 DecodeCtrlReg jetzt mit unsigned-Ergebnis */ +/* 30. 1.1999 Formate maschinenunabhaengig gemacht */ +/* */ +/*****************************************************************************/ + +#include "stdinc.h" +#include +#include + +#include "strutil.h" +#include "bpemu.h" +#include "nls.h" +#include "asmdef.h" +#include "asmsub.h" +#include "asmpars.h" +#include "asmcode.h" +#include "codepseudo.h" +#include "asmitree.h" + +/*---------------------------------------------------------------------------*/ + +typedef enum {NoUnit,L1,L2,S1,S2,M1,M2,D1,D2,LastUnit,UnitCnt} TUnit; + +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 StoreUsed,LongSrc,LongDest; + TUnit U; + } InstrRec; + +typedef struct + { + char *Name; + LongInt Code; + } FixedOrder; + +typedef struct + { + char *Name; + LongInt Code; + LongInt Scale; + } MemOrder; + +typedef struct + { + char *Name; + LongInt Code; + Boolean DSign,SSign1,SSign2; + Boolean MayImm; + } MulOrder; + +typedef struct + { + char *Name; + LongInt Code; + Boolean Rd,Wr; + } CtrlReg; + +static char *UnitNames[UnitCnt]={" ","L1","L2","S1","S2","M1","M2","D1","D2"," "}; +#define MaxParCnt 8 +#define FirstUnit L1 + +#define LinAddCnt 6 +#define CmpCnt 5 +#define MemCnt 8 +#define MulCnt 20 +#define CtrlCnt 13 + +#define ModNone (-1) +#define ModReg 0 +#define MModReg (1 << ModReg) +#define ModLReg 1 +#define MModLReg (1 << ModLReg) +#define ModImm 2 +#define MModImm (1 << ModImm) + +static ShortInt AdrMode; + +static CPUVar CPU32060; + +static Boolean ThisPar,ThisCross,ThisStore; +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[MaxParCnt]; + +FixedOrder *LinAddOrders; +FixedOrder *CmpOrders; +MemOrder *MemOrders; +MulOrder *MulOrders; +CtrlReg *CtrlRegs; +PInstTable InstTable; + +/*-------------------------------------------------------------------------*/ + + static Boolean CheckOpt(char *Asc) +BEGIN + Boolean Flag,erg=True; + int l=strlen(Asc); + + if (strcmp(Asc,"||")==0) ThisPar=True; + else if ((*Asc=='[') AND (Asc[l-1]==']')) + BEGIN + Asc++; Asc[l-2]='\0'; l-=2; + if (*Asc=='!') + BEGIN + Asc++; l--; Condition=1; + END + else Condition=0; + Flag=True; + if (l!=2) Flag=False; + else if (toupper(*Asc)=='A') + if ((Asc[1]>='1') AND (Asc[1]<='2')) Condition+=(Asc[1]-'0'+3) << 1; + else Flag=False; + else if (toupper(*Asc)=='B') + if ((Asc[1]>='0') AND (Asc[1]<='2')) Condition+=(Asc[1]-'0'+1) << 1; + else Flag=False; + if (NOT Flag) WrXError(1445,Asc); erg=Flag; + END + else erg=False; + + return erg; +END + + static Boolean ReiterateOpPart(void) +BEGIN + char *p; + int z; + + if (NOT CheckOpt(OpPart)) return False; + + if (ArgCnt<1) + BEGIN + WrError(1210); return False; + END + p=FirstBlank(ArgStr[1]); + if (p==Nil) + BEGIN + strcpy(OpPart,ArgStr[1]); + for (z=2; z<=ArgCnt; z++) strcpy(ArgStr[z-1],ArgStr[z]); + ArgCnt--; + END + else + BEGIN + *p='\0'; strcpy(OpPart,ArgStr[1]); strcpy(ArgStr[1],p+1); + KillPrefBlanks(ArgStr[1]); + END + NLS_UpString(OpPart); + p=strchr(OpPart,'.'); + if (p==Nil) *AttrPart='\0'; + else + BEGIN + strcpy(AttrPart,p+1); + *p='\0'; + END; + return True; +END + +/*-------------------------------------------------------------------------*/ + + static void AddSrc(LongWord Reg) +BEGIN + LongWord Mask=1 << Reg; + + if ((ThisSrc & Mask)==0) ThisSrc|=Mask; + else ThisSrc2|=Mask; +END + + static void AddLSrc(LongWord Reg) +BEGIN + AddSrc(Reg); AddSrc(Reg+1); + ThisLong|=1; +END + + static void AddDest(LongWord Reg) +BEGIN + ThisDest|=(1 << Reg); +END + + static void AddLDest(LongWord Reg) +BEGIN + ThisDest|=(3 << Reg); + ThisLong|=2; +END + + static LongInt FindReg(LongInt Mask) +BEGIN + int z; + + for (z=0; z<32; z++) + BEGIN + if ((Mask&1)!=0) break; + Mask=Mask >> 1; + END + return z; +END + + static char *RegName(LongInt Num) +BEGIN + static char s[5]; + + Num&=31; + sprintf(s, "%c%ld", 'A' + (Num >> 4), (long) (Num & 15)); + return s; +END + + static Boolean DecodeSReg(char *Asc, LongWord *Reg, Boolean Quarrel) +BEGIN + char *end; + Byte RVal; + Boolean TFlag; + + TFlag=True; + if (toupper(*Asc)=='A') *Reg=0; + else if (toupper(*Asc)=='B') *Reg=16; + else TFlag=False; + if (TFlag) + BEGIN + RVal=strtol(Asc+1,&end,10); + if (*end!='\0') TFlag=False; + else if (RVal>15) TFlag=False; + else *Reg+=RVal; + END + if ((NOT TFlag) AND (Quarrel)) WrXError(1445,Asc); + return TFlag; +END + + static Boolean DecodeReg(char *Asc, LongWord *Reg, Boolean *PFlag, Boolean Quarrel) +BEGIN + char *p; + LongWord NextReg; + + p=strchr(Asc,':'); + if (p==0) + BEGIN + *PFlag=False; return DecodeSReg(Asc,Reg,Quarrel); + END + else + BEGIN + *PFlag=True; *p='\0'; + if (NOT DecodeSReg(Asc,&NextReg,Quarrel)) return False; + else if (NOT DecodeSReg(p+1,Reg,Quarrel)) return False; + else if ((Odd(*Reg)) OR (NextReg!=(*Reg)+1) OR ((((*Reg) ^ NextReg) & 0x10)!=0)) + BEGIN + if (Quarrel) WrXError(1760,Asc); return False; + END + else return True; + END +END + + static Boolean DecodeCtrlReg(char *Asc, LongWord *Erg, Boolean Write) +BEGIN + int z; + + for (z=0; z Skalierungsgroesse bei Autoinkrement/De- + krement, sonst 0 */ + + if (*DispPart=='\0') + DispAcc=(Mode<2) ? 0 : Scale; + + /* Register als Offsetfeld? Dann Bit 2 in Modus setzen */ + + else if (DecodeSReg(DispPart,&IndReg,False)) + BEGIN + if ((IndReg ^ BaseReg)>15) + BEGIN + WrError(1350); return False; + END + Mode+=4; AddSrc(DispAcc=IndReg); + END + + /* ansonsten normaler Offset */ + + else + BEGIN + FirstPassUnknown=False; + DispAcc=EvalIntExpression(DispPart,UInt15,&OK); + if (NOT OK) return False; + if (FirstPassUnknown) DispAcc&=7; + if (Counter==']') DispAcc*=Scale; + END + + /* Benutzung des Adressierers markieren */ + + ThisAddr|=(BaseReg>15) ? 2 : 1; + + /* Wenn Offset>31, muessen wir Variante 2 benutzen */ + + if (((Mode & 4)==0) AND (DispAcc>31)) + if ((BaseReg<0x1e) OR (Mode!=1)) WrError(1350); + else + BEGIN + *Erg=((DispAcc & 0x7fff) << 8)+((BaseReg & 1) << 7)+12; + return True; + END + + else + BEGIN + *Erg=(BaseReg << 18)+((DispAcc & 0x1f) << 13)+(Mode << 9) + +((BaseReg & 0x10) << 3)+4; + return True; + END + + return False; +END + + static Boolean DecodeAdr(char *Asc, Byte Mask, Boolean Signed, LongWord *AdrVal) +BEGIN + Boolean OK; + + AdrMode=ModNone; + + if (DecodeReg(Asc,AdrVal,&OK,False)) + BEGIN + AdrMode=(OK) ? ModLReg : ModReg; + END + else + BEGIN + if (Signed) *AdrVal=EvalIntExpression(Asc,SInt5,&OK) & 0x1f; + else *AdrVal=EvalIntExpression(Asc,UInt5,&OK); + if (OK) AdrMode=ModImm; + END + + if ((AdrMode!=ModNone) AND (((1 << AdrMode) AND Mask)==0)) + BEGIN + WrError(1350); AdrMode=ModNone; return False; + END + else return True; +END + + static Boolean ChkUnit(LongWord Reg, TUnit U1, TUnit U2) +BEGIN + UnitFlag=Ord(Reg>15); + if (ThisUnit==NoUnit) + BEGIN + ThisUnit=(Reg>15) ? U2 : U1; + return True; + END + else if (((ThisUnit==U1) AND (Reg<16)) OR ((ThisUnit==U2) AND (Reg>15))) return True; + else + BEGIN + WrError(1107); return False; + END +END + + static TUnit UnitCode(char c) +BEGIN + switch (c) + BEGIN + case 'L': return L1; + case 'S': return S1; + case 'D': return D1; + case 'M': return M1; + default: return NoUnit; + END +END + + static Boolean UnitUsed(TUnit TestUnit) +BEGIN + Integer z; + + for (z=0; z> 4)!=UnitFlag; +END + + static void SetCross(LongWord Reg) +BEGIN + ThisCross=((Reg >> 4)!=UnitFlag); +END + + static Boolean DecideUnit(LongWord Reg, char *Units) +BEGIN + Integer z; + TUnit TestUnit; + + if (ThisUnit==NoUnit) + BEGIN + z=0; + while ((Units[z]!='\0') AND (ThisUnit==NoUnit)) + BEGIN + TestUnit=UnitCode(Units[z]); + if (Reg>=16) TestUnit++; + if (NOT UnitUsed(TestUnit)) ThisUnit=TestUnit; + z++; + END + if (ThisUnit==NoUnit) + BEGIN + ThisUnit=UnitCode(*Units); + if (Reg>16) TestUnit++; + END + END + UnitFlag=(ThisUnit-FirstUnit) & 1; + if (IsCross(Reg)) + BEGIN + WrError(1107); return False; + END + else return True; +END + + static void SwapReg(LongWord *r1, LongWord *r2) +BEGIN + LongWord tmp; + + tmp=(*r1); *r1=(*r2); *r2=tmp; +END + + static Boolean DecodePseudo(void) +BEGIN + return False; +END + + + static Boolean CodeL(LongWord OpCode,LongWord Dest,LongWord Src1,LongWord Src2) +BEGIN + ThisInst=0x18+(OpCode << 5)+(UnitFlag << 1)+(Ord(ThisCross) << 12) + +(Dest << 23)+(Src2 << 18)+(Src1 << 13); + return True; +END + + static Boolean CodeM(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2) +BEGIN + ThisInst=0x00+(OpCode << 7)+(UnitFlag << 1)+(Ord(ThisCross) << 12) + +(Dest << 23)+(Src2 << 18)+(Src1 << 13); + return True; +END + + static Boolean CodeS(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2) +BEGIN + ThisInst=0x20+(OpCode << 6)+(UnitFlag << 1)+(Ord(ThisCross) << 12) + +(Dest << 23)+(Src2 << 18)+(Src1 << 13); + return True; +END + + static Boolean CodeD(LongWord OpCode, LongWord Dest, LongWord Src1, LongWord Src2) +BEGIN + ThisInst=0x40+(OpCode << 7)+(UnitFlag << 1) + +(Dest << 23)+(Src2 << 18)+(Src1 << 13); + return True; +END + +/*-------------------------------------------------------------------------*/ + +static Boolean __erg; + + static void DecodeIDLE(Word Index) +BEGIN + if (ArgCnt!=0) WrError(1110); + else if ((ThisCross) OR (ThisUnit!=NoUnit)) WrError(1107); + else + BEGIN + ThisInst=0x0001e000; __erg=True; + END +END + + static void DecodeNOP(Word Index) +BEGIN + LongInt Count; + Boolean OK; + + if ((ArgCnt!=0) AND (ArgCnt!=1)) WrError(1110); + else if ((ThisCross) OR (ThisUnit!=NoUnit)) WrError(1107); + else + BEGIN + if (ArgCnt==0) + BEGIN + OK=True; Count=0; + END + else + BEGIN + FirstPassUnknown=False; + Count=EvalIntExpression(ArgStr[1],UInt4,&OK); + if (FirstPassUnknown) Count=0; else Count--; + OK=ChkRange(Count,0,8); + END + if (OK) + BEGIN + ThisInst=Count << 13; __erg=True; + END + END +END + + static void DecodeMul(Word Index) +BEGIN + LongWord DReg,S1Reg,S2Reg; + MulOrder *POrder=MulOrders+Index; + + if (ArgCnt!=3) WrError(1110); + else + BEGIN + if (DecodeAdr(ArgStr[3],MModReg,POrder->DSign,&DReg)) + if (ChkUnit(DReg,M1,M2)) + BEGIN + if (DecodeAdr(ArgStr[2],MModReg,POrder->SSign2,&S2Reg)) + BEGIN + AddSrc(S2Reg); + DecodeAdr(ArgStr[1],(POrder->MayImm?MModImm:0)+MModReg, + POrder->SSign1,&S1Reg); + switch (AdrMode) + BEGIN + case ModReg: + if ((ThisCross) AND (NOT IsCross(S2Reg)) AND (NOT IsCross(S1Reg))) WrError(1350); + else if ((IsCross(S2Reg)) AND (IsCross(S1Reg))) WrError(1350); + else + BEGIN + if (IsCross(S1Reg)) SwapReg(&S1Reg,&S2Reg); + SetCross(S2Reg); + AddSrc(S1Reg); + __erg=CodeM(POrder->Code,DReg,S1Reg,S2Reg); + END + break; + case ModImm: + if (Memo("MPY")) __erg=CodeM(POrder->Code-1,DReg,S1Reg,S2Reg); + else __erg=CodeM(POrder->Code+3,DReg,S1Reg,S2Reg); + break; + END + END + END + END +END + + static void DecodeMemO(Word Index) +BEGIN + LongWord DReg,S1Reg; + MemOrder *POrder=MemOrders+Index; + Boolean OK,IsStore; + + if (ArgCnt!=2) WrError(1110); + else + BEGIN + IsStore=(*OpPart)=='S'; + if (IsStore) + BEGIN + strcpy(ArgStr[3],ArgStr[1]); strcpy(ArgStr[1],ArgStr[2]); + strcpy(ArgStr[2],ArgStr[3]); + ThisStore=True; + END + if (DecodeAdr(ArgStr[2],MModReg,False,&DReg)) + BEGIN + if (IsStore) AddSrc(DReg); + ThisAddr|=(DReg>15) ? 8 : 4; + /* Zielregister 4 Takte verzoegert, nicht als Dest eintragen */ + OK=DecodeMem(ArgStr[1],&S1Reg,POrder->Scale); + if (OK) + if ((S1Reg & 8)==0) OK=ChkUnit((S1Reg >> 18) & 31,D1,D2); + else OK=ChkUnit(0x1e,D1,D2); + if (OK) + BEGIN + ThisInst=S1Reg+(DReg << 23)+(POrder->Code << 4) + +((DReg & 16) >> 3); + __erg=True; + END + END; + END +END + + static void DecodeSTP(Word Index) +BEGIN + LongWord S2Reg; + + if (ArgCnt!=1) WrError(1110); + else if (ChkUnit(0x10,S1,S2)) + BEGIN + if (DecodeAdr(ArgStr[1],MModReg,False,&S2Reg)) + if ((ThisCross) OR (S2Reg<16)) WrError(1110); + else + BEGIN + AddSrc(S2Reg); + __erg=CodeS(0x0c,0,0,S2Reg); + END + END +END + + static void DecodeABS(Word Index) +BEGIN + Boolean DPFlag,S1Flag; + LongWord DReg,S1Reg; + + if (ArgCnt!=2) WrError(1110); + else if (DecodeReg(ArgStr[2],&DReg,&DPFlag,True)) + if (ChkUnit(DReg,L1,L2)) + if (DecodeReg(ArgStr[1],&S1Reg,&S1Flag,True)) + if (DPFlag!=S1Flag) WrError(1350); + else if ((ThisCross) AND ((S1Reg >> 4)==UnitFlag)) WrError(1350); + else + BEGIN + SetCross(S1Reg); + if (DPFlag) __erg=CodeL(0x38,DReg,0,S1Reg); + else __erg=CodeL(0x1a,DReg,0,S1Reg); + if (DPFlag) AddLSrc(S1Reg); else AddSrc(S1Reg); + if (DPFlag) AddLDest(DReg); else AddDest(DReg); + END +END + + static void DecodeADD(Word Index) +BEGIN + LongWord S1Reg,S2Reg,DReg; + Boolean OK; + + if (ArgCnt!=3) WrError(1110); + else + BEGIN + DecodeAdr(ArgStr[3],MModReg+MModLReg,True,&DReg); + UnitFlag=DReg >> 4; + switch (AdrMode) + BEGIN + case ModLReg: /* ADD ?,?,long */ + AddLDest(DReg); + DecodeAdr(ArgStr[1],MModReg+MModLReg+MModImm,True,&S1Reg); + switch (AdrMode) + BEGIN + case ModReg: /* ADD int,?,long */ + AddSrc(S1Reg); + DecodeAdr(ArgStr[2],MModReg+MModLReg,True,&S2Reg); + switch (AdrMode) + BEGIN + case ModReg: /* ADD int,int,long */ + if (ChkUnit(DReg,L1,L2)) + if ((ThisCross) AND (NOT IsCross(S1Reg)) AND (NOT IsCross(S2Reg))) WrError(1350); + else if ((IsCross(S1Reg)) AND (IsCross(S2Reg))) WrError(1350); + else + BEGIN + AddSrc(S2Reg); + if (IsCross(S1Reg)) SwapReg(&S1Reg,&S2Reg); + SetCross(S2Reg); + __erg=CodeL(0x23,DReg,S1Reg,S2Reg); + END + break; + case ModLReg:/* ADD int,long,long */ + if (ChkUnit(DReg,L1,L2)) + if (IsCross(S2Reg)) WrError(1350); + else if ((ThisCross) AND (NOT IsCross(S1Reg))) WrError(1350); + else + BEGIN + AddLSrc(S2Reg); + SetCross(S1Reg); + __erg=CodeL(0x21,DReg,S1Reg,S2Reg); + END + break; + END + break; + case ModLReg: /* ADD long,?,long */ + AddLSrc(S1Reg); + DecodeAdr(ArgStr[2],MModReg+MModImm,True,&S2Reg); + switch (AdrMode) + BEGIN + case ModReg: /* ADD long,int,long */ + if (ChkUnit(DReg,L1,L2)) + if (IsCross(S1Reg)) WrError(1350); + else if ((ThisCross) AND (NOT IsCross(S2Reg))) WrError(1350); + else + BEGIN + AddSrc(S2Reg); + SetCross(S2Reg); + __erg=CodeL(0x21,DReg,S2Reg,S1Reg); + END + break; + case ModImm: /* ADD long,imm,long */ + if (ChkUnit(DReg,L1,L2)) + if (IsCross(S1Reg)) WrError(1350); + else if (ThisCross) WrError(1350); + else __erg=CodeL(0x20,DReg,S2Reg,S1Reg); + break; + END + break; + case ModImm: /* ADD imm,?,long */ + if (DecodeAdr(ArgStr[2],MModLReg,True,&S2Reg)) + BEGIN /* ADD imm,long,long */ + if (ChkUnit(DReg,L1,L2)) + if (IsCross(S2Reg)) WrError(1350); + else if (ThisCross) WrError(1350); + else + BEGIN + AddLSrc(S2Reg); + __erg=CodeL(0x20,DReg,S1Reg,S2Reg); + END + END + break; + END + break; + case ModReg: /* ADD ?,?,int */ + AddDest(DReg); + DecodeAdr(ArgStr[1],MModReg+MModImm,True,&S1Reg); + switch (AdrMode) + BEGIN + case ModReg: /* ADD int,?,int */ + AddSrc(S1Reg); + DecodeAdr(ArgStr[2],MModReg+MModImm,True,&S2Reg); + switch (AdrMode) + BEGIN + case ModReg: /* ADD int,int,int */ + AddSrc(S2Reg); + if (((DReg^S1Reg)>15) AND ((DReg^S2Reg)>15)) WrError(1350); + else if ((ThisCross) AND ((DReg^S1Reg)<16) AND ((DReg^S2Reg)<15)) WrError(1350); + else + BEGIN + if ((S1Reg^DReg)>15) SwapReg(&S1Reg,&S2Reg); + OK=DecideUnit(DReg,((S2Reg^DReg)>15) ? "LS" : "LSD"); + if (OK) + BEGIN + switch (ThisUnit) + BEGIN + case L1: case L2: __erg=CodeL(0x03,DReg,S1Reg,S2Reg); break; /* ADD.Lx int,int,int */ + case S1: case S2: __erg=CodeS(0x07,DReg,S1Reg,S2Reg); break; /* ADD.Sx int,int,int */ + case D1: case D2: __erg=CodeD(0x10,DReg,S1Reg,S2Reg); break; /* ADD.Dx int,int,int */ + default: WrError(20000); + END + END + END + break; + case ModImm: /* ADD int,imm,int */ + if ((ThisCross) AND ((S1Reg^DReg)<16)) WrError(1350); + else + BEGIN + SetCross(S1Reg); + if (DecideUnit(DReg,"LS")) + switch (ThisUnit) + BEGIN + case L1: case L2: __erg=CodeL(0x02,DReg,S2Reg,S1Reg); break; + case S1: case S2: __erg=CodeS(0x06,DReg,S2Reg,S1Reg); break; + default: WrError(20000); + END + END + break; + END + break; + case ModImm: /* ADD imm,?,int */ + if (DecodeAdr(ArgStr[2],MModReg,True,&S2Reg)) + BEGIN + AddSrc(S2Reg); + if ((ThisCross) AND ((S2Reg^DReg)<16)) WrError(1350); + else + BEGIN + SetCross(S2Reg); + if (DecideUnit(DReg,"LS")) + switch (ThisUnit) + BEGIN + case L1: case L2: __erg=CodeL(0x02,DReg,S1Reg,S2Reg); break; + case S1: case S2: __erg=CodeS(0x06,DReg,S1Reg,S2Reg); break; + default: WrError(20000); + END + END + END + break; + END + break; + END + END +END + + static void DecodeADDU(Word Index) +BEGIN + LongWord DReg,S1Reg,S2Reg; + + if (ArgCnt!=3) WrError(1110); + else + BEGIN + DecodeAdr(ArgStr[3],MModReg+MModLReg,False,&DReg); + switch (AdrMode) + BEGIN + case ModReg: /* ADDU ?,?,int */ + if (ChkUnit(DReg,D1,D2)) + BEGIN + AddDest(DReg); + DecodeAdr(ArgStr[1],MModReg+MModImm,False,&S1Reg); + switch (AdrMode) + BEGIN + case ModReg: /* ADDU int,?,int */ + if (IsCross(S1Reg)) WrError(1350); + else + BEGIN + AddSrc(S1Reg); + if (DecodeAdr(ArgStr[2],MModImm,False,&S2Reg)) + __erg=CodeD(0x12,DReg,S2Reg,S1Reg); + END + break; + case ModImm: /* ADDU imm,?,int */ + if (DecodeAdr(ArgStr[2],MModReg,False,&S2Reg)) + if (IsCross(S2Reg)) WrError(1350); + else + BEGIN + AddSrc(S2Reg); + __erg=CodeD(0x12,DReg,S1Reg,S2Reg); + END + break; + END + END + break; + case ModLReg: /* ADDU ?,?,long */ + if (ChkUnit(DReg,L1,L2)) + BEGIN + AddLDest(DReg); + DecodeAdr(ArgStr[1],MModReg+MModLReg,False,&S1Reg); + switch (AdrMode) + BEGIN + case ModReg: /* ADDU int,?,long */ + AddSrc(S1Reg); + DecodeAdr(ArgStr[2],MModReg+MModLReg,False,&S2Reg); + switch (AdrMode) + BEGIN + case ModReg: /* ADDU int,int,long */ + if ((IsCross(S1Reg)) AND (IsCross(S2Reg))) WrError(1350); + else if ((ThisCross) AND (((S1Reg^DReg)<16) AND ((S2Reg^DReg)<16))) WrError(1350); + else + BEGIN + if ((S1Reg^DReg)>15) SwapReg(&S1Reg,&S2Reg); + SetCross(S2Reg); + __erg=CodeL(0x2b,DReg,S1Reg,S2Reg); + END + break; + case ModLReg: /* ADDU int,long,long */ + if (IsCross(S2Reg)) WrError(1350); + else if ((ThisCross) AND ((S1Reg^DReg)<16)) WrError(1350); + else + BEGIN + AddLSrc(S2Reg); + SetCross(S1Reg); + __erg=CodeL(0x29,DReg,S1Reg,S2Reg); + END + break; + END + break; + case ModLReg: + if (IsCross(S1Reg)) WrError(1350); + else + BEGIN + AddLSrc(S1Reg); + if (DecodeAdr(ArgStr[2],MModReg,False,&S2Reg)) + if ((ThisCross) AND ((S2Reg^DReg)<16)) WrError(1350); + else + BEGIN + AddSrc(S2Reg); SetCross(S2Reg); + __erg=CodeL(0x29,DReg,S2Reg,S1Reg); + END + END + break; + END + END + break; + END + END +END + + static void DecodeSUB(Word Index) +BEGIN + LongWord DReg,S1Reg,S2Reg; + Boolean OK; + + if (ArgCnt!=3) WrError(1110); + else + BEGIN + DecodeAdr(ArgStr[3],MModReg+MModLReg,True,&DReg); + switch (AdrMode) + BEGIN + case ModReg: + AddDest(DReg); + DecodeAdr(ArgStr[1],MModReg+MModImm,True,&S1Reg); + switch (AdrMode) + BEGIN + case ModReg: + AddSrc(S1Reg); + DecodeAdr(ArgStr[2],MModReg+MModImm,True,&S2Reg); + switch (AdrMode) + BEGIN + case ModReg: + if ((ThisCross) AND ((S1Reg^DReg)<16) AND ((S2Reg^DReg)<16)) WrError(1350); + else if (((S1Reg^DReg)>15) AND ((S2Reg^DReg)>15)) WrError(1350); + else + BEGIN + AddSrc(S2Reg); + ThisCross=((S1Reg^DReg)>15) OR ((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) + BEGIN + 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(20000); + END + END + break; + case ModImm: + if (ChkUnit(DReg,D1,D2)) + if ((ThisCross) OR ((S1Reg^DReg)>15)) WrError(1350); + else __erg=CodeD(0x13,DReg,S2Reg,S1Reg); + break; + END + break; + case ModImm: + if (DecodeAdr(ArgStr[2],MModReg,True,&S2Reg)) + if ((ThisCross) AND ((S2Reg^DReg)<16)) WrError(1350); + else + BEGIN + AddSrc(S2Reg); + if (DecideUnit(DReg,"LS")) + switch (ThisUnit) + BEGIN + case L1: case L2: __erg=CodeL(0x06,DReg,S1Reg,S2Reg); break; + case S1: case S2: __erg=CodeS(0x16,DReg,S1Reg,S2Reg); break; + default: WrError(20000); + END + END + break; + END + break; + case ModLReg: + AddLDest(DReg); + if (ChkUnit(DReg,L1,L2)) + BEGIN + DecodeAdr(ArgStr[1],MModImm+MModReg,True,&S1Reg); + switch (AdrMode) + BEGIN + case ModImm: + if (DecodeAdr(ArgStr[2],MModLReg,True,&S2Reg)) + if ((ThisCross) OR (NOT IsCross(S2Reg))) WrError(1350); + else + BEGIN + AddLSrc(S2Reg); + __erg=CodeL(0x24,DReg,S1Reg,S2Reg); + END + break; + case ModReg: + AddSrc(S1Reg); + if (DecodeAdr(ArgStr[2],MModReg,True,&S2Reg)) + if ((ThisCross) AND (NOT IsCross(S1Reg)) AND (NOT IsCross(S2Reg))) WrError(1350); + else if ((IsCross(S1Reg)) AND (IsCross(S2Reg))) WrError(1350); + else + BEGIN + AddSrc(S2Reg); + ThisCross=(IsCross(S1Reg)) OR (IsCross(S2Reg)); + if (IsCross(S1Reg)) __erg=CodeL(0x37,DReg,S1Reg,S2Reg); + else __erg=CodeL(0x47,DReg,S1Reg,S2Reg); + END + break; + END + END + break; + END + END +END + + static void DecodeSUBU(Word Index) +BEGIN + LongWord S1Reg,S2Reg,DReg; + + if (ArgCnt!=3) WrError(1110); + else + BEGIN + if ((DecodeAdr(ArgStr[3],MModLReg,False,&DReg)) AND (ChkUnit(DReg,L1,L2))) + BEGIN + AddLDest(DReg); + if (DecodeAdr(ArgStr[1],MModReg,False,&S1Reg)) + BEGIN + AddSrc(S1Reg); + if (DecodeAdr(ArgStr[2],MModReg,False,&S2Reg)) + if ((ThisCross) AND (NOT IsCross(S1Reg)) AND (NOT IsCross(S2Reg))) WrError(1350); + else if ((IsCross(S1Reg)) AND (IsCross(S2Reg))) WrError(1350); + else + BEGIN + AddSrc(S2Reg); + ThisCross=IsCross(S1Reg) OR IsCross(S2Reg); + if (IsCross(S1Reg)) __erg=CodeL(0x3f,DReg,S1Reg,S2Reg); + else __erg=CodeL(0x2f,DReg,S1Reg,S2Reg); + END + END + END + END +END + + static void DecodeSUBC(Word Index) +BEGIN + LongWord DReg,S1Reg,S2Reg; + + if (ArgCnt!=3) WrError(1110); + else + BEGIN + if ((DecodeAdr(ArgStr[3],MModReg,False,&DReg)) AND (ChkUnit(DReg,L1,L2))) + BEGIN + AddLDest(DReg); + if (DecodeAdr(ArgStr[1],MModReg,False,&S1Reg)) + BEGIN + if (DecodeAdr(ArgStr[2],MModReg,False,&S2Reg)) + if ((ThisCross) AND (NOT IsCross(S2Reg))) WrError(1350); + else if (IsCross(S1Reg)) WrError(1350); + else + BEGIN + AddSrc(S2Reg); SetCross(S2Reg); + __erg=CodeL(0x4b,DReg,S1Reg,S2Reg); + END + END + END + END +END + + static void DecodeLinAdd(Word Index) +BEGIN + LongWord DReg,S1Reg,S2Reg; + FixedOrder *POrder=LinAddOrders+Index; + + if (ArgCnt!=3) WrError(1110); + else if (ThisCross) WrError(1350); + else + BEGIN + if (DecodeAdr(ArgStr[3],MModReg,True,&DReg)) + if (ChkUnit(DReg,D1,D2)) + BEGIN + AddDest(DReg); + if (DecodeAdr(ArgStr[1],MModReg,True,&S2Reg)) + if (IsCross(S2Reg)) WrError(1350); + else + BEGIN + AddSrc(S2Reg); + DecodeAdr(ArgStr[2],MModReg+MModImm,False,&S1Reg); + switch (AdrMode) + BEGIN + case ModReg: + if (IsCross(S1Reg)) WrError(1350); + else + BEGIN + AddSrc(S1Reg); + __erg=CodeD(POrder->Code,DReg,S1Reg,S2Reg); + END + break; + case ModImm: + __erg=CodeD(POrder->Code+2,DReg,S1Reg,S2Reg); + break; + END + END + END + END +END + + static void DecodeADDK(Word Index) +BEGIN + LongInt Value; + LongWord DReg; + Boolean OK; + + if (ArgCnt!=2) WrError(1110); + else + BEGIN + if (DecodeAdr(ArgStr[2],MModReg,False,&DReg)) + if (ChkUnit(DReg,S1,S2)) + BEGIN + AddDest(DReg); + Value=EvalIntExpression(ArgStr[1],SInt16,&OK); + if (OK) + BEGIN + ThisInst=0x50+(UnitFlag << 1)+((Value & 0xffff) << 7)+(DReg << 23); + __erg=True; + END + END + END +END + + static void DecodeADD2_SUB2(Word Index) +BEGIN + LongWord DReg,S1Reg,S2Reg; + Boolean OK; + + Index=(Index<<5)+1; + if (ArgCnt!=3) WrError(1110); + else + BEGIN + if (DecodeAdr(ArgStr[3],MModReg,True,&DReg)) + if (ChkUnit(DReg,S1,S2)) + BEGIN + AddDest(DReg); + if (DecodeAdr(ArgStr[1],MModReg,True,&S1Reg)) + BEGIN + AddSrc(S1Reg); + if (DecodeAdr(ArgStr[2],MModReg,True,&S2Reg)) + if ((ThisCross) AND (NOT IsCross(S1Reg)) AND (NOT IsCross(S2Reg))) WrError(1350); + else if ((IsCross(S1Reg)) AND (IsCross(S2Reg))) WrError(1350); + else + BEGIN + OK=True; AddSrc(S2Reg); + if (IsCross(S1Reg)) + if (Index>1) + BEGIN + WrError(1350); OK=False; + END + else SwapReg(&S1Reg,&S2Reg); + if (OK) + BEGIN + SetCross(S2Reg); + __erg=CodeS(Index,DReg,S1Reg,S2Reg); + END + END + END + END + END +END + + static void DecodeLogic(Word Index) +BEGIN + LongWord S1Reg,S2Reg,DReg; + LongWord Code1,Code2; + Boolean OK,WithImm; + + Code1=Lo(Index); Code2=Hi(Index); + + if (ArgCnt!=3) WrError(1110); + else + BEGIN + if (DecodeAdr(ArgStr[3],MModReg,True,&DReg)) + BEGIN + AddDest(DReg); + DecodeAdr(ArgStr[1],MModImm+MModReg,True,&S1Reg); WithImm=False; + switch (AdrMode) + BEGIN + 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) + BEGIN + case ModImm: + SwapReg(&S1Reg,&S2Reg); WithImm=True; + break; + case ModReg: + AddSrc(S2Reg); WithImm=False; + break; + default: + OK=False; + END + break; + default: + OK=False; + END + if (OK) + if (DecideUnit(DReg,"LS")) + if ((NOT WithImm) AND (IsCross(S1Reg)) AND (IsCross(S2Reg))) WrError(1350); + else if ((ThisCross) AND (NOT IsCross(S2Reg)) AND ((WithImm) OR (NOT IsCross(S1Reg)))) WrError(1350); + else + BEGIN + if ((NOT WithImm) AND (IsCross(S1Reg))) SwapReg(&S1Reg,&S2Reg); + SetCross(S2Reg); + switch (ThisUnit) + BEGIN + case L1: case L2: + __erg=CodeL(Code1-Ord(WithImm),DReg,S1Reg,S2Reg); break; + case S1: case S2: + __erg=CodeS(Code1-Ord(WithImm),DReg,S1Reg,S2Reg); break; + default: + WrError(20000); + END + END + END + END +END + + static Boolean DecodeInst(void) +BEGIN + Boolean OK,erg; + LongInt Dist; + int z; + LongWord DReg,S1Reg,S2Reg,HReg; + LongWord Code1; + Boolean WithImm,HasSign; + + erg=__erg=False; + + /* ueber Tabelle: */ + + if (LookupInstTable(InstTable,OpPart)) return __erg; + + /* jetzt geht's los... */ + + if ((Memo("CLR") OR (Memo("EXT")) OR (Memo("EXTU")) OR (Memo("SET")))) + BEGIN + if ((ArgCnt!=3) AND (ArgCnt!=4)) WrError(1110); + else + BEGIN + if (DecodeAdr(ArgStr[ArgCnt],MModReg,Memo("EXT"),&DReg)) + if (ChkUnit(DReg,S1,S2)) + BEGIN + AddDest(DReg); + if (DecodeAdr(ArgStr[1],MModReg,Memo("EXT"),&S2Reg)) + BEGIN + AddSrc(S2Reg); + if (ArgCnt==3) + BEGIN + if (DecodeAdr(ArgStr[2],MModReg,False,&S1Reg)) + if (IsCross(S1Reg)) WrError(1350); + else if ((ThisCross) AND (NOT IsCross(S2Reg))) WrError(1350); + else + BEGIN + SetCross(S2Reg); + if (Memo("CLR")) erg=CodeS(0x3f,DReg,S1Reg,S2Reg); + else if (Memo("EXTU")) erg=CodeS(0x2b,DReg,S1Reg,S2Reg); + else if (Memo("SET")) erg=CodeS(0x3b,DReg,S1Reg,S2Reg); + else erg=CodeS(0x2f,DReg,S1Reg,S2Reg); + END + END + else if ((ThisCross) OR (IsCross(S2Reg))) WrError(1350); + else + BEGIN + S1Reg=EvalIntExpression(ArgStr[2],UInt5,&OK); + if (OK) + BEGIN + HReg=EvalIntExpression(ArgStr[3],UInt5,&OK); + if (OK) + BEGIN + ThisInst=(DReg << 23)+(S2Reg << 18)+(S1Reg << 13)+ + (HReg << 8)+(UnitFlag << 1); + if (Memo("CLR")) ThisInst+=0xc8; + else if (Memo("SET")) ThisInst+=0x88; + else if (Memo("EXT")) ThisInst+=0x48; + else ThisInst+=0x08; + erg=True; + END + END + END + END + END + END + return erg; + END + + for (z=0; z0) + BEGIN + if (DecodeAdr(ArgStr[z],MModReg,False,&S1Reg)) + if ((ThisCross) AND ((z==2) OR (IsCross(S1Reg)))) WrError(1350); + else + BEGIN + if (z==1) + BEGIN + S2Reg=S1Reg; + AddSrc(S2Reg); SetCross(S2Reg); + END + else + BEGIN + DReg=S1Reg; AddDest(DReg); + END + erg=CodeS(0x0d+z,DReg,0,S2Reg); + END + END + END + return erg; + END + + if ((Memo("MVK")) OR (Memo("MVKH")) OR (Memo("MVKLH"))) + BEGIN + if (ArgCnt!=2) WrError(1110); + else + BEGIN + if (DecodeAdr(ArgStr[2],MModReg,True,&DReg)) + if (ChkUnit(DReg,S1,S2)) + BEGIN + S1Reg=EvalIntExpression(ArgStr[1],Memo("MVKLH")?Int16:Int32,&OK); + if (OK) + BEGIN + AddDest(DReg); + if (Memo("MVKH")) S1Reg=S1Reg >> 16; + ThisInst=(DReg << 23)+((S1Reg & 0xffff) << 7)+(UnitFlag << 1); + ThisInst+=Memo("MVK") ? 0x28 : 0x68; + erg=True; + END + END + END + return True; + END + + if (Memo("SHL")) + BEGIN + if (ArgCnt!=3) WrError(1110); + else + BEGIN + DecodeAdr(ArgStr[3],MModReg+MModLReg,True,&DReg); + if ((AdrMode!=ModNone) AND (ChkUnit(DReg,S1,S2))) + switch (AdrMode) + BEGIN + case ModReg: + AddDest(DReg); + if (DecodeAdr(ArgStr[1],MModReg,True,&S2Reg)) + if ((ThisCross) AND (NOT IsCross(S2Reg))) WrError(1350); + else + BEGIN + AddSrc(S2Reg); + SetCross(S2Reg); + DecodeAdr(ArgStr[2],MModReg+MModImm,False,&S1Reg); + switch (AdrMode) + BEGIN + case ModReg: + if (IsCross(S1Reg)) WrError(1350); + else + BEGIN + AddSrc(S1Reg); + erg=CodeS(0x33,DReg,S1Reg,S2Reg); + END + break; + case ModImm: + erg=CodeS(0x32,DReg,S1Reg,S2Reg); + break; + END + END + break; + case ModLReg: + AddLDest(DReg); + DecodeAdr(ArgStr[1],MModReg+MModLReg,True,&S2Reg); + switch (AdrMode) + BEGIN + case ModReg: + if ((ThisCross) AND (NOT IsCross(S2Reg))) WrError(1350); + else + BEGIN + AddSrc(S2Reg); SetCross(S2Reg); + DecodeAdr(ArgStr[2],MModImm+MModReg,False,&S1Reg); + switch (AdrMode) + BEGIN + case ModReg: + if (IsCross(S1Reg)) WrError(1350); + else + BEGIN + AddSrc(S1Reg); + erg=CodeS(0x13,DReg,S1Reg,S2Reg); + END + break; + case ModImm: + erg=CodeS(0x12,DReg,S1Reg,S2Reg); + break; + END + END + break; + case ModLReg: + if ((ThisCross) OR (IsCross(S2Reg))) WrError(1350); + else + BEGIN + AddLSrc(S2Reg); + DecodeAdr(ArgStr[2],MModImm+MModReg,False,&S1Reg); + switch (AdrMode) + BEGIN + case ModReg: + if (IsCross(S1Reg)) WrError(1350); + else + BEGIN + AddSrc(S1Reg); + erg=CodeS(0x31,DReg,S1Reg,S2Reg); + END + break; + case ModImm: + erg=CodeS(0x30,DReg,S1Reg,S2Reg); + break; + END + END + break; + END + break; + END + END + return erg; + END + + if ((Memo("SHR")) OR (Memo("SHRU"))) + BEGIN + if (ArgCnt!=3) WrError(1110); + else + BEGIN + HasSign=Memo("SHR"); z=Ord(HasSign) << 4; + DecodeAdr(ArgStr[3],MModReg+MModLReg,HasSign,&DReg); + if ((AdrMode!=ModNone) AND (ChkUnit(DReg,S1,S2))) + switch (AdrMode) + BEGIN + case ModReg: + AddDest(DReg); + if (DecodeAdr(ArgStr[1],MModReg,HasSign,&S2Reg)) + if ((ThisCross) AND (NOT IsCross(S2Reg))) WrError(1350); + else + BEGIN + AddSrc(S2Reg); SetCross(S2Reg); + DecodeAdr(ArgStr[2],MModReg+MModImm,False,&S1Reg); + switch (AdrMode) + BEGIN + case ModReg: + if (IsCross(S1Reg)) WrError(1350); + else + BEGIN + AddSrc(S1Reg); + erg=CodeS(0x27+z,DReg,S1Reg,S2Reg); + END + break; + case ModImm: + erg=CodeS(0x26+z,DReg,S1Reg,S2Reg); + break; + END + END + break; + case ModLReg: + AddLDest(DReg); + if (DecodeAdr(ArgStr[1],MModLReg,HasSign,&S2Reg)) + if ((ThisCross) OR (IsCross(S2Reg))) WrError(1350); + else + BEGIN + AddLSrc(S2Reg); + DecodeAdr(ArgStr[2],MModReg+MModImm,False,&S1Reg); + switch (AdrMode) + BEGIN + case ModReg: + if (IsCross(S1Reg)) WrError(1350); + else + BEGIN + AddSrc(S1Reg); + erg=CodeS(0x25+z,DReg,S1Reg,S2Reg); + END + break; + case ModImm: + erg=CodeS(0x24+z,DReg,S1Reg,S2Reg); + break; + END + END + break; + END + END + return erg; + END + + if (Memo("SSHL")) + BEGIN + if (ArgCnt!=3) WrError(1110); + else + BEGIN + if (DecodeAdr(ArgStr[3],MModReg,True,&DReg)) + if (ChkUnit(DReg,S1,S2)) + BEGIN + AddDest(DReg); + if (DecodeAdr(ArgStr[1],MModReg,True,&S2Reg)) + if ((ThisCross) AND (NOT IsCross(S2Reg))) WrError(1350); + else + BEGIN + AddSrc(S2Reg); SetCross(S2Reg); + DecodeAdr(ArgStr[2],MModReg+MModImm,False,&S1Reg); + switch (AdrMode) + BEGIN + case ModReg: + if (IsCross(S1Reg)) WrError(1350); + else + BEGIN + AddSrc(S1Reg); + erg=CodeS(0x23,DReg,S1Reg,S2Reg); + END + break; + case ModImm: + erg=CodeS(0x22,DReg,S1Reg,S2Reg); + break; + END + END + END + END + return erg; + END + + if (Memo("SSUB")) + BEGIN + if (ArgCnt!=3) WrError(1110); + else + BEGIN + DecodeAdr(ArgStr[3],MModReg+MModLReg,True,&DReg); + if ((AdrMode!=ModNone) AND (ChkUnit(DReg,L1,L2))) + switch (AdrMode) + BEGIN + case ModReg: + AddDest(DReg); + DecodeAdr(ArgStr[1],MModReg+MModImm,True,&S1Reg); + switch (AdrMode) + BEGIN + case ModReg: + AddSrc(S1Reg); + if (DecodeAdr(ArgStr[2],MModReg,True,&S2Reg)) + if ((ThisCross) AND (NOT IsCross(S1Reg)) AND (NOT IsCross(S2Reg))) WrError(1350); + else if ((IsCross(S1Reg)) AND (IsCross(S2Reg))) WrError(1350); + else if (IsCross(S1Reg)) + BEGIN + ThisCross=True; + erg=CodeL(0x1f,DReg,S1Reg,S2Reg); + END + else + BEGIN + SetCross(S2Reg); + erg=CodeL(0x0f,DReg,S1Reg,S2Reg); + END + break; + case ModImm: + if (DecodeAdr(ArgStr[2],MModReg,True,&S2Reg)) + if ((ThisCross) AND (NOT IsCross(S2Reg)<16)) WrError(1350); + else + BEGIN + AddSrc(S2Reg); SetCross(S2Reg); + erg=CodeL(0x0e,DReg,S1Reg,S2Reg); + END + break; + END + break; + case ModLReg: + AddLDest(DReg); + if (DecodeAdr(ArgStr[1],MModImm,True,&S1Reg)) + BEGIN + if (DecodeAdr(ArgStr[2],MModLReg,True,&S2Reg)) + if ((ThisCross) OR (IsCross(S2Reg))) WrError(1350); + else + BEGIN + AddLSrc(S2Reg); + erg=CodeL(0x2c,DReg,S1Reg,S2Reg); + END + END + break; + END + END; + return erg; + END + + /* Spruenge */ + + /* Wie zum Henker unterscheiden sich B IRP und B NRP ??? + Kann TI keine ordentlichen Handbuecher mehr schreiben ? */ + + if (Memo("B")) + BEGIN + if (ArgCnt!=1) WrError(1350); + else if (ThisCross) WrError(1350); + else if ((ThisUnit!=NoUnit) AND (ThisUnit!=S1) AND (ThisUnit!=S2)) WrError(1350); + else + BEGIN + OK=True; S2Reg=0; WithImm=False; Code1=0; + if (strcasecmp(ArgStr[1],"IRP")==0) Code1=0x03; + else if (strcasecmp(ArgStr[1],"NRP")==0) Code1=0x03; /* !!! */ + else if (DecodeReg(ArgStr[1],&S2Reg,&OK,False)) + BEGIN + if (OK) WrError(1350); OK=NOT OK; + Code1=0x0d; + END + else WithImm=True; + if (OK) + if (WithImm) + BEGIN + if (ThisUnit==NoUnit) + ThisUnit=(UnitUsed(S1)) ? S2 : S1; + UnitFlag=Ord(ThisUnit==S2); + Dist=EvalIntExpression(ArgStr[1],Int32,&OK)-PacketAddr; + if (OK) + if ((Dist & 3)!=0) WrError(1325); + else if ((NOT SymbolQuestionable) AND ((Dist>0x3fffff) OR (Dist<-0x400000))) WrError(1370); + else + BEGIN + ThisInst=0x50+((Dist & 0x007ffffc) << 5)+(UnitFlag << 1); + erg=True; + END + END + else + BEGIN + if (ChkUnit(0x10,S1,S2)) erg=CodeS(Code1,0,0,S2Reg); + END + END + return erg; + END + + WrXError(1200,OpPart); + + return erg; +END + + static void ChkPacket(void) +BEGIN + LongWord EndAddr,Mask; + LongInt z,z1,z2; + Integer RegReads[32]; + char TestUnit[4]; + + /* nicht ueber 8er-Grenze */ + + EndAddr=PacketAddr+((ParCnt << 2)-1); + if ((PacketAddr >> 5)!=(EndAddr >> 5)) WrError(2000); + + /* doppelte Units,Crosspaths,Adressierer,Zielregister */ + + for (z1=0; z1> 28)==(ParRecs[z2].OpCode >> 28)) + BEGIN + /* doppelte Units */ + if ((ParRecs[z1].U!=NoUnit) AND (ParRecs[z1].U==ParRecs[z2].U)) + WrXError(2001,UnitNames[ParRecs[z1].U]); + + /* Crosspaths */ + z=ParRecs[z1].CrossUsed & ParRecs[z2].CrossUsed; + if (z!=0) + BEGIN + *TestUnit=z+'0'; TestUnit[1]='X'; TestUnit[2]='\0'; + WrXError(2001,TestUnit); + END + + z=ParRecs[z1].AddrUsed & ParRecs[z2].AddrUsed; + /* Adressgeneratoren */ + if ((z & 1)==1) WrXError(2001,"Addr. A"); + if ((z & 2)==2) WrXError(2001,"Addr. B"); + /* Hauptspeicherpfade */ + if ((z & 4)==4) WrXError(2001,"LdSt. A"); + if ((z & 8)==8) WrXError(2001,"LdSt. B"); + + /* ueberlappende Zielregister */ + z=ParRecs[z1].DestMask & ParRecs[z2].DestMask; + if (z!=0) WrXError(2006,RegName(FindReg(z))); + + if ((ParRecs[z1].U & 1)==(ParRecs[z2].U & 1)) + BEGIN + TestUnit[0]=ParRecs[z1].U-NoUnit-1+'A'; + TestUnit[1]='\0'; + + /* mehrere Long-Reads */ + if ((ParRecs[z1].LongSrc) AND (ParRecs[z2].LongSrc)) + WrXError(2002,TestUnit); + + /* mehrere Long-Writes */ + if ((ParRecs[z1].LongDest) AND (ParRecs[z2].LongDest)) + WrXError(2003,TestUnit); + + /* Long-Read mit Store */ + if ((ParRecs[z1].StoreUsed) AND (ParRecs[z2].LongSrc)) + WrXError(2004,TestUnit); + if ((ParRecs[z2].StoreUsed) AND (ParRecs[z1].LongSrc)) + WrXError(2004,TestUnit); + END + END + + for (z2=0; z2<32; RegReads[z2++]=0); + for (z1=0; z14) WrXError(2005,RegName(z1)); +END + + static void MakeCode_3206X(void) +BEGIN + CodeLen=0; DontPrint=False; + + /* zu ignorierendes */ + + if ((*OpPart=='\0') AND (*LabPart=='\0')) return; + + /* Pseudoanweisungen */ + + if (DecodePseudo()) return; + + /* Flags zuruecksetzen */ + + ThisPar=False; Condition=0; + + /* Optionen aus Label holen */ + + if (*LabPart!='\0') + if ((strcmp(LabPart,"||")==0) OR (*LabPart=='[')) + if (NOT CheckOpt(LabPart)) return; + + /* eventuell falsche Mnemonics verwerten */ + + if (strcmp(OpPart,"||")==0) + if (NOT ReiterateOpPart()) return; + if (*OpPart=='[') + if (NOT ReiterateOpPart()) return; + + if (Memo("")) return; + + /* Attribut auswerten */ + + ThisUnit=NoUnit; ThisCross=False; + if (*AttrPart!='\0') + BEGIN + if (toupper(AttrPart[strlen(AttrPart)-1])=='X') + BEGIN + ThisCross=True; + AttrPart[strlen(AttrPart)-1]='\0'; + END + if (*AttrPart=='\0') ThisUnit=NoUnit; + else + for (; ThisUnit!=LastUnit; ThisUnit++) + if (strcasecmp(AttrPart,UnitNames[ThisUnit])==0) break; + if (ThisUnit==LastUnit) + BEGIN + WrError(1107); return; + END + if (((ThisUnit==D1) OR (ThisUnit==D2)) AND (ThisCross)) + BEGIN + WrError(1350); return; + END + END + + /* falls nicht parallel, vorherigen Stack durchpruefen und verwerfen */ + + if ((NOT ThisPar) AND (ParCnt>0)) + BEGIN + ChkPacket(); + ParCnt=0; PacketAddr=EProgCounter(); + END + + /* dekodieren */ + + ThisSrc=0; ThisSrc2=0; ThisDest=0; + ThisAddr=0; ThisStore=False; ThisLong=0; + if (NOT DecodeInst()) return; + + /* einsortieren */ + + ParRecs[ParCnt].OpCode=(Condition << 28)+ThisInst; + ParRecs[ParCnt].U=ThisUnit; + if (ThisCross) + switch (ThisUnit) + BEGIN + case L1: case S1: case M1: case D1: ParRecs[ParCnt].CrossUsed=1; break; + default: ParRecs[ParCnt].CrossUsed=2; + END + 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; + ParCnt++; + + /* wenn mehr als eine Instruktion, Ressourcenkonflikte abklopfen und + vorherige Instruktion zuruecknehmen */ + + if (ParCnt>1) + BEGIN + RetractWords(4); + DAsmCode[CodeLen >> 2]=ParRecs[ParCnt-2].OpCode | 1; + CodeLen+=4; + END + + /* aktuelle Instruktion auswerfen: fuer letzte kein Parallelflag setzen */ + + DAsmCode[CodeLen >> 2]=ParRecs[ParCnt-1].OpCode; + CodeLen+=4; +END + +/*-------------------------------------------------------------------------*/ + +static int InstrZ; + + + static void AddLinAdd(char *NName, LongInt NCode) +BEGIN + if (InstrZ>=LinAddCnt) exit(255); + LinAddOrders[InstrZ].Name=NName; + LinAddOrders[InstrZ].Code=NCode; + AddInstTable(InstTable,NName,InstrZ++,DecodeLinAdd); +END + + static void AddCmp(char *NName, LongInt NCode) +BEGIN + if (InstrZ>=CmpCnt) exit(255); + CmpOrders[InstrZ].Name=NName; + CmpOrders[InstrZ++].Code=NCode; +END + + static void AddMem(char *NName, LongInt NCode, LongInt NScale) +BEGIN + if (InstrZ>=MemCnt) exit(255); + MemOrders[InstrZ].Name=NName; + MemOrders[InstrZ].Code=NCode; + MemOrders[InstrZ].Scale=NScale; + AddInstTable(InstTable,NName,InstrZ++,DecodeMemO); +END + + static void AddMul(char *NName, LongInt NCode, + Boolean NDSign,Boolean NSSign1,Boolean NSSign2, Boolean NMay) +BEGIN + if (InstrZ>=MulCnt) exit(255); + MulOrders[InstrZ].Name=NName; + 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); +END + + static void AddCtrl(char *NName, LongInt NCode, + Boolean NWr, Boolean NRd) +BEGIN + if (InstrZ>=CtrlCnt) exit(255); + CtrlRegs[InstrZ].Name=NName; + CtrlRegs[InstrZ].Code=NCode; + CtrlRegs[InstrZ].Wr=NWr; + CtrlRegs[InstrZ++].Rd=NRd; +END + + static void InitFields(void) +BEGIN + 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",0x1f79,DecodeLogic); + AddInstTable(InstTable,"OR",0x1b7f,DecodeLogic); + AddInstTable(InstTable,"XOR",0x0b6f,DecodeLogic); + + LinAddOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*LinAddCnt); InstrZ=0; + AddLinAdd("ADDAB",0x30); AddLinAdd("ADDAH",0x34); AddLinAdd("ADDAW",0x38); + AddLinAdd("SUBAB",0x31); AddLinAdd("SUBAH",0x35); AddLinAdd("SUBAW",0x39); + + CmpOrders=(FixedOrder *) malloc(sizeof(FixedOrder)*CmpCnt); InstrZ=0; + AddCmp("CMPEQ",0x50); AddCmp("CMPGT",0x44); AddCmp("CMPGTU",0x4c); + AddCmp("CMPLT",0x54); AddCmp("CMPLTU",0x5c); + + MemOrders=(MemOrder *) malloc(sizeof(MemOrder)*MemCnt); 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); + + MulOrders=(MulOrder *) malloc(sizeof(MulOrder)*MulCnt); 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); + + CtrlRegs=(CtrlReg *) malloc(sizeof(CtrlReg)*CtrlCnt); 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 ); +END + + static void DeinitFields(void) +BEGIN + DestroyInstTable(InstTable); + free(LinAddOrders); + free(CmpOrders); + free(MemOrders); + free(MulOrders); + free(CtrlRegs); +END + +/*------------------------------------------------------------------------*/ + + static Boolean IsDef_3206X(void) +BEGIN + return (strcmp(LabPart,"||")==0) OR (*LabPart=='['); +END + + static void SwitchFrom_3206X(void) +BEGIN + if (ParCnt>1) ChkPacket(); + DeinitFields(); +END + + static void SwitchTo_3206X(void) +BEGIN + TurnWords=False; ConstMode=ConstModeIntel; SetIsOccupied=False; + + PCSymbol="$"; HeaderID=0x47; NOPCode=0x00000000; + DivideChars=","; HasAttrs=True; AttrChars="."; + SetIsOccupied=True; + + ValidSegs=1<