/* 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<