/* code77230.c */ /*****************************************************************************/ /* Makroassembler AS */ /* */ /* Codegenerator NEC uPD77230 */ /* */ /* Historie: 13. 9.1998 Grundsteinlegung */ /* 14. 9.1998 LDI/Destregs getestet */ /* 16. 9.1998 das instruktionelle Kleingemuese begonnen */ /* 19. 9.1998 restliche CPU-Instruktionen */ /* 27. 9.1998 DW-Anweisung */ /* 28. 9.1998 String-Argument fuer DW */ /* DS */ /* 2. 1.1999 ChkPC-Anpassung */ /* */ /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* Includes */ #include "stdinc.h" #include #include #include "strutil.h" #include "nls.h" #include "endian.h" #include "asmdef.h" #include "asmsub.h" #include "asmpars.h" #include "asmitree.h" #include "headids.h" /*---------------------------------------------------------------------------*/ /* Definitionen */ #define SrcRegCnt 32 #define DestRegCnt 32 #define ALUSrcRegCnt 4 #define JmpOrderCnt 32 #define ALU1OrderCnt 15 #define ALU2OrderCnt 10 #define CaseCnt 17 typedef struct { LongWord Code; } FixedOrder; typedef struct { char *Name; LongWord Code; } Register; enum {InstrLDI, InstrBranch, InstrALU, InstrMove, InstrM0, InstrM1, InstrDP0, InstrDP1, InstrEA, InstrRP, InstrFC, InstrLC, InstrBASE0, InstrBASE1, InstrRPC, InstrP2, InstrP3, InstrEM, InstrBM, InstrL, InstrRW, InstrWT, InstrNF, InstrWI, InstrFIS, InstrFD, InstrSHV, InstrRPS, InstrNAL, InstrCnt}; static LongWord CaseMasks[CaseCnt]= {(1l<0) BEGIN DiscPtr=ArgStr[1]-1; SplittedArg=1; END else DiscPtr=Nil; return True; END if (ArgCnt0) BEGIN for (z=0; z<=ArgCnt-DiscCnt; z++) strcpy(ArgStr[z+1],ArgStr[z+DiscCnt]); ArgCnt-=DiscCnt-1; END END static void AddComp(int Index, LongWord Value) BEGIN if ((InstrMask&(1l<Code+(Adr << 5)); DiscardArgs(); END static void DecodeMOV(Word Index) BEGIN LongWord DReg,SReg; if (NOT SplitArgs(2)) return; if (NOT DecodeReg(ArgStr[1],&DReg,DestRegs,DestRegCnt)) BEGIN WrXError(1445,ArgStr[1]); Error=True; END else if (NOT DecodeReg(ArgStr[2],&SReg,SrcRegs,SrcRegCnt)) BEGIN WrXError(1445,ArgStr[2]); Error=True; END else AddComp(InstrMove,(SReg<<5)+DReg); DiscardArgs(); END static void DecodeLDI(Word Index) BEGIN LongWord DReg,Src=0; if (NOT SplitArgs(2)) return; if (NOT DecodeReg(ArgStr[1],&DReg,DestRegs,DestRegCnt)) BEGIN WrXError(1445,ArgStr[1]); Error=True; END else Src=EvalIntExpression(ArgStr[2],Int24,&Error); Error=NOT Error; if (NOT Error) AddComp(InstrLDI,(Src<<5)+DReg); DiscardArgs(); END static void DecodeNOP(Word Index) BEGIN if (NOT SplitArgs(0)) return; AddComp(InstrALU,0); DiscardArgs(); END static void DecodeALU1(Word Index) BEGIN FixedOrder *Op=ALU1Orders+Index; LongWord DReg; if (NOT SplitArgs(1)) return; if ((NOT DecodeReg(ArgStr[1],&DReg,DestRegs,DestRegCnt)) OR (DReg<16) OR (DReg>23)) BEGIN WrXError(1445,ArgStr[1]); Error=True; END else AddComp(InstrALU,(Op->Code<<17)+(DReg&7)); DiscardArgs(); END static void DecodeALU2(Word Index) BEGIN FixedOrder *Op=ALU2Orders+Index; LongWord DReg,SReg; if (NOT SplitArgs(2)) return; if ((NOT DecodeReg(ArgStr[1],&DReg,DestRegs,DestRegCnt)) OR (DReg<16) OR (DReg>23)) BEGIN WrXError(1445,ArgStr[1]); Error=True; END else if (NOT DecodeReg(ArgStr[2],&SReg,ALUSrcRegs,ALUSrcRegCnt)) BEGIN WrXError(1445,ArgStr[2]); Error=True; END else AddComp(InstrALU,(Op->Code<<17)+(SReg<<3)+(DReg&7)); DiscardArgs(); END static void DecodeM0(Word Index) BEGIN if (NOT SplitArgs(0)) return; AddComp(InstrM0,Index); DiscardArgs(); END static void DecodeM1(Word Index) BEGIN if (NOT SplitArgs(0)) return; AddComp(InstrM1,Index); DiscardArgs(); END static void DecodeDP0(Word Index) BEGIN if (NOT SplitArgs(0)) return; AddComp(InstrDP0,Index); DiscardArgs(); END static void DecodeDP1(Word Index) BEGIN if (NOT SplitArgs(0)) return; AddComp(InstrDP1,Index); DiscardArgs(); END static void DecodeEA(Word Index) BEGIN if (NOT SplitArgs(0)) return; AddComp(InstrEA,Index); DiscardArgs(); END static void DecodeFC(Word Index) BEGIN if (NOT SplitArgs(0)) return; AddComp(InstrFC,Index); DiscardArgs(); END static void DecodeRP(Word Index) BEGIN if (NOT SplitArgs(0)) return; AddComp(InstrRP,Index); DiscardArgs(); END static void DecodeL(Word Index) BEGIN if (NOT SplitArgs(0)) return; AddComp(InstrL,Index); DiscardArgs(); END static void DecodeBASE(Word Index) BEGIN LongWord Value; if (NOT SplitArgs(1)) return; Value=EvalIntExpression(ArgStr[1],UInt3,&Error); Error=NOT Error; if (NOT Error) AddComp(Index,Value); DiscardArgs(); END static void DecodeRPC(Word Index) BEGIN LongWord Value; if (NOT SplitArgs(1)) return; FirstPassUnknown=False; Value=EvalIntExpression(ArgStr[1],UInt4,&Error); if (FirstPassUnknown) Value&=7; if (Value>9) Error=True; else Error=NOT Error; if (NOT Error) AddComp(InstrRPC,Value); DiscardArgs(); END static void DecodeP2(Word Index) BEGIN if (NOT SplitArgs(0)) return; AddComp(InstrP2,Index); DiscardArgs(); END static void DecodeP3(Word Index) BEGIN if (NOT SplitArgs(0)) return; AddComp(InstrP3,Index); DiscardArgs(); END static void DecodeBM(Word Index) BEGIN /* Wenn EM-Feld schon da war, muss es EI gewesen sein */ if (NOT SplitArgs(0)) return; if ((InstrMask&(1<46) Error=True; else Error=NOT Error; if (NOT Error) AddComp(InstrSHV,(Index<<6)+Value); DiscardArgs(); END static void DecodeRPS(Word Index) BEGIN LongWord Value; if (NOT SplitArgs(1)) return; Value=EvalIntExpression(ArgStr[1],UInt9,&Error); Error=NOT Error; if (NOT Error) AddComp(InstrRPS,Value); DiscardArgs(); END static void DecodeNAL(Word Index) BEGIN LongWord Value; if (NOT SplitArgs(1)) return; FirstPassUnknown=False; Value=EvalIntExpression(ArgStr[1],UInt13,&Error); if (FirstPassUnknown) Value=(Value&0x1ff)|(EProgCounter()&0x1e00); Error=NOT Error; if (NOT Error) if ((NOT SymbolQuestionable) AND ((Value^EProgCounter())&0x1e00)) WrError(1910); else AddComp(InstrNAL,Value&0x1ff); DiscardArgs(); END static Boolean DecodePseudo(void) BEGIN int z; Boolean OK; TempResult t; LongWord temp; LongInt sign,mant,expo,Size; char *cp; if (Memo("DW")) BEGIN if (ArgCnt<1) WrError(1110); else BEGIN z=1; OK=True; while ((OK) AND (z<=ArgCnt)) BEGIN FirstPassUnknown=FALSE; EvalExpression(ArgStr[z],&t); switch(t.Typ) BEGIN case TempInt: if (NOT RangeCheck(t.Contents.Int,Int32)) BEGIN WrError(1320); OK=False; break; END DAsmCode[CodeLen++]=t.Contents.Int; break; case TempFloat: if (NOT FloatRangeCheck(t.Contents.Float,Float32)) BEGIN WrError(1320); OK=False; break; END Double_2_ieee4(t.Contents.Float,(Byte*) &temp,BigEndian); sign=(temp>>31)&1; expo=(temp>>23)&255; mant=temp&0x7fffff; if ((mant==0) AND (expo==0)) DAsmCode[CodeLen++]=0x80000000; else BEGIN if (expo>0) BEGIN mant|=0x800000; expo-=127; END else expo-=126; if (mant>=0x800000) BEGIN mant=mant>>1; expo+=1; END if (sign==1) mant=((mant^0xffffff)+1); DAsmCode[CodeLen++]=((expo&0xff)<<24)|(mant&0xffffff); END break; case TempString: for (z=0,cp=t.Contents.Ascii; *cp!='\0'; cp++,z++) BEGIN DAsmCode[CodeLen]=(DAsmCode[CodeLen]<<8)+CharTransTable[((usint)*cp)&0xff]; if ((z&3)==3) CodeLen++; END if ((z&3)!=0) DAsmCode[CodeLen++]=(DAsmCode[CodeLen])<<((4-(z&3))<<3); break; default: OK=False; END z++; END if (NOT OK) CodeLen=0; END return True; END if (Memo("DS")) BEGIN if (ArgCnt!=1) WrError(1110); else BEGIN FirstPassUnknown=False; Size=EvalIntExpression(ArgStr[1],Int16,&OK); if (FirstPassUnknown) WrError(1820); if ((OK) AND (NOT FirstPassUnknown)) BEGIN DontPrint=True; CodeLen=Size; BookKeeping(); END END return True; END return FALSE; END /*---------------------------------------------------------------------------*/ /* Codetabellenverwaltung */ static int InstrZ; static void AddJmp(char *NName, LongWord NCode) BEGIN if (InstrZ>=JmpOrderCnt) exit(255); JmpOrders[InstrZ].Code=NCode; AddInstTable(InstTable,NName,InstrZ++,DecodeJmp); END static void AddALU1(char *NName, LongWord NCode) BEGIN if (InstrZ>=ALU1OrderCnt) exit(255); ALU1Orders[InstrZ].Code=NCode; AddInstTable(InstTable,NName,InstrZ++,DecodeALU1); END static void AddALU2(char *NName, LongWord NCode) BEGIN if (InstrZ>=ALU2OrderCnt) exit(255); ALU2Orders[InstrZ].Code=NCode; AddInstTable(InstTable,NName,InstrZ++,DecodeALU2); END static void AddSrcReg(char *NName, LongWord NCode) BEGIN if (InstrZ>=SrcRegCnt) exit(255); SrcRegs[InstrZ].Name=NName; SrcRegs[InstrZ++].Code=NCode; END static void AddALUSrcReg(char *NName, LongWord NCode) BEGIN if (InstrZ>=ALUSrcRegCnt) exit(255); ALUSrcRegs[InstrZ].Name=NName; ALUSrcRegs[InstrZ++].Code=NCode; END static void AddDestReg(char *NName, LongWord NCode) BEGIN if (InstrZ>=DestRegCnt) exit(255); DestRegs[InstrZ].Name=NName; DestRegs[InstrZ++].Code=NCode; END static void InitFields(void) BEGIN InstTable=CreateInstTable(201); AddInstTable(InstTable,"MOV",0,DecodeMOV); AddInstTable(InstTable,"LDI",0,DecodeLDI); AddInstTable(InstTable,"NOP",0,DecodeNOP); AddInstTable(InstTable,"SPCBP0",1,DecodeM0); AddInstTable(InstTable,"SPCIX0",2,DecodeM0); AddInstTable(InstTable,"SPCBI0",3,DecodeM0); AddInstTable(InstTable,"SPCBP1",1,DecodeM1); AddInstTable(InstTable,"SPCIX1",2,DecodeM1); AddInstTable(InstTable,"SPCBI1",3,DecodeM1); AddInstTable(InstTable,"INCBP0",1,DecodeDP0); AddInstTable(InstTable,"DECBP0",2,DecodeDP0); AddInstTable(InstTable,"CLRBP0",3,DecodeDP0); AddInstTable(InstTable,"STIX0" ,4,DecodeDP0); AddInstTable(InstTable,"INCIX0",5,DecodeDP0); AddInstTable(InstTable,"DECIX0",6,DecodeDP0); AddInstTable(InstTable,"CLRIX0",7,DecodeDP0); AddInstTable(InstTable,"INCBP1",1,DecodeDP1); AddInstTable(InstTable,"DECBP1",2,DecodeDP1); AddInstTable(InstTable,"CLRBP1",3,DecodeDP1); AddInstTable(InstTable,"STIX1" ,4,DecodeDP1); AddInstTable(InstTable,"INCIX1",5,DecodeDP1); AddInstTable(InstTable,"DECIX1",6,DecodeDP1); AddInstTable(InstTable,"CLRIX1",7,DecodeDP1); AddInstTable(InstTable,"INCAR" ,1,DecodeEA); AddInstTable(InstTable,"DECAR" ,2,DecodeEA); AddInstTable(InstTable,"XCHPSW",1,DecodeFC); AddInstTable(InstTable,"INCRP" ,1,DecodeRP); AddInstTable(InstTable,"DECRP" ,2,DecodeRP); AddInstTable(InstTable,"INCBRP",3,DecodeRP); AddInstTable(InstTable,"DECLC" ,1,DecodeL); AddInstTable(InstTable,"MCNBP0",InstrBASE0,DecodeBASE); AddInstTable(InstTable,"MCNBP1",InstrBASE1,DecodeBASE); AddInstTable(InstTable,"BITRP" ,0,DecodeRPC); AddInstTable(InstTable,"CLRP2" ,0,DecodeP2); AddInstTable(InstTable,"SETP2" ,1,DecodeP2); AddInstTable(InstTable,"CLRP3" ,0,DecodeP3); AddInstTable(InstTable,"SETP3" ,1,DecodeP3); AddInstTable(InstTable,"DI" ,0,DecodeEM); AddInstTable(InstTable,"EI" ,1,DecodeEM); AddInstTable(InstTable,"CLRBM" ,1,DecodeBM); AddInstTable(InstTable,"SETBM" ,2,DecodeBM); AddInstTable(InstTable,"RD" ,1,DecodeRW); AddInstTable(InstTable,"WR" ,2,DecodeRW); AddInstTable(InstTable,"WRBORD",1,DecodeWT); AddInstTable(InstTable,"WRBL24",2,DecodeWT); AddInstTable(InstTable,"WRBL23",3,DecodeWT); AddInstTable(InstTable,"WRBEL8",4,DecodeWT); AddInstTable(InstTable,"WRBL8E",5,DecodeWT); AddInstTable(InstTable,"WRBXCH",6,DecodeWT); AddInstTable(InstTable,"WRBBRV",7,DecodeWT); AddInstTable(InstTable,"TRNORM",2,DecodeNF); AddInstTable(InstTable,"RDNORM",4,DecodeNF); AddInstTable(InstTable,"FLTFIX",6,DecodeNF); AddInstTable(InstTable,"FIXMA" ,7,DecodeNF); AddInstTable(InstTable,"BWRL24",1,DecodeWI); AddInstTable(InstTable,"BWRORD",2,DecodeWI); AddInstTable(InstTable,"SPCPSW0",1,DecodeFIS); AddInstTable(InstTable,"SPCPSW1",2,DecodeFIS); AddInstTable(InstTable,"CLRPSW0",4,DecodeFIS); AddInstTable(InstTable,"CLRPSW1",5,DecodeFIS); AddInstTable(InstTable,"CLRPSW" ,6,DecodeFIS); AddInstTable(InstTable,"SPIE",1,DecodeFD); AddInstTable(InstTable,"IESP",2,DecodeFD); AddInstTable(InstTable,"SETSVL",0,DecodeSHV); AddInstTable(InstTable,"SETSVR",1,DecodeSHV); AddInstTable(InstTable,"SPCRA",0,DecodeRPS); AddInstTable(InstTable,"JBLK" ,0,DecodeNAL); JmpOrders=(FixedOrder*) malloc(sizeof(FixedOrder)*JmpOrderCnt); InstrZ=0; AddJmp("JMP" ,0x00); AddJmp("CALL" ,0x01); AddJmp("RET" ,0x02); AddJmp("JNZRP" ,0x03); AddJmp("JZ0" ,0x04); AddJmp("JNZ0" ,0x05); AddJmp("JZ1" ,0x06); AddJmp("JNZ1" ,0x07); AddJmp("JC0" ,0x08); AddJmp("JNC0" ,0x09); AddJmp("JC1" ,0x0a); AddJmp("JNC1" ,0x0b); AddJmp("JS0" ,0x0c); AddJmp("JNS0" ,0x0d); AddJmp("JS1" ,0x0e); AddJmp("JNS1" ,0x0f); AddJmp("JV0" ,0x10); AddJmp("JNV0" ,0x11); AddJmp("JV1" ,0x12); AddJmp("JNV1" ,0x13); AddJmp("JEV0" ,0x14); AddJmp("JEV1" ,0x15); AddJmp("JNFSI" ,0x16); AddJmp("JNESO" ,0x17); AddJmp("JIP0" ,0x18); AddJmp("JIP1" ,0x19); AddJmp("JNZIX0",0x1a); AddJmp("JNZIX1",0x1b); AddJmp("JNZBP0",0x1c); AddJmp("JNZBP1",0x1d); AddJmp("JRDY" ,0x1e); AddJmp("JRQM" ,0x1f); ALU1Orders=(FixedOrder*) malloc(sizeof(FixedOrder)*ALU1OrderCnt); InstrZ=0; AddALU1("INC" ,0x01); AddALU1("DEC" ,0x02); AddALU1("ABS" ,0x03); AddALU1("NOT" ,0x04); AddALU1("NEG" ,0x05); AddALU1("SHLC" ,0x06); AddALU1("SHRC" ,0x07); AddALU1("ROL" ,0x08); AddALU1("ROR" ,0x09); AddALU1("SHLM" ,0x0a); AddALU1("SHRM" ,0x0b); AddALU1("SHRAM",0x0c); AddALU1("CLR" ,0x0d); AddALU1("NORM" ,0x0e); AddALU1("CVT" ,0x0f); ALU2Orders=(FixedOrder*) malloc(sizeof(FixedOrder)*ALU2OrderCnt); InstrZ=0; AddALU2("ADD" ,0x10); AddALU2("SUB" ,0x11); AddALU2("ADDC" ,0x12); AddALU2("SUBC" ,0x13); AddALU2("CMP" ,0x14); AddALU2("AND" ,0x15); AddALU2("OR" ,0x16); AddALU2("XOR" ,0x17); AddALU2("ADDF" ,0x18); AddALU2("SUBF" ,0x19); SrcRegs=(Register*) malloc(sizeof(Register)*SrcRegCnt); InstrZ=0; AddSrcReg("NON" ,0x00); AddSrcReg("RP" ,0x01); AddSrcReg("PSW0" ,0x02); AddSrcReg("PSW1",0x03); AddSrcReg("SVR" ,0x04); AddSrcReg("SR" ,0x05); AddSrcReg("LC" ,0x06); AddSrcReg("STX" ,0x07); AddSrcReg("M" ,0x08); AddSrcReg("ML" ,0x09); AddSrcReg("ROM" ,0x0a); AddSrcReg("TR" ,0x0b); AddSrcReg("AR" ,0x0c); AddSrcReg("SI" ,0x0d); AddSrcReg("DR" ,0x0e); AddSrcReg("DRS" ,0x0f); AddSrcReg("WR0" ,0x10); AddSrcReg("WR1" ,0x11); AddSrcReg("WR2" ,0x12); AddSrcReg("WR3" ,0x13); AddSrcReg("WR4" ,0x14); AddSrcReg("WR5" ,0x15); AddSrcReg("WR6" ,0x16); AddSrcReg("WR7" ,0x17); AddSrcReg("RAM0",0x18); AddSrcReg("RAM1",0x19); AddSrcReg("BP0" ,0x1a); AddSrcReg("BP1" ,0x1b); AddSrcReg("IX0" ,0x1c); AddSrcReg("IX1" ,0x1d); AddSrcReg("K" ,0x1e); AddSrcReg("L" ,0x1f); ALUSrcRegs=(Register*) malloc(sizeof(Register)*ALUSrcRegCnt); InstrZ=0; AddALUSrcReg("IB" ,0x00); AddALUSrcReg("M" ,0x01); AddALUSrcReg("RAM0",0x02); AddALUSrcReg("RAM1",0x03); DestRegs=(Register*) malloc(sizeof(Register)*DestRegCnt); InstrZ=0; AddDestReg("NON" ,0x00); AddDestReg("RP" ,0x01); AddDestReg("PSW0" ,0x02); AddDestReg("PSW1",0x03); AddDestReg("SVR" ,0x04); AddDestReg("SR" ,0x05); AddDestReg("LC" ,0x06); AddDestReg("STK" ,0x07); AddDestReg("LKR0" ,0x08); AddDestReg("KLR1",0x09); AddDestReg("TRE" ,0x0a); AddDestReg("TR" ,0x0b); AddDestReg("AR" ,0x0c); AddDestReg("SO" ,0x0d); AddDestReg("DR" ,0x0e); AddDestReg("DRS" ,0x0f); AddDestReg("WR0" ,0x10); AddDestReg("WR1" ,0x11); AddDestReg("WR2" ,0x12); AddDestReg("WR3" ,0x13); AddDestReg("WR4" ,0x14); AddDestReg("WR5" ,0x15); AddDestReg("WR6" ,0x16); AddDestReg("WR7" ,0x17); AddDestReg("RAM0",0x18); AddDestReg("RAM1",0x19); AddDestReg("BP0" ,0x1a); AddDestReg("BP1" ,0x1b); AddDestReg("IX0" ,0x1c); AddDestReg("IX1" ,0x1d); AddDestReg("K" ,0x1e); AddDestReg("L" ,0x1f); InstrComps=(LongWord*) malloc(sizeof(LongWord)*InstrCnt); InstrDefs=(LongWord*) malloc(sizeof(LongWord)*InstrCnt); for (InstrZ=0; InstrZId; NOPCode=0x00000000; DivideChars=","; HasAttrs=False; ValidSegs=(1<